Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
5b8df111
提交
5b8df111
authored
6 年前
作者:
Andrei Tokar
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Introduce last commited value into a VersionedValue
上级
c6c72d96
显示空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
136 行增加
和
69 行删除
+136
-69
CommitDecisionMaker.java
h2/src/main/org/h2/mvstore/tx/CommitDecisionMaker.java
+1
-1
TransactionMap.java
h2/src/main/org/h2/mvstore/tx/TransactionMap.java
+35
-34
TxDecisionMaker.java
h2/src/main/org/h2/mvstore/tx/TxDecisionMaker.java
+5
-3
VersionedValue.java
h2/src/main/org/h2/mvstore/tx/VersionedValue.java
+95
-31
没有找到文件。
h2/src/main/org/h2/mvstore/tx/CommitDecisionMaker.java
浏览文件 @
5b8df111
...
...
@@ -49,7 +49,7 @@ final class CommitDecisionMaker extends MVMap.DecisionMaker<VersionedValue> {
public
VersionedValue
selectValue
(
VersionedValue
existingValue
,
VersionedValue
providedValue
)
{
assert
decision
==
MVMap
.
Decision
.
PUT
;
assert
existingValue
!=
null
;
return
new
VersionedValue
(
0L
,
existingValue
.
value
);
return
VersionedValue
.
getInstance
(
existingValue
.
value
);
}
@Override
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/tx/TransactionMap.java
浏览文件 @
5b8df111
...
...
@@ -233,7 +233,7 @@ public class TransactionMap<K, V> {
*/
public
V
putCommitted
(
K
key
,
V
value
)
{
DataUtils
.
checkArgument
(
value
!=
null
,
"The value may not be null"
);
VersionedValue
newValue
=
new
VersionedValue
(
0L
,
value
);
VersionedValue
newValue
=
VersionedValue
.
getInstance
(
value
);
VersionedValue
oldValue
=
map
.
put
(
key
,
newValue
);
@SuppressWarnings
(
"unchecked"
)
V
result
=
(
V
)
(
oldValue
==
null
?
null
:
oldValue
.
value
);
...
...
@@ -449,27 +449,18 @@ public class TransactionMap<K, V> {
*/
VersionedValue
getValue
(
Page
root
,
Page
undoRoot
,
K
key
,
long
maxLog
,
VersionedValue
data
,
BitSet
committingTransactions
)
{
// TODO: This method is overly complicated and has a bunch of extra parameters
// TODO: to support maxLog feature, which is not really used by H2
long
id
;
int
tx
;
while
(
true
)
{
if
(
data
==
null
)
{
// doesn't exist or deleted by a committed transaction
return
null
;
}
long
id
=
data
.
operationId
;
if
(
id
==
0
)
{
// it is committed
return
data
;
}
int
tx
=
TransactionStore
.
getTransactionId
(
id
);
if
(
tx
==
transaction
.
transactionId
)
{
// added by this transaction
if
(
TransactionStore
.
getLogId
(
id
)
<
maxLog
)
{
return
data
;
}
}
else
if
(
committingTransactions
.
get
(
tx
))
{
// transaction which made a change is committed by now
return
data
;
}
// get the value before the uncommitted transaction
// If value doesn't exist or it was deleted by a committed transaction,
// or if value is a committed one, just return it.
if
(
data
!=
null
&&
(
id
=
data
.
getOperationId
())
!=
0
)
{
if
((
tx
=
TransactionStore
.
getTransactionId
(
id
))
==
transaction
.
transactionId
)
{
// current value comes from our transaction
if
(
TransactionStore
.
getLogId
(
id
)
>=
maxLog
)
{
Object
d
[]
=
transaction
.
store
.
undoLog
.
get
(
undoRoot
,
id
);
if
(
d
==
null
)
{
if
(
transaction
.
store
.
store
.
isReadOnly
())
{
...
...
@@ -484,6 +475,16 @@ public class TransactionMap<K, V> {
}
else
{
data
=
(
VersionedValue
)
d
[
2
];
}
continue
;
}
}
else
if
(!
committingTransactions
.
get
(
tx
))
{
// current value comes from another uncommitted transaction
// take committed value instead
Object
committedValue
=
data
.
getCommittedValue
();
data
=
committedValue
==
null
?
null
:
VersionedValue
.
getInstance
(
committedValue
);
}
}
return
data
;
}
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/tx/TxDecisionMaker.java
浏览文件 @
5b8df111
...
...
@@ -46,7 +46,7 @@ public abstract class TxDecisionMaker extends MVMap.DecisionMaker<VersionedValue
// We assume that we are looking at the final value for this transaction,
// and if it's not the case, then it will fail later,
// because a tree root has definitely been changed.
logIt
(
existingValue
.
value
==
null
?
null
:
new
VersionedValue
(
0L
,
existingValue
.
value
));
logIt
(
existingValue
.
value
==
null
?
null
:
VersionedValue
.
getInstance
(
existingValue
.
value
));
decision
=
MVMap
.
Decision
.
PUT
;
}
else
if
(
fetchTransaction
(
blockingId
)
==
null
)
{
// condition above means transaction has been committed/rplled back and closed by now
...
...
@@ -113,7 +113,8 @@ public abstract class TxDecisionMaker extends MVMap.DecisionMaker<VersionedValue
@SuppressWarnings
(
"unchecked"
)
@Override
public
final
VersionedValue
selectValue
(
VersionedValue
existingValue
,
VersionedValue
providedValue
)
{
return
new
VersionedValue
(
undoKey
,
value
);
return
VersionedValue
.
getInstance
(
undoKey
,
value
,
existingValue
==
null
?
null
:
existingValue
.
getCommittedValue
());
}
}
...
...
@@ -171,7 +172,8 @@ public abstract class TxDecisionMaker extends MVMap.DecisionMaker<VersionedValue
@SuppressWarnings
(
"unchecked"
)
@Override
public
VersionedValue
selectValue
(
VersionedValue
existingValue
,
VersionedValue
providedValue
)
{
return
new
VersionedValue
(
undoKey
,
existingValue
==
null
?
null
:
existingValue
.
value
);
assert
existingValue
!=
null
;
// otherwise, what's there to lock?
return
VersionedValue
.
getInstance
(
undoKey
,
existingValue
.
value
,
existingValue
.
getCommittedValue
());
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/tx/VersionedValue.java
浏览文件 @
5b8df111
...
...
@@ -5,44 +5,90 @@
*/
package
org
.
h2
.
mvstore
.
tx
;
import
org.h2.engine.Constants
;
import
org.h2.mvstore.DataUtils
;
import
org.h2.mvstore.WriteBuffer
;
import
org.h2.mvstore.type.DataType
;
import
java.nio.ByteBuffer
;
/**
* A versioned value (possibly null). It contains a pointer to the old
* value, and the value itself.
* A versioned value (possibly null).
* It contains current value and latest committed value if current one is uncommitted.
* Also for uncommitted values it contains operationId - a combination of
* transactionId and logId.
*/
public
class
VersionedValue
{
public
static
final
VersionedValue
DUMMY
=
new
VersionedValue
(
0L
,
new
Object
());
public
static
final
VersionedValue
DUMMY
=
new
VersionedValue
(
new
Object
());
/**
* The operation id.
*/
final
long
operationId
;
/**
* The value.
* The current value.
*/
public
final
Object
value
;
VersionedValue
(
long
operationId
,
Object
value
)
{
this
.
operationId
=
operationId
;
static
VersionedValue
getInstance
(
Object
value
)
{
assert
value
!=
null
;
return
new
VersionedValue
(
value
);
}
public
static
VersionedValue
getInstance
(
long
operationId
,
Object
value
,
Object
committedValue
)
{
return
new
Uncommitted
(
operationId
,
value
,
committedValue
);
}
private
VersionedValue
(
Object
value
)
{
this
.
value
=
value
;
}
public
boolean
isCommitted
()
{
return
true
;
}
public
long
getOperationId
()
{
return
0L
;
}
public
Object
getCommittedValue
()
{
return
value
;
}
@Override
public
String
toString
()
{
return
String
.
valueOf
(
value
);
}
private
static
class
Uncommitted
extends
VersionedValue
{
private
final
long
operationId
;
private
final
Object
committedValue
;
Uncommitted
(
long
operationId
,
Object
value
,
Object
committedValue
)
{
super
(
value
);
assert
operationId
!=
0
;
this
.
operationId
=
operationId
;
this
.
committedValue
=
committedValue
;
}
@Override
public
boolean
isCommitted
()
{
return
false
;
}
@Override
public
long
getOperationId
()
{
return
operationId
;
}
@Override
public
Object
getCommittedValue
()
{
return
committedValue
;
}
@Override
public
String
toString
()
{
return
value
+
(
operationId
==
0
?
""
:
(
"
"
+
TransactionStore
.
getTransactionId
(
operationId
)
+
"/"
+
TransactionStore
.
getLogId
(
operationId
)));
return
super
.
toString
()
+
" "
+
TransactionStore
.
getTransactionId
(
operationId
)
+
"/
"
+
TransactionStore
.
getLogId
(
operationId
)
+
" "
+
committedValue
;
}
}
/**
...
...
@@ -58,8 +104,18 @@ public class VersionedValue {
@Override
public
int
getMemory
(
Object
obj
)
{
if
(
obj
==
null
)
return
0
;
VersionedValue
v
=
(
VersionedValue
)
obj
;
return
valueType
.
getMemory
(
v
.
value
)
+
8
;
int
res
=
Constants
.
MEMORY_OBJECT
+
8
+
2
*
Constants
.
MEMORY_POINTER
+
getValMemory
(
v
.
value
);
if
(
v
.
getOperationId
()
!=
0
)
{
res
+=
getValMemory
(
v
.
getCommittedValue
());
}
return
res
;
}
private
int
getValMemory
(
Object
obj
)
{
return
obj
==
null
?
0
:
valueType
.
getMemory
(
obj
);
}
@Override
...
...
@@ -69,7 +125,7 @@ public class VersionedValue {
}
VersionedValue
a
=
(
VersionedValue
)
aObj
;
VersionedValue
b
=
(
VersionedValue
)
bObj
;
long
comp
=
a
.
operationId
-
b
.
operationId
;
long
comp
=
a
.
getOperationId
()
-
b
.
getOperationId
()
;
if
(
comp
==
0
)
{
return
valueType
.
compare
(
a
.
value
,
b
.
value
);
}
...
...
@@ -81,7 +137,7 @@ public class VersionedValue {
if
(
buff
.
get
()
==
0
)
{
// fast path (no op ids or null entries)
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
obj
[
i
]
=
new
VersionedValue
(
0L
,
valueType
.
read
(
buff
));
obj
[
i
]
=
new
VersionedValue
(
valueType
.
read
(
buff
));
}
}
else
{
// slow path (some entries may be null)
...
...
@@ -94,13 +150,14 @@ public class VersionedValue {
@Override
public
Object
read
(
ByteBuffer
buff
)
{
long
operationId
=
DataUtils
.
readVarLong
(
buff
);
Object
value
;
if
(
buff
.
get
()
==
1
)
{
value
=
valueType
.
read
(
buff
);
if
(
operationId
==
0
)
{
return
new
VersionedValue
(
valueType
.
read
(
buff
));
}
else
{
value
=
null
;
byte
flags
=
buff
.
get
();
Object
value
=
(
flags
&
1
)
!=
0
?
valueType
.
read
(
buff
)
:
null
;
Object
committedValue
=
(
flags
&
2
)
!=
0
?
valueType
.
read
(
buff
)
:
null
;
return
new
Uncommitted
(
operationId
,
value
,
committedValue
);
}
return
new
VersionedValue
(
operationId
,
value
);
}
@Override
...
...
@@ -108,7 +165,7 @@ public class VersionedValue {
boolean
fastPath
=
true
;
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
VersionedValue
v
=
(
VersionedValue
)
obj
[
i
];
if
(
v
.
operationId
!=
0
||
v
.
value
==
null
)
{
if
(
v
.
getOperationId
()
!=
0
||
v
.
value
==
null
)
{
fastPath
=
false
;
}
}
...
...
@@ -131,14 +188,21 @@ public class VersionedValue {
@Override
public
void
write
(
WriteBuffer
buff
,
Object
obj
)
{
VersionedValue
v
=
(
VersionedValue
)
obj
;
buff
.
putVarLong
(
v
.
operationId
);
if
(
v
.
value
==
null
)
{
buff
.
put
((
byte
)
0
);
long
operationId
=
v
.
getOperationId
();
buff
.
putVarLong
(
operationId
);
if
(
operationId
==
0
)
{
valueType
.
write
(
buff
,
v
.
value
);
}
else
{
buff
.
put
((
byte
)
1
);
Object
committedValue
=
v
.
getCommittedValue
();
int
flags
=
(
v
.
value
==
null
?
0
:
1
)
|
(
committedValue
==
null
?
0
:
2
);
buff
.
put
((
byte
)
flags
);
if
(
v
.
value
!=
null
)
{
valueType
.
write
(
buff
,
v
.
value
);
}
if
(
committedValue
!=
null
)
{
valueType
.
write
(
buff
,
committedValue
);
}
}
}
}
}
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论