Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
9632595d
提交
9632595d
authored
11 年前
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
MVStore: use a write buffer instead of a ByteBuffer
上级
ba877c18
全部展开
显示空白字符变更
内嵌
并排
正在显示
12 个修改的文件
包含
392 行增加
和
256 行删除
+392
-256
Chunk.java
h2/src/main/org/h2/mvstore/Chunk.java
+1
-1
MVStore.java
h2/src/main/org/h2/mvstore/MVStore.java
+58
-33
Page.java
h2/src/main/org/h2/mvstore/Page.java
+11
-15
WriteBuffer.java
h2/src/main/org/h2/mvstore/WriteBuffer.java
+159
-0
TransactionStore.java
h2/src/main/org/h2/mvstore/db/TransactionStore.java
+7
-8
ValueDataType.java
h2/src/main/org/h2/mvstore/db/ValueDataType.java
+57
-101
SpatialDataType.java
h2/src/main/org/h2/mvstore/rtree/SpatialDataType.java
+4
-4
DataType.java
h2/src/main/org/h2/mvstore/type/DataType.java
+3
-2
ObjectDataType.java
h2/src/main/org/h2/mvstore/type/ObjectDataType.java
+75
-78
StringDataType.java
h2/src/main/org/h2/mvstore/type/StringDataType.java
+4
-3
RowDataType.java
h2/src/test/org/h2/test/store/RowDataType.java
+4
-5
TestObjectDataType.java
h2/src/test/org/h2/test/store/TestObjectDataType.java
+9
-6
没有找到文件。
h2/src/main/org/h2/mvstore/Chunk.java
浏览文件 @
9632595d
...
@@ -120,7 +120,7 @@ public class Chunk {
...
@@ -120,7 +120,7 @@ public class Chunk {
*
*
* @param buff the target buffer
* @param buff the target buffer
*/
*/
void
writeHeader
(
By
teBuffer
buff
)
{
void
writeHeader
(
Wri
teBuffer
buff
)
{
buff
.
put
((
byte
)
'c'
);
buff
.
put
((
byte
)
'c'
);
buff
.
putInt
(
length
);
buff
.
putInt
(
length
);
buff
.
putInt
(
id
);
buff
.
putInt
(
id
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/MVStore.java
浏览文件 @
9632595d
...
@@ -181,7 +181,7 @@ public class MVStore {
...
@@ -181,7 +181,7 @@ public class MVStore {
private
HashMap
<
String
,
String
>
storeHeader
=
New
.
hashMap
();
private
HashMap
<
String
,
String
>
storeHeader
=
New
.
hashMap
();
private
By
teBuffer
writeBuffer
;
private
Wri
teBuffer
writeBuffer
;
private
int
lastMapId
;
private
int
lastMapId
;
...
@@ -269,12 +269,14 @@ public class MVStore {
...
@@ -269,12 +269,14 @@ public class MVStore {
boolean
readOnly
=
config
.
containsKey
(
"readOnly"
);
boolean
readOnly
=
config
.
containsKey
(
"readOnly"
);
o
=
config
.
get
(
"cacheSize"
);
o
=
config
.
get
(
"cacheSize"
);
int
mb
=
o
==
null
?
16
:
(
Integer
)
o
;
int
mb
=
o
==
null
?
16
:
(
Integer
)
o
;
if
(
mb
>
0
)
{
int
maxMemoryBytes
=
mb
*
1024
*
1024
;
int
maxMemoryBytes
=
mb
*
1024
*
1024
;
int
averageMemory
=
Math
.
max
(
10
,
pageSplitSize
/
2
);
int
averageMemory
=
Math
.
max
(
10
,
pageSplitSize
/
2
);
int
segmentCount
=
16
;
int
segmentCount
=
16
;
int
stackMoveDistance
=
maxMemoryBytes
/
averageMemory
*
2
/
100
;
int
stackMoveDistance
=
maxMemoryBytes
/
averageMemory
*
2
/
100
;
cache
=
new
CacheLongKeyLIRS
<
Page
>(
cache
=
new
CacheLongKeyLIRS
<
Page
>(
maxMemoryBytes
,
averageMemory
,
segmentCount
,
stackMoveDistance
);
maxMemoryBytes
,
averageMemory
,
segmentCount
,
stackMoveDistance
);
}
o
=
config
.
get
(
"writeBufferSize"
);
o
=
config
.
get
(
"writeBufferSize"
);
mb
=
o
==
null
?
4
:
(
Integer
)
o
;
mb
=
o
==
null
?
4
:
(
Integer
)
o
;
int
writeBufferSize
=
mb
*
1024
*
1024
;
int
writeBufferSize
=
mb
*
1024
*
1024
;
...
@@ -519,6 +521,11 @@ public class MVStore {
...
@@ -519,6 +521,11 @@ public class MVStore {
private
void
readMeta
()
{
private
void
readMeta
()
{
chunks
.
clear
();
chunks
.
clear
();
Chunk
header
=
readChunkHeader
(
rootChunkStart
);
Chunk
header
=
readChunkHeader
(
rootChunkStart
);
if
(
header
.
start
==
Long
.
MAX_VALUE
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_FILE_CORRUPT
,
"Chunk {0} is invalid"
,
header
.
id
);
}
lastChunkId
=
header
.
id
;
lastChunkId
=
header
.
id
;
chunks
.
put
(
header
.
id
,
header
);
chunks
.
put
(
header
.
id
,
header
);
meta
.
setRootPos
(
header
.
metaRootPos
,
-
1
);
meta
.
setRootPos
(
header
.
metaRootPos
,
-
1
);
...
@@ -543,6 +550,11 @@ public class MVStore {
...
@@ -543,6 +550,11 @@ public class MVStore {
s
=
meta
.
get
(
s
);
s
=
meta
.
get
(
s
);
Chunk
c
=
Chunk
.
fromString
(
s
);
Chunk
c
=
Chunk
.
fromString
(
s
);
if
(!
chunks
.
containsKey
(
c
.
id
))
{
if
(!
chunks
.
containsKey
(
c
.
id
))
{
if
(
c
.
start
==
Long
.
MAX_VALUE
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_FILE_CORRUPT
,
"Chunk {0} is invalid"
,
c
.
id
);
}
chunks
.
put
(
c
.
id
,
c
);
chunks
.
put
(
c
.
id
,
c
);
}
}
}
}
...
@@ -731,10 +743,14 @@ public class MVStore {
...
@@ -731,10 +743,14 @@ public class MVStore {
if
(
s
==
null
)
{
if
(
s
==
null
)
{
throw
DataUtils
.
newIllegalStateException
(
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_FILE_CORRUPT
,
DataUtils
.
ERROR_FILE_CORRUPT
,
"Chunk {0} not found"
,
"Chunk {0} not found"
,
chunkId
);
DataUtils
.
getPageChunkId
(
pos
));
}
}
c
=
Chunk
.
fromString
(
s
);
c
=
Chunk
.
fromString
(
s
);
if
(
c
.
start
==
Long
.
MAX_VALUE
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_FILE_CORRUPT
,
"Chunk {0} is invalid"
,
chunkId
);
}
chunks
.
put
(
c
.
id
,
c
);
chunks
.
put
(
c
.
id
,
c
);
}
}
return
c
;
return
c
;
...
@@ -892,7 +908,7 @@ public class MVStore {
...
@@ -892,7 +908,7 @@ public class MVStore {
}
}
}
}
Set
<
Chunk
>
removedChunks
=
applyFreedSpace
(
storeVersion
,
time
);
Set
<
Chunk
>
removedChunks
=
applyFreedSpace
(
storeVersion
,
time
);
By
teBuffer
buff
=
getWriteBuffer
();
Wri
teBuffer
buff
=
getWriteBuffer
();
// need to patch the header later
// need to patch the header later
c
.
writeHeader
(
buff
);
c
.
writeHeader
(
buff
);
c
.
maxLength
=
0
;
c
.
maxLength
=
0
;
...
@@ -900,28 +916,24 @@ public class MVStore {
...
@@ -900,28 +916,24 @@ public class MVStore {
for
(
MVMap
<?,
?>
m
:
changed
)
{
for
(
MVMap
<?,
?>
m
:
changed
)
{
Page
p
=
m
.
getRoot
();
Page
p
=
m
.
getRoot
();
if
(
p
.
getTotalCount
()
>
0
)
{
if
(
p
.
getTotalCount
()
>
0
)
{
buff
=
p
.
writeUnsavedRecursive
(
c
,
buff
);
p
.
writeUnsavedRecursive
(
c
,
buff
);
long
root
=
p
.
getPos
();
long
root
=
p
.
getPos
();
meta
.
put
(
"root."
+
m
.
getId
(),
""
+
root
);
meta
.
put
(
"root."
+
m
.
getId
(),
""
+
root
);
}
}
}
}
meta
.
put
(
"chunk."
+
c
.
id
,
c
.
asString
());
meta
.
put
(
"chunk."
+
c
.
id
,
c
.
asString
());
meta
.
setWriteVersion
(
version
);
meta
.
setWriteVersion
(
version
);
// this will (again) modify maxLengthLive, but
// this will (again) modify maxLengthLive, but
// the correct value is written in the chunk header
// the correct value is written in the chunk header
Page
metaRoot
=
meta
.
getRoot
();
Page
metaRoot
=
meta
.
getRoot
();
buff
=
metaRoot
.
writeUnsavedRecursive
(
c
,
buff
);
metaRoot
.
writeUnsavedRecursive
(
c
,
buff
);
int
chunkLength
=
buff
.
position
();
int
chunkLength
=
buff
.
position
();
// round to the next block,
// round to the next block,
// and one additional block for the store header
// and one additional block for the store header
int
length
=
MathUtils
.
roundUpInt
(
chunkLength
,
BLOCK_SIZE
)
+
BLOCK_SIZE
;
int
length
=
MathUtils
.
roundUpInt
(
chunkLength
,
BLOCK_SIZE
)
+
BLOCK_SIZE
;
if
(
length
>
buff
.
capacity
())
{
buff
=
DataUtils
.
ensureCapacity
(
buff
,
length
-
buff
.
capacity
());
}
buff
.
limit
(
length
);
buff
.
limit
(
length
);
// free up the space of unused chunks now
// free up the space of unused chunks now
...
@@ -940,6 +952,14 @@ public class MVStore {
...
@@ -940,6 +952,14 @@ public class MVStore {
}
}
boolean
storeAtEndOfFile
=
filePos
+
length
>=
end
;
boolean
storeAtEndOfFile
=
filePos
+
length
>=
end
;
// try {
// Thread.sleep(10);
// } catch (InterruptedException e) {
// ; int todo;
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
c
.
start
=
filePos
;
c
.
start
=
filePos
;
c
.
length
=
chunkLength
;
c
.
length
=
chunkLength
;
c
.
metaRootPos
=
metaRoot
.
getPos
();
c
.
metaRootPos
=
metaRoot
.
getPos
();
...
@@ -955,7 +975,7 @@ public class MVStore {
...
@@ -955,7 +975,7 @@ public class MVStore {
buff
.
put
(
new
byte
[
BLOCK_SIZE
-
header
.
length
]);
buff
.
put
(
new
byte
[
BLOCK_SIZE
-
header
.
length
]);
buff
.
position
(
0
);
buff
.
position
(
0
);
fileStore
.
writeFully
(
filePos
,
buff
);
fileStore
.
writeFully
(
filePos
,
buff
.
getBuffer
()
);
releaseWriteBuffer
(
buff
);
releaseWriteBuffer
(
buff
);
...
@@ -975,6 +995,7 @@ public class MVStore {
...
@@ -975,6 +995,7 @@ public class MVStore {
// some pages might have been changed in the meantime (in the newest version)
// some pages might have been changed in the meantime (in the newest version)
unsavedPageCount
=
Math
.
max
(
0
,
unsavedPageCount
-
currentUnsavedPageCount
);
unsavedPageCount
=
Math
.
max
(
0
,
unsavedPageCount
-
currentUnsavedPageCount
);
if
(!
temp
)
{
if
(!
temp
)
{
metaChanged
=
false
;
metaChanged
=
false
;
lastStoredVersion
=
storeVersion
;
lastStoredVersion
=
storeVersion
;
...
@@ -988,13 +1009,13 @@ public class MVStore {
...
@@ -988,13 +1009,13 @@ public class MVStore {
*
*
* @return the buffer
* @return the buffer
*/
*/
private
By
teBuffer
getWriteBuffer
()
{
private
Wri
teBuffer
getWriteBuffer
()
{
By
teBuffer
buff
;
Wri
teBuffer
buff
;
if
(
writeBuffer
!=
null
)
{
if
(
writeBuffer
!=
null
)
{
buff
=
writeBuffer
;
buff
=
writeBuffer
;
buff
.
clear
();
buff
.
clear
();
}
else
{
}
else
{
buff
=
ByteBuffer
.
allocate
(
1024
*
1024
);
buff
=
new
WriteBuffer
(
);
}
}
return
buff
;
return
buff
;
}
}
...
@@ -1005,7 +1026,7 @@ public class MVStore {
...
@@ -1005,7 +1026,7 @@ public class MVStore {
*
*
* @param buff the buffer than can be re-used
* @param buff the buffer than can be re-used
*/
*/
private
void
releaseWriteBuffer
(
By
teBuffer
buff
)
{
private
void
releaseWriteBuffer
(
Wri
teBuffer
buff
)
{
if
(
buff
.
capacity
()
<=
4
*
1024
*
1024
)
{
if
(
buff
.
capacity
()
<=
4
*
1024
*
1024
)
{
writeBuffer
=
buff
;
writeBuffer
=
buff
;
}
}
...
@@ -1123,9 +1144,6 @@ public class MVStore {
...
@@ -1123,9 +1144,6 @@ public class MVStore {
private
long
getEndPosition
()
{
private
long
getEndPosition
()
{
long
size
=
2
*
BLOCK_SIZE
;
long
size
=
2
*
BLOCK_SIZE
;
for
(
Chunk
c
:
chunks
.
values
())
{
for
(
Chunk
c
:
chunks
.
values
())
{
if
(
c
.
start
==
Long
.
MAX_VALUE
)
{
continue
;
}
long
x
=
c
.
start
+
c
.
length
;
long
x
=
c
.
start
+
c
.
length
;
size
=
Math
.
max
(
size
,
MathUtils
.
roundUpLong
(
x
,
BLOCK_SIZE
)
+
BLOCK_SIZE
);
size
=
Math
.
max
(
size
,
MathUtils
.
roundUpLong
(
x
,
BLOCK_SIZE
)
+
BLOCK_SIZE
);
}
}
...
@@ -1200,9 +1218,8 @@ public class MVStore {
...
@@ -1200,9 +1218,8 @@ public class MVStore {
}
}
}
}
for
(
Chunk
c
:
move
)
{
for
(
Chunk
c
:
move
)
{
By
teBuffer
buff
=
getWriteBuffer
();
Wri
teBuffer
buff
=
getWriteBuffer
();
int
length
=
MathUtils
.
roundUpInt
(
c
.
length
,
BLOCK_SIZE
)
+
BLOCK_SIZE
;
int
length
=
MathUtils
.
roundUpInt
(
c
.
length
,
BLOCK_SIZE
)
+
BLOCK_SIZE
;
buff
=
DataUtils
.
ensureCapacity
(
buff
,
length
);
buff
.
limit
(
length
);
buff
.
limit
(
length
);
ByteBuffer
buff2
=
fileStore
.
readFully
(
c
.
start
,
length
);
ByteBuffer
buff2
=
fileStore
.
readFully
(
c
.
start
,
length
);
buff
.
put
(
buff2
);
buff
.
put
(
buff2
);
...
@@ -1218,7 +1235,7 @@ public class MVStore {
...
@@ -1218,7 +1235,7 @@ public class MVStore {
// fill the header with zeroes
// fill the header with zeroes
buff
.
put
(
new
byte
[
BLOCK_SIZE
-
header
.
length
]);
buff
.
put
(
new
byte
[
BLOCK_SIZE
-
header
.
length
]);
buff
.
position
(
0
);
buff
.
position
(
0
);
fileStore
.
writeFully
(
end
,
buff
);
fileStore
.
writeFully
(
end
,
buff
.
getBuffer
()
);
releaseWriteBuffer
(
buff
);
releaseWriteBuffer
(
buff
);
meta
.
put
(
"chunk."
+
c
.
id
,
c
.
asString
());
meta
.
put
(
"chunk."
+
c
.
id
,
c
.
asString
());
}
}
...
@@ -1238,9 +1255,8 @@ public class MVStore {
...
@@ -1238,9 +1255,8 @@ public class MVStore {
// previous store operation
// previous store operation
continue
;
continue
;
}
}
By
teBuffer
buff
=
getWriteBuffer
();
Wri
teBuffer
buff
=
getWriteBuffer
();
int
length
=
MathUtils
.
roundUpInt
(
c
.
length
,
BLOCK_SIZE
)
+
BLOCK_SIZE
;
int
length
=
MathUtils
.
roundUpInt
(
c
.
length
,
BLOCK_SIZE
)
+
BLOCK_SIZE
;
buff
=
DataUtils
.
ensureCapacity
(
buff
,
length
);
buff
.
limit
(
length
);
buff
.
limit
(
length
);
ByteBuffer
buff2
=
fileStore
.
readFully
(
c
.
start
,
length
);
ByteBuffer
buff2
=
fileStore
.
readFully
(
c
.
start
,
length
);
buff
.
put
(
buff2
);
buff
.
put
(
buff2
);
...
@@ -1255,7 +1271,7 @@ public class MVStore {
...
@@ -1255,7 +1271,7 @@ public class MVStore {
// fill the header with zeroes
// fill the header with zeroes
buff
.
put
(
new
byte
[
BLOCK_SIZE
-
header
.
length
]);
buff
.
put
(
new
byte
[
BLOCK_SIZE
-
header
.
length
]);
buff
.
position
(
0
);
buff
.
position
(
0
);
fileStore
.
writeFully
(
pos
,
buff
);
fileStore
.
writeFully
(
pos
,
buff
.
getBuffer
()
);
releaseWriteBuffer
(
buff
);
releaseWriteBuffer
(
buff
);
meta
.
put
(
"chunk."
+
c
.
id
,
c
.
asString
());
meta
.
put
(
"chunk."
+
c
.
id
,
c
.
asString
());
}
}
...
@@ -1432,7 +1448,7 @@ public class MVStore {
...
@@ -1432,7 +1448,7 @@ public class MVStore {
throw
DataUtils
.
newIllegalStateException
(
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_FILE_CORRUPT
,
"Position 0"
);
DataUtils
.
ERROR_FILE_CORRUPT
,
"Position 0"
);
}
}
Page
p
=
cache
.
get
(
pos
);
Page
p
=
cache
==
null
?
null
:
cache
.
get
(
pos
);
if
(
p
==
null
)
{
if
(
p
==
null
)
{
Chunk
c
=
getChunk
(
pos
);
Chunk
c
=
getChunk
(
pos
);
long
filePos
=
c
.
start
;
long
filePos
=
c
.
start
;
...
@@ -1442,8 +1458,10 @@ public class MVStore {
...
@@ -1442,8 +1458,10 @@ public class MVStore {
DataUtils
.
ERROR_FILE_CORRUPT
,
"Negative position {0}"
,
filePos
);
DataUtils
.
ERROR_FILE_CORRUPT
,
"Negative position {0}"
,
filePos
);
}
}
p
=
Page
.
read
(
fileStore
,
map
,
pos
,
filePos
,
fileStore
.
size
());
p
=
Page
.
read
(
fileStore
,
map
,
pos
,
filePos
,
fileStore
.
size
());
if
(
cache
!=
null
)
{
cache
.
put
(
pos
,
p
,
p
.
getMemory
());
cache
.
put
(
pos
,
p
,
p
.
getMemory
());
}
}
}
return
p
;
return
p
;
}
}
...
@@ -1466,7 +1484,9 @@ public class MVStore {
...
@@ -1466,7 +1484,9 @@ public class MVStore {
// This could result in a cache miss if the operation is rolled back,
// This could result in a cache miss if the operation is rolled back,
// but we don't optimize for rollback.
// but we don't optimize for rollback.
// We could also keep the page in the cache, as somebody could read it.
// We could also keep the page in the cache, as somebody could read it.
if
(
cache
!=
null
)
{
cache
.
remove
(
pos
);
cache
.
remove
(
pos
);
}
Chunk
c
=
getChunk
(
pos
);
Chunk
c
=
getChunk
(
pos
);
long
version
=
currentVersion
;
long
version
=
currentVersion
;
...
@@ -1800,6 +1820,11 @@ public class MVStore {
...
@@ -1800,6 +1820,11 @@ public class MVStore {
}
}
}
}
// rollback might have rolled back the stored chunk metadata as well
Chunk
c
=
chunks
.
get
(
lastChunkId
-
1
);
if
(
c
!=
null
)
{
meta
.
put
(
"chunk."
+
c
.
id
,
c
.
asString
());
}
currentVersion
=
version
;
currentVersion
=
version
;
setWriteVersion
(
version
);
setWriteVersion
(
version
);
lastCommittedVersion
=
version
;
lastCommittedVersion
=
version
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/Page.java
浏览文件 @
9632595d
...
@@ -770,35 +770,33 @@ public class Page {
...
@@ -770,35 +770,33 @@ public class Page {
*
*
* @param chunk the chunk
* @param chunk the chunk
* @param buff the target buffer
* @param buff the target buffer
* @return the target buffer
*/
*/
private
ByteBuffer
write
(
Chunk
chunk
,
ByteBuffer
buff
)
{
private
void
write
(
Chunk
chunk
,
WriteBuffer
buff
)
{
buff
=
DataUtils
.
ensureCapacity
(
buff
,
1024
);
int
start
=
buff
.
position
();
int
start
=
buff
.
position
();
buff
.
putInt
(
0
);
buff
.
putInt
(
0
);
buff
.
putShort
((
byte
)
0
);
buff
.
putShort
((
byte
)
0
);
DataUtils
.
writeVarInt
(
buff
,
map
.
getId
());
buff
.
writeVarInt
(
map
.
getId
());
int
len
=
keyCount
;
int
len
=
keyCount
;
DataUtils
.
writeVarInt
(
buff
,
len
);
buff
.
writeVarInt
(
len
);
int
type
=
children
!=
null
?
DataUtils
.
PAGE_TYPE_NODE
int
type
=
children
!=
null
?
DataUtils
.
PAGE_TYPE_NODE
:
DataUtils
.
PAGE_TYPE_LEAF
;
:
DataUtils
.
PAGE_TYPE_LEAF
;
buff
.
put
((
byte
)
type
);
buff
.
put
((
byte
)
type
);
int
compressStart
=
buff
.
position
();
int
compressStart
=
buff
.
position
();
DataType
keyType
=
map
.
getKeyType
();
DataType
keyType
=
map
.
getKeyType
();
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
buff
=
keyType
.
write
(
buff
,
keys
[
i
]);
keyType
.
write
(
buff
,
keys
[
i
]);
}
}
if
(
type
==
DataUtils
.
PAGE_TYPE_NODE
)
{
if
(
type
==
DataUtils
.
PAGE_TYPE_NODE
)
{
for
(
int
i
=
0
;
i
<=
len
;
i
++)
{
for
(
int
i
=
0
;
i
<=
len
;
i
++)
{
buff
.
putLong
(
children
[
i
]);
buff
.
putLong
(
children
[
i
]);
}
}
for
(
int
i
=
0
;
i
<=
len
;
i
++)
{
for
(
int
i
=
0
;
i
<=
len
;
i
++)
{
DataUtils
.
writeVarLong
(
buff
,
counts
[
i
]);
buff
.
writeVarLong
(
counts
[
i
]);
}
}
}
else
{
}
else
{
DataType
valueType
=
map
.
getValueType
();
DataType
valueType
=
map
.
getValueType
();
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
buff
=
valueType
.
write
(
buff
,
values
[
i
]);
valueType
.
write
(
buff
,
values
[
i
]);
}
}
}
}
if
(
map
.
getStore
().
getCompress
())
{
if
(
map
.
getStore
().
getCompress
())
{
...
@@ -812,7 +810,7 @@ public class Page {
...
@@ -812,7 +810,7 @@ public class Page {
if
(
compLen
+
DataUtils
.
getVarIntLen
(
compLen
-
expLen
)
<
expLen
)
{
if
(
compLen
+
DataUtils
.
getVarIntLen
(
compLen
-
expLen
)
<
expLen
)
{
buff
.
position
(
compressStart
-
1
);
buff
.
position
(
compressStart
-
1
);
buff
.
put
((
byte
)
(
type
+
DataUtils
.
PAGE_COMPRESSED
));
buff
.
put
((
byte
)
(
type
+
DataUtils
.
PAGE_COMPRESSED
));
DataUtils
.
writeVarInt
(
buff
,
expLen
-
compLen
);
buff
.
writeVarInt
(
expLen
-
compLen
);
buff
.
put
(
comp
,
0
,
compLen
);
buff
.
put
(
comp
,
0
,
compLen
);
}
}
}
}
...
@@ -833,7 +831,6 @@ public class Page {
...
@@ -833,7 +831,6 @@ public class Page {
chunk
.
maxLengthLive
+=
max
;
chunk
.
maxLengthLive
+=
max
;
chunk
.
pageCount
++;
chunk
.
pageCount
++;
chunk
.
pageCountLive
++;
chunk
.
pageCountLive
++;
return
buff
;
}
}
/**
/**
...
@@ -842,24 +839,23 @@ public class Page {
...
@@ -842,24 +839,23 @@ public class Page {
*
*
* @param chunk the chunk
* @param chunk the chunk
* @param buff the target buffer
* @param buff the target buffer
* @return the target buffer
*/
*/
ByteBuffer
writeUnsavedRecursive
(
Chunk
chunk
,
By
teBuffer
buff
)
{
void
writeUnsavedRecursive
(
Chunk
chunk
,
Wri
teBuffer
buff
)
{
if
(
pos
!=
0
)
{
if
(
pos
!=
0
)
{
// already stored before
// already stored before
return
buff
;
return
;
}
}
if
(!
isLeaf
())
{
if
(!
isLeaf
())
{
int
len
=
children
.
length
;
int
len
=
children
.
length
;
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
Page
p
=
childrenPages
[
i
];
Page
p
=
childrenPages
[
i
];
if
(
p
!=
null
)
{
if
(
p
!=
null
)
{
buff
=
p
.
writeUnsavedRecursive
(
chunk
,
buff
);
p
.
writeUnsavedRecursive
(
chunk
,
buff
);
children
[
i
]
=
p
.
getPos
();
children
[
i
]
=
p
.
getPos
();
}
}
}
}
}
}
return
write
(
chunk
,
buff
);
write
(
chunk
,
buff
);
}
}
/**
/**
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/WriteBuffer.java
0 → 100644
浏览文件 @
9632595d
/*
* Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
mvstore
;
import
java.nio.ByteBuffer
;
/**
* An auto-resize buffer to write data into a ByteBuffer.
*/
public
class
WriteBuffer
{
private
static
final
int
MAX_REUSE_LIMIT
=
4
*
1024
*
1024
;
/**
* The maximum byte to grow a buffer at a time.
*/
private
static
final
int
MAX_GROW
=
4
*
1024
*
1024
;
private
ByteBuffer
reuse
=
ByteBuffer
.
allocate
(
512
*
1024
);
private
ByteBuffer
buff
=
reuse
;
public
void
writeVarInt
(
int
x
)
{
DataUtils
.
writeVarInt
(
ensureCapacity
(
5
),
x
);
}
public
void
writeVarLong
(
long
x
)
{
DataUtils
.
writeVarLong
(
ensureCapacity
(
10
),
x
);
}
public
void
writeStringData
(
String
s
,
int
len
)
{
ByteBuffer
b
=
ensureCapacity
(
3
*
len
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
int
c
=
s
.
charAt
(
i
);
if
(
c
<
0x80
)
{
b
.
put
((
byte
)
c
);
}
else
if
(
c
>=
0x800
)
{
b
.
put
((
byte
)
(
0xe0
|
(
c
>>
12
)));
b
.
put
((
byte
)
(((
c
>>
6
)
&
0x3f
)));
b
.
put
((
byte
)
(
c
&
0x3f
));
}
else
{
b
.
put
((
byte
)
(
0xc0
|
(
c
>>
6
)));
b
.
put
((
byte
)
(
c
&
0x3f
));
}
}
}
public
void
put
(
byte
x
)
{
ensureCapacity
(
1
).
put
(
x
);
}
public
void
putChar
(
char
x
)
{
ensureCapacity
(
2
).
putChar
(
x
);
}
public
void
putShort
(
short
x
)
{
ensureCapacity
(
2
).
putShort
(
x
);
}
public
void
putInt
(
int
x
)
{
ensureCapacity
(
4
).
putInt
(
x
);
}
public
void
putLong
(
long
x
)
{
ensureCapacity
(
8
).
putLong
(
x
);
}
public
void
putFloat
(
float
x
)
{
ensureCapacity
(
4
).
putFloat
(
x
);
}
public
void
putDouble
(
double
x
)
{
ensureCapacity
(
8
).
putDouble
(
x
);
}
public
void
put
(
byte
[]
bytes
)
{
ensureCapacity
(
bytes
.
length
).
put
(
bytes
);
}
public
void
put
(
byte
[]
bytes
,
int
offset
,
int
length
)
{
ensureCapacity
(
length
).
put
(
bytes
,
offset
,
length
);
}
public
void
position
(
int
newPosition
)
{
buff
.
position
(
newPosition
);
}
public
int
position
()
{
return
buff
.
position
();
}
public
void
get
(
byte
[]
dst
)
{
buff
.
get
(
dst
);
}
public
void
putInt
(
int
index
,
int
value
)
{
buff
.
putInt
(
index
,
value
);
}
public
void
putShort
(
int
index
,
short
value
)
{
buff
.
putShort
(
index
,
value
);
}
public
void
put
(
ByteBuffer
src
)
{
ensureCapacity
(
buff
.
remaining
()).
put
(
src
);
}
public
void
limit
(
int
newLimit
)
{
ensureCapacity
(
newLimit
-
buff
.
position
()).
limit
(
newLimit
);
}
public
int
limit
()
{
return
buff
.
limit
();
}
public
int
capacity
()
{
return
buff
.
capacity
();
}
public
ByteBuffer
getBuffer
()
{
return
buff
;
}
/**
* Clear the buffer after use.
*/
void
clear
()
{
if
(
buff
.
limit
()
>
MAX_REUSE_LIMIT
)
{
buff
=
reuse
;
}
buff
.
clear
();
}
private
ByteBuffer
ensureCapacity
(
int
len
)
{
if
(
buff
.
remaining
()
<
len
)
{
grow
(
len
);
}
return
buff
;
}
private
void
grow
(
int
len
)
{
ByteBuffer
temp
=
buff
;
len
=
temp
.
remaining
()
+
len
;
int
capacity
=
temp
.
capacity
();
len
=
Math
.
max
(
len
,
Math
.
min
(
capacity
+
MAX_GROW
,
capacity
*
2
));
buff
=
ByteBuffer
.
allocate
(
len
);
temp
.
flip
();
buff
.
put
(
temp
);
if
(
len
<=
MAX_REUSE_LIMIT
)
{
reuse
=
buff
;
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/db/TransactionStore.java
浏览文件 @
9632595d
...
@@ -17,6 +17,7 @@ import org.h2.mvstore.DataUtils;
...
@@ -17,6 +17,7 @@ import org.h2.mvstore.DataUtils;
import
org.h2.mvstore.MVMap
;
import
org.h2.mvstore.MVMap
;
import
org.h2.mvstore.MVMap.Builder
;
import
org.h2.mvstore.MVMap.Builder
;
import
org.h2.mvstore.MVStore
;
import
org.h2.mvstore.MVStore
;
import
org.h2.mvstore.WriteBuffer
;
import
org.h2.mvstore.type.DataType
;
import
org.h2.mvstore.type.DataType
;
import
org.h2.mvstore.type.ObjectDataType
;
import
org.h2.mvstore.type.ObjectDataType
;
import
org.h2.util.New
;
import
org.h2.util.New
;
...
@@ -1324,17 +1325,16 @@ public class TransactionStore {
...
@@ -1324,17 +1325,16 @@ public class TransactionStore {
}
}
@Override
@Override
public
ByteBuffer
write
(
By
teBuffer
buff
,
Object
obj
)
{
public
void
write
(
Wri
teBuffer
buff
,
Object
obj
)
{
VersionedValue
v
=
(
VersionedValue
)
obj
;
VersionedValue
v
=
(
VersionedValue
)
obj
;
DataUtils
.
writeVarLong
(
buff
,
v
.
transactionId
);
buff
.
writeVarLong
(
v
.
transactionId
);
DataUtils
.
writeVarLong
(
buff
,
v
.
logId
);
buff
.
writeVarLong
(
v
.
logId
);
if
(
v
.
value
==
null
)
{
if
(
v
.
value
==
null
)
{
buff
.
put
((
byte
)
0
);
buff
.
put
((
byte
)
0
);
}
else
{
}
else
{
buff
.
put
((
byte
)
1
);
buff
.
put
((
byte
)
1
);
buff
=
valueType
.
write
(
buff
,
v
.
value
);
valueType
.
write
(
buff
,
v
.
value
);
}
}
return
buff
;
}
}
@Override
@Override
...
@@ -1396,7 +1396,7 @@ public class TransactionStore {
...
@@ -1396,7 +1396,7 @@ public class TransactionStore {
}
}
@Override
@Override
public
ByteBuffer
write
(
By
teBuffer
buff
,
Object
obj
)
{
public
void
write
(
Wri
teBuffer
buff
,
Object
obj
)
{
Object
[]
array
=
(
Object
[])
obj
;
Object
[]
array
=
(
Object
[])
obj
;
for
(
int
i
=
0
;
i
<
arrayLength
;
i
++)
{
for
(
int
i
=
0
;
i
<
arrayLength
;
i
++)
{
DataType
t
=
elementTypes
[
i
];
DataType
t
=
elementTypes
[
i
];
...
@@ -1405,10 +1405,9 @@ public class TransactionStore {
...
@@ -1405,10 +1405,9 @@ public class TransactionStore {
buff
.
put
((
byte
)
0
);
buff
.
put
((
byte
)
0
);
}
else
{
}
else
{
buff
.
put
((
byte
)
1
);
buff
.
put
((
byte
)
1
);
buff
=
t
.
write
(
buff
,
o
);
t
.
write
(
buff
,
o
);
}
}
}
}
return
buff
;
}
}
@Override
@Override
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/db/ValueDataType.java
浏览文件 @
9632595d
差异被折叠。
点击展开。
h2/src/main/org/h2/mvstore/rtree/SpatialDataType.java
浏览文件 @
9632595d
...
@@ -9,6 +9,7 @@ package org.h2.mvstore.rtree;
...
@@ -9,6 +9,7 @@ package org.h2.mvstore.rtree;
import
java.nio.ByteBuffer
;
import
java.nio.ByteBuffer
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
org.h2.mvstore.DataUtils
;
import
org.h2.mvstore.DataUtils
;
import
org.h2.mvstore.WriteBuffer
;
import
org.h2.mvstore.type.DataType
;
import
org.h2.mvstore.type.DataType
;
/**
/**
...
@@ -53,7 +54,7 @@ public class SpatialDataType implements DataType {
...
@@ -53,7 +54,7 @@ public class SpatialDataType implements DataType {
}
}
@Override
@Override
public
ByteBuffer
write
(
By
teBuffer
buff
,
Object
obj
)
{
public
void
write
(
Wri
teBuffer
buff
,
Object
obj
)
{
SpatialKey
k
=
(
SpatialKey
)
obj
;
SpatialKey
k
=
(
SpatialKey
)
obj
;
int
flags
=
0
;
int
flags
=
0
;
for
(
int
i
=
0
;
i
<
dimensions
;
i
++)
{
for
(
int
i
=
0
;
i
<
dimensions
;
i
++)
{
...
@@ -61,15 +62,14 @@ public class SpatialDataType implements DataType {
...
@@ -61,15 +62,14 @@ public class SpatialDataType implements DataType {
flags
|=
1
<<
i
;
flags
|=
1
<<
i
;
}
}
}
}
DataUtils
.
writeVarInt
(
buff
,
flags
);
buff
.
writeVarInt
(
flags
);
for
(
int
i
=
0
;
i
<
dimensions
;
i
++)
{
for
(
int
i
=
0
;
i
<
dimensions
;
i
++)
{
buff
.
putFloat
(
k
.
min
(
i
));
buff
.
putFloat
(
k
.
min
(
i
));
if
((
flags
&
(
1
<<
i
))
==
0
)
{
if
((
flags
&
(
1
<<
i
))
==
0
)
{
buff
.
putFloat
(
k
.
max
(
i
));
buff
.
putFloat
(
k
.
max
(
i
));
}
}
}
}
DataUtils
.
writeVarLong
(
buff
,
k
.
getId
());
buff
.
writeVarLong
(
k
.
getId
());
return
buff
;
}
}
@Override
@Override
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/type/DataType.java
浏览文件 @
9632595d
...
@@ -8,6 +8,8 @@ package org.h2.mvstore.type;
...
@@ -8,6 +8,8 @@ package org.h2.mvstore.type;
import
java.nio.ByteBuffer
;
import
java.nio.ByteBuffer
;
import
org.h2.mvstore.WriteBuffer
;
/**
/**
* A data type.
* A data type.
*/
*/
...
@@ -36,9 +38,8 @@ public interface DataType {
...
@@ -36,9 +38,8 @@ public interface DataType {
*
*
* @param buff the target buffer
* @param buff the target buffer
* @param obj the value
* @param obj the value
* @return the byte buffer
*/
*/
ByteBuffer
write
(
By
teBuffer
buff
,
Object
obj
);
void
write
(
Wri
teBuffer
buff
,
Object
obj
);
/**
/**
* Read an object.
* Read an object.
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/type/ObjectDataType.java
浏览文件 @
9632595d
差异被折叠。
点击展开。
h2/src/main/org/h2/mvstore/type/StringDataType.java
浏览文件 @
9632595d
...
@@ -8,6 +8,7 @@ package org.h2.mvstore.type;
...
@@ -8,6 +8,7 @@ package org.h2.mvstore.type;
import
java.nio.ByteBuffer
;
import
java.nio.ByteBuffer
;
import
org.h2.mvstore.DataUtils
;
import
org.h2.mvstore.DataUtils
;
import
org.h2.mvstore.WriteBuffer
;
/**
/**
* A string type.
* A string type.
...
@@ -33,11 +34,11 @@ public class StringDataType implements DataType {
...
@@ -33,11 +34,11 @@ public class StringDataType implements DataType {
}
}
@Override
@Override
public
ByteBuffer
write
(
By
teBuffer
buff
,
Object
obj
)
{
public
void
write
(
Wri
teBuffer
buff
,
Object
obj
)
{
String
s
=
obj
.
toString
();
String
s
=
obj
.
toString
();
int
len
=
s
.
length
();
int
len
=
s
.
length
();
DataUtils
.
writeVarInt
(
buff
,
len
);
buff
.
writeVarInt
(
len
);
return
DataUtils
.
writeStringData
(
buff
,
s
,
len
);
buff
.
writeStringData
(
s
,
len
);
}
}
}
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/store/RowDataType.java
浏览文件 @
9632595d
...
@@ -8,6 +8,7 @@ package org.h2.test.store;
...
@@ -8,6 +8,7 @@ package org.h2.test.store;
import
java.nio.ByteBuffer
;
import
java.nio.ByteBuffer
;
import
org.h2.mvstore.DataUtils
;
import
org.h2.mvstore.DataUtils
;
import
org.h2.mvstore.WriteBuffer
;
import
org.h2.mvstore.type.DataType
;
import
org.h2.mvstore.type.DataType
;
/**
/**
...
@@ -69,15 +70,13 @@ public class RowDataType implements DataType {
...
@@ -69,15 +70,13 @@ public class RowDataType implements DataType {
}
}
@Override
@Override
public
ByteBuffer
write
(
By
teBuffer
buff
,
Object
obj
)
{
public
void
write
(
Wri
teBuffer
buff
,
Object
obj
)
{
Object
[]
x
=
(
Object
[])
obj
;
Object
[]
x
=
(
Object
[])
obj
;
int
len
=
x
.
length
;
int
len
=
x
.
length
;
DataUtils
.
writeVarInt
(
buff
,
len
);
buff
.
writeVarInt
(
len
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
buff
=
DataUtils
.
ensureCapacity
(
buff
,
0
);
types
[
i
].
write
(
buff
,
x
[
i
]);
buff
=
types
[
i
].
write
(
buff
,
x
[
i
]);
}
}
return
buff
;
}
}
}
}
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/store/TestObjectDataType.java
浏览文件 @
9632595d
...
@@ -13,6 +13,8 @@ import java.sql.Timestamp;
...
@@ -13,6 +13,8 @@ import java.sql.Timestamp;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.Random
;
import
java.util.Random
;
import
java.util.UUID
;
import
java.util.UUID
;
import
org.h2.mvstore.WriteBuffer
;
import
org.h2.mvstore.type.ObjectDataType
;
import
org.h2.mvstore.type.ObjectDataType
;
import
org.h2.test.TestBase
;
import
org.h2.test.TestBase
;
...
@@ -131,17 +133,18 @@ public class TestObjectDataType extends TestBase {
...
@@ -131,17 +133,18 @@ public class TestObjectDataType extends TestBase {
ot
.
getMemory
(
last
);
ot
.
getMemory
(
last
);
assertEquals
(
0
,
ot
.
compare
(
x
,
x
));
assertEquals
(
0
,
ot
.
compare
(
x
,
x
));
ByteBuffer
buff
=
ByteBuffer
.
allocate
(
1024
);
WriteBuffer
buff
=
new
WriteBuffer
(
);
ot
.
getMemory
(
last
);
ot
.
getMemory
(
last
);
buff
=
ot
.
write
(
buff
,
x
);
ot
.
write
(
buff
,
x
);
buff
.
put
((
byte
)
123
);
buff
.
put
((
byte
)
123
);
buff
.
flip
();
ByteBuffer
bb
=
buff
.
getBuffer
();
bb
.
flip
();
ot
.
getMemory
(
last
);
ot
.
getMemory
(
last
);
Object
y
=
ot
.
read
(
b
uff
);
Object
y
=
ot
.
read
(
b
b
);
assertEquals
(
123
,
b
uff
.
get
());
assertEquals
(
123
,
b
b
.
get
());
assertEquals
(
0
,
b
uff
.
remaining
());
assertEquals
(
0
,
b
b
.
remaining
());
assertEquals
(
x
.
getClass
().
getName
(),
y
.
getClass
().
getName
());
assertEquals
(
x
.
getClass
().
getName
(),
y
.
getClass
().
getName
());
ot
.
getMemory
(
last
);
ot
.
getMemory
(
last
);
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论