Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
5f5eb72d
提交
5f5eb72d
authored
11月 13, 2013
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
MVStore: simpler API
上级
7cb0c93e
显示空白字符变更
内嵌
并排
正在显示
14 个修改的文件
包含
326 行增加
和
309 行删除
+326
-309
MVMap.java
h2/src/main/org/h2/mvstore/MVMap.java
+1
-1
MVStore.java
h2/src/main/org/h2/mvstore/MVStore.java
+190
-177
MVSecondaryIndex.java
h2/src/main/org/h2/mvstore/db/MVSecondaryIndex.java
+1
-1
MVSpatialIndex.java
h2/src/main/org/h2/mvstore/db/MVSpatialIndex.java
+8
-7
MVTable.java
h2/src/main/org/h2/mvstore/db/MVTable.java
+1
-1
MVTableEngine.java
h2/src/main/org/h2/mvstore/db/MVTableEngine.java
+5
-9
TransactionStore.java
h2/src/main/org/h2/mvstore/db/TransactionStore.java
+19
-15
TestConcurrent.java
h2/src/test/org/h2/test/store/TestConcurrent.java
+12
-13
TestKillProcessWhileWriting.java
...c/test/org/h2/test/store/TestKillProcessWhileWriting.java
+4
-5
TestMVRTree.java
h2/src/test/org/h2/test/store/TestMVRTree.java
+2
-3
TestMVStore.java
h2/src/test/org/h2/test/store/TestMVStore.java
+71
-59
TestRandomMapOps.java
h2/src/test/org/h2/test/store/TestRandomMapOps.java
+7
-12
TestStreamStore.java
h2/src/test/org/h2/test/store/TestStreamStore.java
+4
-5
TestTransactionStore.java
h2/src/test/org/h2/test/store/TestTransactionStore.java
+1
-1
没有找到文件。
h2/src/main/org/h2/mvstore/MVMap.java
浏览文件 @
5f5eb72d
...
...
@@ -847,7 +847,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
* Forget those old versions that are no longer needed.
*/
void
removeUnusedOldVersions
()
{
long
oldest
=
store
.
get
RetainOrStoreVersion
();
long
oldest
=
store
.
get
OldestVersionToKeep
();
if
(
oldest
==
-
1
)
{
return
;
}
...
...
h2/src/main/org/h2/mvstore/MVStore.java
浏览文件 @
5f5eb72d
...
...
@@ -57,6 +57,10 @@ MVTableEngine:
TransactionStore:
MVStore:
- better document auto-commit (also when many unsaved pages)
advantages and disadvantages
- auto-commit when used in memory as well
- better document MVStore setters
- automated 'kill process' and 'power failure' test
- update checkstyle
- feature to auto-compact from time to time and on close
...
...
@@ -177,8 +181,7 @@ public class MVStore {
/**
* The map of chunks.
*/
private
final
ConcurrentHashMap
<
Integer
,
Chunk
>
chunks
=
new
ConcurrentHashMap
<
Integer
,
Chunk
>();
private
final
ConcurrentHashMap
<
Integer
,
Chunk
>
chunks
=
new
ConcurrentHashMap
<
Integer
,
Chunk
>();
/**
* The map of temporarily freed storage space caused by freed pages. The key
...
...
@@ -189,12 +192,12 @@ public class MVStore {
new
ConcurrentHashMap
<
Long
,
HashMap
<
Integer
,
Chunk
>>();
/**
* The metadata map. Write access to this map needs to be synchronized on the store.
* The metadata map. Write access to this map needs to be synchronized on
* the store.
*/
private
MVMap
<
String
,
String
>
meta
;
private
MVMap
Concurrent
<
String
,
String
>
meta
;
private
final
ConcurrentHashMap
<
Integer
,
MVMap
<?,
?>>
maps
=
new
ConcurrentHashMap
<
Integer
,
MVMap
<?,
?>>();
private
final
ConcurrentHashMap
<
Integer
,
MVMap
<?,
?>>
maps
=
new
ConcurrentHashMap
<
Integer
,
MVMap
<?,
?>>();
private
HashMap
<
String
,
String
>
storeHeader
=
New
.
hashMap
();
...
...
@@ -202,7 +205,7 @@ public class MVStore {
private
int
lastMapId
;
private
long
retainVersion
=
-
1
;
private
int
versionsToKeep
=
5
;
/**
* Whether to compress new pages. Even if disabled, the store may contain
...
...
@@ -222,14 +225,13 @@ public class MVStore {
private
long
lastStoredVersion
;
/**
* The estimated number of unsaved pages
* (this number may not be completely accurate,
* because it may be changed concurrently, and
* because temporary pages are counted)
* The estimated number of unsaved pages (this number may not be completely
* accurate, because it may be changed concurrently, and because temporary
* pages are counted)
*/
private
int
unsavedPageCount
;
private
int
unsavedPageCountMax
;
private
boolean
s
tor
eNeeded
;
private
int
autoCommitPageCount
;
private
boolean
s
av
eNeeded
;
/**
* The time the store was created, in milliseconds since 1970.
...
...
@@ -237,7 +239,7 @@ public class MVStore {
private
long
creationTime
;
private
int
retentionTime
;
private
long
last
Store
Time
;
private
long
last
Commit
Time
;
/**
* The earliest chunk to retain, if any.
...
...
@@ -254,9 +256,9 @@ public class MVStore {
private
volatile
boolean
metaChanged
;
/**
* The delay in milliseconds to automatically
stor
e changes.
* The delay in milliseconds to automatically
commit and writ
e changes.
*/
private
int
write
Delay
;
private
int
autoCommit
Delay
;
/**
* Create and open the store.
...
...
@@ -272,7 +274,8 @@ public class MVStore {
pageSplitSize
=
o
==
null
?
6
*
1024
:
(
Integer
)
o
;
o
=
config
.
get
(
"backgroundExceptionHandler"
);
this
.
backgroundExceptionHandler
=
(
UncaughtExceptionHandler
)
o
;
meta
=
new
MVMap
<
String
,
String
>(
StringDataType
.
INSTANCE
,
StringDataType
.
INSTANCE
);
meta
=
new
MVMapConcurrent
<
String
,
String
>(
StringDataType
.
INSTANCE
,
StringDataType
.
INSTANCE
);
HashMap
<
String
,
String
>
c
=
New
.
hashMap
();
c
.
put
(
"id"
,
"0"
);
c
.
put
(
"createVersion"
,
Long
.
toString
(
currentVersion
));
...
...
@@ -295,21 +298,21 @@ public class MVStore {
int
averageMemory
=
Math
.
max
(
10
,
pageSplitSize
/
2
);
int
segmentCount
=
16
;
int
stackMoveDistance
=
maxMemoryBytes
/
averageMemory
*
2
/
100
;
cache
=
new
CacheLongKeyLIRS
<
Page
>(
maxMemoryBytes
,
averageMemory
,
segmentCount
,
stackMoveDistance
);
cache
=
new
CacheLongKeyLIRS
<
Page
>(
maxMemoryBytes
,
averageMemory
,
segmentCount
,
stackMoveDistance
);
}
o
=
config
.
get
(
"
write
BufferSize"
);
o
=
config
.
get
(
"
autoCommit
BufferSize"
);
mb
=
o
==
null
?
4
:
(
Integer
)
o
;
int
writeBufferSize
=
mb
*
1024
*
1024
;
int
autoCommitBufferSize
=
mb
*
1024
*
1024
;
int
div
=
pageSplitSize
;
unsavedPageCountMax
=
write
BufferSize
/
(
div
==
0
?
1
:
div
);
autoCommitPageCount
=
autoCommit
BufferSize
/
(
div
==
0
?
1
:
div
);
char
[]
encryptionKey
=
(
char
[])
config
.
get
(
"encryptionKey"
);
try
{
fileStore
.
open
(
fileName
,
readOnly
,
encryptionKey
);
if
(
fileStore
.
size
()
==
0
)
{
creationTime
=
0
;
creationTime
=
getTime
();
last
Store
Time
=
creationTime
;
last
Commit
Time
=
creationTime
;
storeHeader
.
put
(
"H"
,
"3"
);
storeHeader
.
put
(
"blockSize"
,
""
+
BLOCK_SIZE
);
storeHeader
.
put
(
"format"
,
""
+
FORMAT_WRITE
);
...
...
@@ -348,14 +351,13 @@ public class MVStore {
Arrays
.
fill
(
encryptionKey
,
(
char
)
0
);
}
}
last
Store
Time
=
getTime
();
last
Commit
Time
=
getTime
();
// setWriteDelay starts the thread, but only if
// the parameter is different than the current value
o
=
config
.
get
(
"writeDelay"
);
int
writeDelay
=
o
==
null
?
1000
:
(
Integer
)
o
;
setWriteDelay
(
writeDelay
);
// setAutoCommitDelay starts the thread, but only if
// the parameter is different from the old value
o
=
config
.
get
(
"autoCommitDelay"
);
int
delay
=
o
==
null
?
1000
:
(
Integer
)
o
;
setAutoCommitDelay
(
delay
);
}
/**
...
...
@@ -380,7 +382,8 @@ public class MVStore {
* @return the read-only map
*/
@SuppressWarnings
(
"unchecked"
)
<
T
extends
MVMap
<?,
?>>
T
openMapVersion
(
long
version
,
int
mapId
,
MVMap
<?,
?>
template
)
{
<
T
extends
MVMap
<?,
?>>
T
openMapVersion
(
long
version
,
int
mapId
,
MVMap
<?,
?>
template
)
{
MVMap
<
String
,
String
>
oldMeta
=
getMetaMap
(
version
);
String
r
=
oldMeta
.
get
(
"root."
+
mapId
);
long
rootPos
=
DataUtils
.
parseLong
(
r
,
0
);
...
...
@@ -512,7 +515,7 @@ public class MVStore {
metaChanged
=
true
;
}
private
void
readMeta
()
{
private
synchronized
void
readMeta
()
{
chunks
.
clear
();
Chunk
header
=
readChunkHeader
(
rootChunkStart
);
if
(
header
.
start
==
Long
.
MAX_VALUE
)
{
...
...
@@ -569,7 +572,8 @@ public class MVStore {
// we don't know which chunk is the newest
long
newestChunk
=
-
1
;
// read the last block of the file, and then the two first blocks
ByteBuffer
buffLastBlock
=
fileStore
.
readFully
(
fileStore
.
size
()
-
BLOCK_SIZE
,
BLOCK_SIZE
);
ByteBuffer
buffLastBlock
=
fileStore
.
readFully
(
fileStore
.
size
()
-
BLOCK_SIZE
,
BLOCK_SIZE
);
ByteBuffer
buffFirst2Blocks
=
fileStore
.
readFully
(
0
,
BLOCK_SIZE
*
2
);
ByteBuffer
buff
=
ByteBuffer
.
allocate
(
3
*
BLOCK_SIZE
);
buff
.
put
(
buffLastBlock
);
...
...
@@ -611,7 +615,8 @@ public class MVStore {
}
if
(
currentVersion
<
0
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_FILE_CORRUPT
,
"Store header is corrupt: {0}"
,
fileStore
);
DataUtils
.
ERROR_FILE_CORRUPT
,
"Store header is corrupt: {0}"
,
fileStore
);
}
setWriteVersion
(
currentVersion
);
lastStoredVersion
=
-
1
;
...
...
@@ -647,10 +652,7 @@ public class MVStore {
}
/**
* Close the file and the store. If there are any uncommitted changes, they
* are written to disk first. All open maps are closed.
* <p>
* It is not allowed to concurrently call close and store.
* Close the file and the store. Unsaved changes are written to disk first.
*/
public
void
close
()
{
if
(
closed
)
{
...
...
@@ -659,7 +661,7 @@ public class MVStore {
if
(
fileStore
!=
null
&&
!
fileStore
.
isReadOnly
())
{
stopBackgroundThread
();
if
(
hasUnsavedChanges
())
{
stor
e
();
commitAndSav
e
();
}
}
closeStore
(
true
);
...
...
@@ -722,6 +724,11 @@ public class MVStore {
int
chunkId
=
DataUtils
.
getPageChunkId
(
pos
);
Chunk
c
=
chunks
.
get
(
chunkId
);
if
(
c
==
null
)
{
if
(!
Thread
.
holdsLock
(
this
))
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_INTERNAL
,
"Unsynchronized metadata read"
);
}
String
s
=
meta
.
get
(
"chunk."
+
chunkId
);
if
(
s
==
null
)
{
throw
DataUtils
.
newIllegalStateException
(
...
...
@@ -747,18 +754,22 @@ public class MVStore {
}
/**
* Commit the changes. This method marks the changes as committed and
* increments the version.
* Commit the changes.
* <p>
* For in-memory stores, this method increments the version.
* <p>
* Unless the write delay is set to 0, this method does not write to the
* file. Instead, data is written after the delay, manually by calling the
* store method, when the write buffer is full, or when closing the store.
* For persistent stores, it also writes changes to disk. It does nothing if
* there are no unsaved changes, and returns the old version. It is not
* necessary to call this method when auto-commit is enabled (the default
* setting), as in this case it is automatically called from time to time or
* when enough changes have accumulated. However, it may still be called to
* flush all changes to disk.
*
* @return the new version
*/
public
long
commit
()
{
if
(
fileStore
!=
null
)
{
return
stor
e
();
return
commitAndSav
e
();
}
long
v
=
++
currentVersion
;
setWriteVersion
(
v
);
...
...
@@ -774,13 +785,14 @@ public class MVStore {
*
* @return the new version (incremented if there were changes)
*/
p
ublic
synchronized
long
stor
e
()
{
p
rivate
synchronized
long
commitAndSav
e
()
{
if
(
closed
)
{
return
currentVersion
;
}
if
(
fileStore
==
null
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_WRITING_FAILED
,
"This is an in-memory store"
);
DataUtils
.
ERROR_WRITING_FAILED
,
"This is an in-memory store"
);
}
if
(
currentStoreVersion
>=
0
)
{
// store is possibly called within store, if the meta map changed
...
...
@@ -811,7 +823,7 @@ public class MVStore {
long
version
=
++
currentVersion
;
setWriteVersion
(
version
);
long
time
=
getTime
();
last
Store
Time
=
time
;
last
Commit
Time
=
time
;
retainChunk
=
null
;
// the last chunk was not completely correct in the last store()
...
...
@@ -903,14 +915,6 @@ public class MVStore {
}
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
.
length
=
chunkLength
;
c
.
metaRootPos
=
metaRoot
.
getPos
();
...
...
@@ -944,8 +948,10 @@ public class MVStore {
}
metaRoot
.
writeEnd
();
// some pages might have been changed in the meantime (in the newest version)
unsavedPageCount
=
Math
.
max
(
0
,
unsavedPageCount
-
currentUnsavedPageCount
);
// some pages might have been changed in the meantime (in the newest
// version)
unsavedPageCount
=
Math
.
max
(
0
,
unsavedPageCount
-
currentUnsavedPageCount
);
metaChanged
=
false
;
lastStoredVersion
=
storeVersion
;
...
...
@@ -1098,7 +1104,8 @@ public class MVStore {
long
size
=
2
*
BLOCK_SIZE
;
for
(
Chunk
c
:
chunks
.
values
())
{
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
);
}
return
size
;
}
...
...
@@ -1109,8 +1116,6 @@ public class MVStore {
* @return if there are any changes
*/
public
boolean
hasUnsavedChanges
()
{
// TODO maybe private; rename to hasUncommittedChanges
checkOpen
();
if
(
metaChanged
)
{
return
true
;
...
...
@@ -1160,7 +1165,8 @@ public class MVStore {
chunks
.
remove
(
c
.
id
);
markMetaChanged
();
meta
.
remove
(
"chunk."
+
c
.
id
);
int
length
=
MathUtils
.
roundUpInt
(
c
.
length
,
BLOCK_SIZE
)
+
BLOCK_SIZE
;
int
length
=
MathUtils
.
roundUpInt
(
c
.
length
,
BLOCK_SIZE
)
+
BLOCK_SIZE
;
fileStore
.
free
(
c
.
start
,
length
);
}
if
(
fileStore
.
getFillRate
()
==
100
)
{
...
...
@@ -1175,7 +1181,8 @@ public class MVStore {
}
for
(
Chunk
c
:
move
)
{
WriteBuffer
buff
=
getWriteBuffer
();
int
length
=
MathUtils
.
roundUpInt
(
c
.
length
,
BLOCK_SIZE
)
+
BLOCK_SIZE
;
int
length
=
MathUtils
.
roundUpInt
(
c
.
length
,
BLOCK_SIZE
)
+
BLOCK_SIZE
;
buff
.
limit
(
length
);
ByteBuffer
buff2
=
fileStore
.
readFully
(
c
.
start
,
length
);
buff
.
put
(
buff2
);
...
...
@@ -1200,7 +1207,7 @@ public class MVStore {
// update the metadata (store at the end of the file)
reuseSpace
=
false
;
stor
e
();
commitAndSav
e
();
sync
();
...
...
@@ -1213,7 +1220,8 @@ public class MVStore {
continue
;
}
WriteBuffer
buff
=
getWriteBuffer
();
int
length
=
MathUtils
.
roundUpInt
(
c
.
length
,
BLOCK_SIZE
)
+
BLOCK_SIZE
;
int
length
=
MathUtils
.
roundUpInt
(
c
.
length
,
BLOCK_SIZE
)
+
BLOCK_SIZE
;
buff
.
limit
(
length
);
ByteBuffer
buff2
=
fileStore
.
readFully
(
c
.
start
,
length
);
buff
.
put
(
buff2
);
...
...
@@ -1235,7 +1243,7 @@ public class MVStore {
}
// update the metadata (within the file)
stor
e
();
commitAndSav
e
();
sync
();
shrinkFileIfPossible
(
0
);
...
...
@@ -1309,7 +1317,8 @@ public class MVStore {
Collections
.
sort
(
old
,
new
Comparator
<
Chunk
>()
{
@Override
public
int
compare
(
Chunk
o1
,
Chunk
o2
)
{
return
new
Integer
(
o1
.
collectPriority
).
compareTo
(
o2
.
collectPriority
);
return
new
Integer
(
o1
.
collectPriority
)
.
compareTo
(
o2
.
collectPriority
);
}
});
...
...
@@ -1341,7 +1350,7 @@ public class MVStore {
copyLive
(
c
,
old
);
}
stor
e
();
commitAndSav
e
();
return
true
;
}
...
...
@@ -1413,7 +1422,8 @@ public class MVStore {
filePos
+=
DataUtils
.
getPageOffset
(
pos
);
if
(
filePos
<
0
)
{
throw
DataUtils
.
newIllegalStateException
(
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
());
if
(
cache
!=
null
)
{
...
...
@@ -1460,11 +1470,13 @@ public class MVStore {
registerFreePage
(
version
,
c
.
id
,
DataUtils
.
getPageMaxLength
(
pos
),
1
);
}
private
void
registerFreePage
(
long
version
,
int
chunkId
,
long
maxLengthLive
,
int
pageCount
)
{
private
void
registerFreePage
(
long
version
,
int
chunkId
,
long
maxLengthLive
,
int
pageCount
)
{
HashMap
<
Integer
,
Chunk
>
freed
=
freedPageSpace
.
get
(
version
);
if
(
freed
==
null
)
{
freed
=
New
.
hashMap
();
HashMap
<
Integer
,
Chunk
>
f2
=
freedPageSpace
.
putIfAbsent
(
version
,
freed
);
HashMap
<
Integer
,
Chunk
>
f2
=
freedPageSpace
.
putIfAbsent
(
version
,
freed
);
if
(
f2
!=
null
)
{
freed
=
f2
;
}
...
...
@@ -1541,13 +1553,13 @@ public class MVStore {
}
/**
*
Which version to retain in memory. If not set, all versions back to the
*
last stored version
are retained.
*
How many versions to retain for in-memory stores. If not set, 5 versions
* are retained.
*
* @param
retainVersion the oldest version to retain
* @param
count the number of versions to keep
*/
public
void
set
RetainVersion
(
long
retainVersion
)
{
this
.
retainVersion
=
retainVersion
;
public
void
set
VersionsToKeep
(
int
count
)
{
this
.
versionsToKeep
=
count
;
}
/**
...
...
@@ -1555,13 +1567,8 @@ public class MVStore {
*
* @return the version
*/
public
long
getRetainVersion
()
{
long
v
=
retainVersion
;
long
storeVersion
=
currentStoreVersion
;
if
(
storeVersion
>
-
1
)
{
v
=
Math
.
min
(
v
,
storeVersion
);
}
return
v
;
public
long
getVersionsToKeep
()
{
return
versionsToKeep
;
}
/**
...
...
@@ -1570,8 +1577,11 @@ public class MVStore {
*
* @return the version
*/
long
getRetainOrStoreVersion
()
{
long
v
=
retainVersion
;
long
getOldestVersionToKeep
()
{
long
v
=
currentVersion
;
if
(
fileStore
==
null
)
{
return
v
-
versionsToKeep
;
}
long
storeVersion
=
currentStoreVersion
;
if
(
storeVersion
>
-
1
)
{
v
=
Math
.
min
(
v
,
storeVersion
);
...
...
@@ -1618,34 +1628,13 @@ public class MVStore {
return
true
;
}
/**
* Get the estimated number of unsaved pages. The returned value is not
* accurate, specially after rollbacks, but can be used to estimate the
* memory usage for unsaved data.
*
* @return the number of unsaved pages
*/
public
int
getUnsavedPageCount
()
{
return
unsavedPageCount
;
}
/**
* Get the maximum number of unsaved pages. If this number is exceeded, the
* unsaved changes are stored to disk.
*
* @return the number of maximum unsaved pages
*/
public
int
getUnsavedPageCountMax
()
{
return
unsavedPageCountMax
;
}
/**
* Increment the number of unsaved pages.
*/
void
registerUnsavedPage
()
{
int
count
=
++
unsavedPageCount
;
if
(
count
>
unsavedPageCountMax
&&
unsavedPageCountMax
>
0
)
{
s
tor
eNeeded
=
true
;
if
(
count
>
autoCommitPageCount
&&
autoCommitPageCount
>
0
)
{
s
av
eNeeded
=
true
;
}
}
...
...
@@ -1653,9 +1642,9 @@ public class MVStore {
* This method is called before writing to a map.
*/
void
beforeWrite
()
{
if
(
s
tor
eNeeded
)
{
s
tor
eNeeded
=
false
;
stor
e
();
if
(
s
av
eNeeded
)
{
s
av
eNeeded
=
false
;
commitAndSav
e
();
}
}
...
...
@@ -1684,11 +1673,10 @@ public class MVStore {
}
/**
* Revert to the beginning of the current version.
* Revert to the beginning of the current version, reverting all uncommitted
* changes.
*/
public
void
rollback
()
{
// TODO document and test
rollbackTo
(
currentVersion
);
}
...
...
@@ -1841,8 +1829,8 @@ public class MVStore {
private
void
checkOpen
()
{
if
(
closed
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_CLOSED
,
"This store is closed"
);
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_CLOSED
,
"This store is closed"
);
}
}
...
...
@@ -1901,9 +1889,9 @@ public class MVStore {
}
/**
*
Store all unsaved changes, if there are any that are committed
.
*
Commit and save all changes, if there are any
.
*/
void
store
InBackground
()
{
void
commit
InBackground
()
{
if
(
unsavedPageCount
==
0
||
closed
)
{
return
;
}
...
...
@@ -1912,14 +1900,14 @@ public class MVStore {
// but according to a test it doesn't really help
long
time
=
getTime
();
if
(
time
<=
last
StoreTime
+
write
Delay
)
{
if
(
time
<=
last
CommitTime
+
autoCommit
Delay
)
{
return
;
}
if
(!
hasUnsavedChanges
())
{
return
;
}
try
{
stor
e
();
commitAndSav
e
();
}
catch
(
Exception
e
)
{
if
(
backgroundExceptionHandler
!=
null
)
{
backgroundExceptionHandler
.
uncaughtException
(
null
,
e
);
...
...
@@ -1959,25 +1947,21 @@ public class MVStore {
}
/**
* Set the maximum delay in milliseconds to commit changes.
* Set the maximum delay in milliseconds to
auto-
commit changes.
* <p>
* T
he default is 1000, meaning changes are committed after at
*
most one second
.
* T
o disable auto-commit, set the value to 0. In this case, changes are
*
only committed when explicitly calling commit
.
* <p>
* When the value is set to -1, changes are only written when
* calling the store method. When the value is set to 0, committed
* changes are immediately written on a commit, but please note this
* decreases performance and does still not guarantee the disk will
* actually write the data.
* The default is 1000, meaning all changes are committed after at most one
* second.
*
* @param millis the maximum delay
*/
public
void
setWriteDelay
(
int
millis
)
{
// TODO rename to commitDelay
if
(
writeDelay
==
millis
)
{
public
void
setAutoCommitDelay
(
int
millis
)
{
if
(
autoCommitDelay
==
millis
)
{
return
;
}
write
Delay
=
millis
;
autoCommit
Delay
=
millis
;
if
(
fileStore
==
null
)
{
return
;
}
...
...
@@ -1991,8 +1975,36 @@ public class MVStore {
}
}
public
int
getWriteDelay
()
{
return
writeDelay
;
/**
* Get the auto-commit delay.
*
* @return the delay in milliseconds, or 0 if auto-commit is disabled.
*/
public
int
getAutoCommitDelay
()
{
return
autoCommitDelay
;
}
/**
* Get the maximum number of unsaved pages. If this number is exceeded,
* unsaved changes are stored to disk.
*
* @return the number of maximum unsaved pages
*/
public
int
getAutoCommitPageCount
()
{
return
autoCommitPageCount
;
}
/**
* Get the estimated number of unsaved pages. If the value exceeds the
* auto-commit page count, the changes are committed.
* <p>
* The returned value may not be completely accurate, but can be used to
* estimate the memory usage for unsaved data.
*
* @return the number of unsaved pages
*/
public
int
getUnsavedPageCount
()
{
return
unsavedPageCount
;
}
/**
...
...
@@ -2000,9 +2012,9 @@ public class MVStore {
*/
private
static
class
BackgroundWriterThread
extends
Thread
{
public
final
Object
sync
=
new
Object
();
private
final
MVStore
store
;
private
final
int
sleep
;
public
final
Object
sync
=
new
Object
();
BackgroundWriterThread
(
MVStore
store
,
int
sleep
,
String
fileStoreName
)
{
super
(
"MVStore background writer "
+
fileStoreName
);
...
...
@@ -2025,7 +2037,7 @@ public class MVStore {
continue
;
}
}
store
.
store
InBackground
();
store
.
commit
InBackground
();
}
}
...
...
@@ -2043,6 +2055,38 @@ public class MVStore {
return
this
;
}
/**
* Disable auto-commit, by setting the auto-commit delay and auto-commit
* buffer size to 0.
*
* @return this
*/
public
Builder
autoCommitDisabled
()
{
// we have a separate config option so that
// no thread is started if the write delay is 0
// (if we only had a setter in the MVStore,
// the thread would need to be started in any case)
set
(
"autoCommitBufferSize"
,
0
);
return
set
(
"autoCommitDelay"
,
0
);
}
/**
* Set the size of the write buffer, in MB (for file-based stores).
* Unless auto-commit is disabled, changes are automatically saved if
* there are more than this amount of changes.
* <p>
* The default is 4 MB.
* <p>
* When the value is set to 0 or lower, data is not automatically
* stored.
*
* @param mb the write buffer size, in megabytes
* @return this
*/
public
Builder
autoCommitBufferSize
(
int
mb
)
{
return
set
(
"autoCommitBufferSize"
,
mb
);
}
/**
* Use the following file name. If the file does not exist, it is
* automatically created. The parent directory already must exist.
...
...
@@ -2076,8 +2120,8 @@ public class MVStore {
* If this option is not used, the file is locked exclusively.
* <p>
* Please note a store may only be opened once in every JVM (no matter
* whether it is opened in read-only or read-write mode), because each
file
* may be locked only once in a process.
* whether it is opened in read-only or read-write mode), because each
*
file
may be locked only once in a process.
*
* @return this
*/
...
...
@@ -2110,23 +2154,6 @@ public class MVStore {
return
set
(
"compress"
,
1
);
}
/**
* Set the size of the write buffer, in MB (for file-based stores).
* Unless auto-commit is disabled, changes are automatically stored if
* the buffer grows larger than this.
* <p>
* The default is 4 MB.
* <p>
* When the value is set to 0 or lower, data is never automatically
* stored.
*
* @param mb the write buffer size, in megabytes
* @return this
*/
public
Builder
writeBufferSize
(
int
mb
)
{
return
set
(
"writeBufferSize"
,
mb
);
}
/**
* Set the amount of memory a page should contain at most, in bytes,
* before it is split. The default is 6 KB. This is not a limit in the
...
...
@@ -2141,8 +2168,8 @@ public class MVStore {
}
/**
* Set the listener to be used for exceptions that occur
in the background
* thread.
* Set the listener to be used for exceptions that occur
when writing in
* th
e background th
read.
*
* @param exceptionHandler the handler
* @return this
...
...
@@ -2162,20 +2189,6 @@ public class MVStore {
return
set
(
"fileStore"
,
store
);
}
/**
* Set the initial write delay.
*
* @param writeDelay the write delay
* @return this
*/
public
Builder
writeDelay
(
int
writeDelay
)
{
// we have a separate config option so that
// no thread is started if the write delay is 0
// (if we only had a setter in the MVStore,
// the thread would need to be started in any case)
return
set
(
"writeDelay"
,
writeDelay
);
}
/**
* Open the store.
*
...
...
h2/src/main/org/h2/mvstore/db/MVSecondaryIndex.java
浏览文件 @
5f5eb72d
...
...
@@ -96,7 +96,7 @@ public class MVSecondaryIndex extends BaseIndex {
}
}
try
{
map
.
put
(
array
,
Value
Long
.
get
(
0
)
);
map
.
put
(
array
,
Value
Null
.
INSTANCE
);
}
catch
(
IllegalStateException
e
)
{
throw
DbException
.
get
(
ErrorCode
.
CONCURRENT_UPDATE_1
,
table
.
getName
());
}
...
...
h2/src/main/org/h2/mvstore/db/MVSpatialIndex.java
浏览文件 @
5f5eb72d
...
...
@@ -58,6 +58,7 @@ public class MVSpatialIndex extends BaseIndex implements SpatialIndex {
/**
* Constructor.
*
* @param db the database
* @param table the table instance
* @param id the index id
* @param indexName the index name
...
...
h2/src/main/org/h2/mvstore/db/MVTable.java
浏览文件 @
5f5eb72d
h2/src/main/org/h2/mvstore/db/MVTableEngine.java
浏览文件 @
5f5eb72d
...
...
@@ -168,13 +168,13 @@ public class MVTableEngine implements TableEngine {
/**
* Store all pending changes.
*/
public
void
store
()
{
public
void
flush
()
{
FileStore
s
=
store
.
getFileStore
();
if
(
s
==
null
||
s
.
isReadOnly
())
{
return
;
}
if
(!
store
.
compact
(
50
))
{
store
.
store
();
store
.
commit
();
}
}
...
...
@@ -213,9 +213,7 @@ public class MVTableEngine implements TableEngine {
Transaction
t
=
session
.
getTransaction
();
t
.
setName
(
transactionName
);
t
.
prepare
();
if
(
store
.
getFileStore
()
!=
null
)
{
store
.
store
();
}
store
.
commit
();
}
public
ArrayList
<
InDoubtTransaction
>
getInDoubtTransactions
()
{
...
...
@@ -245,7 +243,7 @@ public class MVTableEngine implements TableEngine {
* Force the changes to disk.
*/
public
void
sync
()
{
store
();
flush
();
store
.
sync
();
}
...
...
@@ -316,9 +314,7 @@ public class MVTableEngine implements TableEngine {
}
else
{
transaction
.
rollback
();
}
if
(
store
.
getFileStore
()
!=
null
)
{
store
.
store
();
}
store
.
commit
();
this
.
state
=
state
;
}
...
...
h2/src/main/org/h2/mvstore/db/TransactionStore.java
浏览文件 @
5f5eb72d
...
...
@@ -170,9 +170,7 @@ public class TransactionStore {
public
synchronized
void
close
()
{
// to avoid losing transaction ids
settings
.
put
(
LAST_TRANSACTION_ID
,
""
+
lastTransactionId
);
if
(
store
.
getFileStore
()
!=
null
)
{
store
.
store
();
}
store
.
commit
();
}
/**
...
...
@@ -192,9 +190,7 @@ public class TransactionStore {
private
void
commitIfNeeded
()
{
if
(
store
.
getUnsavedPageCount
()
>
MAX_UNSAVED_PAGES
)
{
if
(
store
.
getFileStore
()
!=
null
)
{
store
.
store
();
}
store
.
commit
();
}
}
...
...
@@ -354,10 +350,8 @@ public class TransactionStore {
if
(
t
.
getId
()
==
firstOpenTransaction
)
{
firstOpenTransaction
=
-
1
;
}
if
(
store
.
getWriteDelay
()
==
0
)
{
if
(
store
.
getFileStore
()
!=
null
)
{
store
.
store
();
}
if
(
store
.
getAutoCommitDelay
()
==
0
)
{
store
.
commit
();
return
;
}
// to avoid having to store the transaction log,
...
...
@@ -365,10 +359,10 @@ public class TransactionStore {
// and if there have been many changes, store them now
if
(
undoLog
.
isEmpty
())
{
int
unsaved
=
store
.
getUnsavedPageCount
();
int
max
=
store
.
get
UnsavedPageCountMax
();
int
max
=
store
.
get
AutoCommitPageCount
();
// save at 3/4 capacity
if
(
unsaved
*
4
>
max
*
3
)
{
store
.
store
();
store
.
commit
();
}
}
}
...
...
@@ -659,6 +653,14 @@ public class TransactionStore {
return
new
TransactionMap
<
K
,
V
>(
this
,
map
,
mapId
);
}
/**
* Open the transactional version of the given map.
*
* @param <K> the key type
* @param <V> the value type
* @param map the base map
* @return the transactional map
*/
public
<
K
,
V
>
TransactionMap
<
K
,
V
>
openMap
(
MVMap
<
K
,
VersionedValue
>
map
)
{
checkNotClosed
();
int
mapId
=
map
.
getId
();
...
...
@@ -729,6 +731,8 @@ public class TransactionStore {
/**
* Remove the map.
*
* @param map the map
*/
public
<
K
,
V
>
void
removeMap
(
TransactionMap
<
K
,
V
>
map
)
{
store
.
store
.
removeMap
(
map
.
map
);
...
...
h2/src/test/org/h2/test/store/TestConcurrent.java
浏览文件 @
5f5eb72d
...
...
@@ -62,20 +62,19 @@ public class TestConcurrent extends TestMVStore {
for
(
int
test
=
0
;
test
<
10
;
test
++)
{
FileUtils
.
delete
(
fileName
);
final
MVStore
s1
=
new
MVStore
.
Builder
().
fileName
(
fileName
).
writeDelay
(-
1
).
open
();
fileName
(
fileName
).
autoCommitDisabled
(
).
open
();
s1
.
setRetentionTime
(
0
);
final
int
count
=
200
;
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
MVMap
<
Integer
,
Integer
>
m
=
s1
.
openMap
(
"d"
+
i
);
m
.
put
(
1
,
1
);
if
(
i
%
2
==
0
)
{
s1
.
store
();
s1
.
commit
();
}
}
s1
.
store
();
s1
.
close
();
final
MVStore
s
=
new
MVStore
.
Builder
().
fileName
(
fileName
).
writeDelay
(-
1
).
open
();
fileName
(
fileName
).
autoCommitDisabled
(
).
open
();
s
.
setRetentionTime
(
0
);
final
ArrayList
<
MVMap
<
Integer
,
Integer
>>
list
=
New
.
arrayList
();
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
...
...
@@ -113,7 +112,7 @@ public class TestConcurrent extends TestMVStore {
}
}
task
.
get
();
s
.
store
();
s
.
commit
();
MVMap
<
String
,
String
>
meta
=
s
.
getMetaMap
();
int
chunkCount
=
0
;
...
...
@@ -142,7 +141,7 @@ public class TestConcurrent extends TestMVStore {
public
void
call
()
throws
Exception
{
while
(!
stop
)
{
counter
.
incrementAndGet
();
s
.
store
();
s
.
commit
();
}
}
};
...
...
@@ -172,7 +171,7 @@ public class TestConcurrent extends TestMVStore {
public
void
call
()
throws
Exception
{
while
(!
stop
)
{
s
.
setStoreVersion
(
counter
.
incrementAndGet
());
s
.
store
();
s
.
commit
();
}
}
};
...
...
@@ -270,9 +269,9 @@ public class TestConcurrent extends TestMVStore {
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
map
.
put
(
i
,
new
byte
[
100
*
r
.
nextInt
(
100
)]);
}
s
.
store
();
s
.
commit
();
map
.
clear
();
s
.
store
();
s
.
commit
();
long
len
=
s
.
getFileStore
().
size
();
if
(
len
>
1024
*
1024
)
{
// slow down writing a lot
...
...
@@ -322,6 +321,7 @@ public class TestConcurrent extends TestMVStore {
private
void
testConcurrentIterate
()
{
MVStore
s
=
new
MVStore
.
Builder
().
pageSplitSize
(
3
).
open
();
s
.
setVersionsToKeep
(
100
);
final
MVMap
<
Integer
,
Integer
>
map
=
s
.
openMap
(
"test"
);
final
int
len
=
10
;
final
Random
r
=
new
Random
();
...
...
@@ -343,7 +343,6 @@ public class TestConcurrent extends TestMVStore {
Iterator
<
Integer
>
it
=
map
.
keyIterator
(
r
.
nextInt
(
len
));
long
old
=
s
.
getCurrentVersion
();
s
.
commit
();
s
.
setRetainVersion
(
old
-
100
);
while
(
map
.
getVersion
()
==
old
)
{
Thread
.
yield
();
}
...
...
h2/src/test/org/h2/test/store/TestKillProcessWhileWriting.java
浏览文件 @
5f5eb72d
...
...
@@ -84,9 +84,8 @@ public class TestKillProcessWhileWriting extends TestBase {
s
=
new
MVStore
.
Builder
().
fileName
(
fileName
).
pageSplitSize
(
50
).
writeDelay
(
0
).
autoCommitDisabled
(
).
open
();
s
.
setWriteDelay
(
0
);
m
=
s
.
openMap
(
"data"
);
Random
r
=
new
Random
(
seed
);
int
op
=
0
;
...
...
@@ -107,7 +106,7 @@ public class TestKillProcessWhileWriting extends TestBase {
m
.
remove
(
k
);
break
;
case
6
:
s
.
store
();
s
.
commit
();
break
;
case
7
:
s
.
compact
(
80
);
...
...
@@ -120,12 +119,12 @@ public class TestKillProcessWhileWriting extends TestBase {
s
=
new
MVStore
.
Builder
().
fileName
(
fileName
).
pageSplitSize
(
50
).
writeDelay
(
0
).
open
();
autoCommitDisabled
().
open
();
m
=
s
.
openMap
(
"data"
);
break
;
}
}
s
.
store
();
s
.
close
();
return
0
;
}
catch
(
Exception
e
)
{
...
...
h2/src/test/org/h2/test/store/TestMVRTree.java
浏览文件 @
5f5eb72d
...
...
@@ -119,7 +119,7 @@ public class TestMVRTree extends TestMVStore {
SpatialKey
k
=
new
SpatialKey
(
i
,
x
-
p
,
x
+
p
,
y
-
p
,
y
+
p
);
r
.
add
(
k
,
""
+
i
);
if
(
i
>
0
&&
(
i
%
len
/
10
)
==
0
)
{
s
.
store
();
s
.
commit
();
}
if
(
i
>
0
&&
(
i
%
10000
)
==
0
)
{
render
(
r
,
getBaseDir
()
+
"/test.png"
);
...
...
@@ -127,7 +127,6 @@ public class TestMVRTree extends TestMVStore {
}
// System.out.println(prof.getTop(5));
// System.out.println("add: " + (System.currentTimeMillis() - t));
s
.
store
();
s
.
close
();
s
=
openStore
(
fileName
);
r
=
s
.
openMap
(
"data"
,
...
...
h2/src/test/org/h2/test/store/TestMVStore.java
浏览文件 @
5f5eb72d
...
...
@@ -48,6 +48,8 @@ public class TestMVStore extends TestBase {
public
void
test
()
throws
Exception
{
FileUtils
.
deleteRecursive
(
getBaseDir
(),
true
);
FileUtils
.
createDirectories
(
getBaseDir
());
testRollback
();
testVersionsToKeep
();
testRemoveMap
();
testIsEmpty
();
testOffHeapStorage
();
...
...
@@ -97,6 +99,26 @@ public class TestMVStore extends TestBase {
testLargerThan2G
();
}
private
void
testVersionsToKeep
()
throws
Exception
{
MVStore
s
=
new
MVStore
.
Builder
().
open
();
MVMap
<
Integer
,
Integer
>
map
;
map
=
s
.
openMap
(
"data"
);
for
(
int
i
=
0
;
i
<
20
;
i
++)
{
long
version
=
s
.
getCurrentVersion
();
map
.
put
(
i
,
i
);
s
.
commit
();
if
(
version
>=
6
)
{
map
.
openVersion
(
version
-
6
);
try
{
map
.
openVersion
(
version
-
7
);
fail
();
}
catch
(
IllegalArgumentException
e
)
{
// expected
}
}
}
}
private
void
testRemoveMap
()
throws
Exception
{
String
fileName
=
getBaseDir
()
+
"/testCloseMap.h3"
;
FileUtils
.
delete
(
fileName
);
...
...
@@ -108,15 +130,14 @@ public class TestMVStore extends TestBase {
map
=
s
.
openMap
(
"data"
);
map
.
put
(
1
,
1
);
assertEquals
(
1
,
map
.
get
(
1
).
intValue
());
s
.
store
();
s
.
commit
();
s
.
removeMap
(
map
);
s
.
store
();
s
.
commit
();
map
=
s
.
openMap
(
"data"
);
assertTrue
(
map
.
isEmpty
());
map
.
put
(
2
,
2
);
s
.
store
();
s
.
close
();
}
...
...
@@ -145,7 +166,7 @@ public class TestMVStore extends TestBase {
Map
<
Integer
,
String
>
map
=
s
.
openMap
(
"data"
);
for
(
int
i
=
0
;
i
<
1000
;
i
++)
{
map
.
put
(
i
,
"Hello "
+
i
);
s
.
store
();
s
.
commit
();
}
assertTrue
(
1000
<
offHeap
.
getWriteCount
());
s
.
close
();
...
...
@@ -173,7 +194,6 @@ public class TestMVStore extends TestBase {
header
.
put
(
"format"
,
"2"
);
MVMap
<
Integer
,
String
>
m
=
s
.
openMap
(
"data"
);
m
.
put
(
0
,
"Hello World"
);
s
.
store
();
s
.
close
();
try
{
...
...
@@ -218,12 +238,12 @@ public class TestMVStore extends TestBase {
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
m
=
s
.
openMap
(
"data"
+
i
);
m
.
put
(
0
,
"Hello World"
);
s
.
store
();
s
.
commit
();
}
for
(
int
i
=
0
;
i
<
10
;
i
+=
2
)
{
m
=
s
.
openMap
(
"data"
+
i
);
s
.
removeMap
(
m
);
s
.
store
();
s
.
commit
();
}
long
sizeOld
=
s
.
getFileStore
().
size
();
s
.
compactMoveChunks
();
...
...
@@ -248,7 +268,7 @@ public class TestMVStore extends TestBase {
}).
open
();
s
.
set
Write
Delay
(
2
);
s
.
set
AutoCommit
Delay
(
2
);
MVMap
<
Integer
,
String
>
m
;
m
=
s
.
openMap
(
"data"
);
s
.
getFileStore
().
getFile
().
close
();
...
...
@@ -313,7 +333,7 @@ public class TestMVStore extends TestBase {
for
(
int
bs
=
0
;
bs
<=
1
;
bs
++)
{
s
=
new
MVStore
.
Builder
().
fileName
(
fileName
).
write
BufferSize
(
bs
).
autoCommit
BufferSize
(
bs
).
open
();
m
=
s
.
openMap
(
"data"
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
...
...
@@ -332,7 +352,7 @@ public class TestMVStore extends TestBase {
assertTrue
(
m
.
containsKey
(
1
));
m
.
put
(-
1
,
data
);
s
.
store
();
s
.
commit
();
m
.
put
(-
2
,
data
);
s
.
close
();
...
...
@@ -354,15 +374,15 @@ public class TestMVStore extends TestBase {
FileUtils
.
delete
(
fileName
);
s
=
new
MVStore
.
Builder
().
autoCommitDisabled
().
fileName
(
fileName
).
open
();
s
.
setWriteDelay
(
0
);
m
=
s
.
openMap
(
"data"
);
m
.
put
(
1
,
"1"
);
s
.
commit
();
s
.
close
();
s
=
new
MVStore
.
Builder
().
autoCommitDisabled
().
fileName
(
fileName
).
open
();
s
.
setWriteDelay
(
0
);
m
=
s
.
openMap
(
"data"
);
assertEquals
(
1
,
m
.
size
());
s
.
close
();
...
...
@@ -371,10 +391,10 @@ public class TestMVStore extends TestBase {
s
=
new
MVStore
.
Builder
().
fileName
(
fileName
).
open
();
s
.
set
Write
Delay
(
1
);
s
.
set
AutoCommit
Delay
(
1
);
m
=
s
.
openMap
(
"data"
);
m
.
put
(
1
,
"Hello"
);
s
.
store
();
s
.
commit
();
long
v
=
s
.
getCurrentVersion
();
m
.
put
(
2
,
"World."
);
Thread
.
sleep
(
5
);
...
...
@@ -383,12 +403,11 @@ public class TestMVStore extends TestBase {
s
=
new
MVStore
.
Builder
().
fileName
(
fileName
).
open
();
s
.
set
Write
Delay
(
1
);
s
.
set
AutoCommit
Delay
(
1
);
m
=
s
.
openMap
(
"data"
);
assertEquals
(
"World."
,
m
.
get
(
2
));
m
.
put
(
2
,
"World"
);
s
.
commit
();
s
.
store
();
v
=
s
.
getCurrentVersion
();
m
.
put
(
3
,
"!"
);
...
...
@@ -433,7 +452,6 @@ public class TestMVStore extends TestBase {
m
=
s
.
openMap
(
"test"
);
m
.
put
(
1
,
"Hello"
);
assertEquals
(
"Hello"
,
m
.
get
(
1
));
s
.
store
();
s
.
close
();
passwordChars
=
"008"
.
toCharArray
();
...
...
@@ -485,7 +503,6 @@ public class TestMVStore extends TestBase {
int
format
=
Integer
.
parseInt
(
header
.
get
(
"format"
));
assertEquals
(
1
,
format
);
header
.
put
(
"format"
,
Integer
.
toString
(
format
+
1
));
s
.
store
();
s
.
close
();
try
{
openStore
(
fileName
).
close
();
...
...
@@ -503,9 +520,8 @@ public class TestMVStore extends TestBase {
MVStore
s
=
openStore
(
fileName
);
MVMap
<
Integer
,
Integer
>
m
=
s
.
openMap
(
"test"
);
m
.
put
(
1
,
1
);
s
.
store
();
s
.
commit
();
s
.
removeMap
(
m
);
s
.
store
();
s
.
close
();
s
=
openStore
(
fileName
);
m
=
s
.
openMap
(
"test"
);
...
...
@@ -548,17 +564,16 @@ public class TestMVStore extends TestBase {
MVMap
<
Integer
,
String
>
map
;
s
=
new
MVStore
.
Builder
().
fileName
(
fileName
).
writeDelay
(-
1
).
autoCommitDisabled
(
).
compressData
().
open
();
map
=
s
.
openMap
(
"test"
);
// add 10 MB of data
for
(
int
i
=
0
;
i
<
1024
;
i
++)
{
map
.
put
(
i
,
new
String
(
new
char
[
10240
]));
}
s
.
store
();
s
.
close
();
int
[]
expectedReadsForCacheSize
=
{
34
05
,
2590
,
1924
,
1440
,
1108
,
956
,
918
34
13
,
2590
,
1924
,
1440
,
1112
,
956
,
918
};
for
(
int
cacheSize
=
0
;
cacheSize
<=
6
;
cacheSize
+=
4
)
{
s
=
new
MVStore
.
Builder
().
...
...
@@ -613,7 +628,6 @@ public class TestMVStore extends TestBase {
s
.
getStoreHeader
().
put
(
"test"
,
"123"
);
MVMap
<
Integer
,
Integer
>
map
=
s
.
openMap
(
"test"
);
map
.
put
(
10
,
100
);
s
.
store
();
s
.
close
();
s
=
openStore
(
fileName
);
assertEquals
(
"123"
,
s
.
getStoreHeader
().
get
(
"test"
));
...
...
@@ -630,14 +644,13 @@ public class TestMVStore extends TestBase {
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
map
=
s
.
openMap
(
"test"
+
i
);
map
.
put
(
0
,
new
byte
[
1000
]);
s
.
store
();
s
.
commit
();
}
FileStore
fs
=
s
.
getFileStore
();
long
size
=
fs
.
getFile
().
size
();
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
map
=
s
.
openMap
(
"test"
+
i
);
s
.
removeMap
(
map
);
s
.
store
();
s
.
commit
();
s
.
compact
(
100
);
if
(
fs
.
getFile
().
size
()
<=
size
)
{
...
...
@@ -818,14 +831,13 @@ public class TestMVStore extends TestBase {
assertEquals
(
0
,
s
.
getCurrentVersion
());
assertEquals
(
0
,
s
.
getStoreVersion
());
s
.
setStoreVersion
(
0
);
s
.
store
();
s
.
commit
();
s
.
setStoreVersion
(
1
);
s
.
closeImmediately
();
s
=
MVStore
.
open
(
fileName
);
assertEquals
(
1
,
s
.
getCurrentVersion
());
assertEquals
(
0
,
s
.
getStoreVersion
());
s
.
setStoreVersion
(
1
);
s
.
store
();
s
.
close
();
s
=
MVStore
.
open
(
fileName
);
assertEquals
(
2
,
s
.
getCurrentVersion
());
...
...
@@ -866,7 +878,6 @@ public class TestMVStore extends TestBase {
map
.
put
(
1
,
"Hello"
);
map
.
put
(
"2"
,
200
);
map
.
put
(
new
Object
[
1
],
new
Object
[]{
1
,
"2"
});
s
.
store
();
s
.
close
();
s
=
new
MVStore
.
Builder
().
fileName
(
fileName
).
open
();
...
...
@@ -958,7 +969,7 @@ public class TestMVStore extends TestBase {
for
(
int
i
=
0
;
i
<
3
;
i
++)
{
Integer
x
=
m
.
get
(
"value"
);
m
.
put
(
"value"
,
x
==
null
?
0
:
x
+
1
);
s
.
store
();
s
.
commit
();
}
s
.
close
();
}
...
...
@@ -972,7 +983,7 @@ public class TestMVStore extends TestBase {
for
(
int
op
=
0
;
op
<=
1
;
op
++)
{
for
(
int
i
=
0
;
i
<
5
;
i
++)
{
s
=
openStore
(
null
);
s
.
set
RetainVersion
(
0
);
s
.
set
VersionsToKeep
(
Integer
.
MAX_VALUE
);
MVMap
<
String
,
String
>
m
;
m
=
s
.
openMap
(
"data"
);
for
(
int
j
=
0
;
j
<
5
;
j
++)
{
...
...
@@ -1021,7 +1032,7 @@ public class TestMVStore extends TestBase {
assertEquals
(
"World"
,
mOld
.
get
(
"2"
));
assertTrue
(
mOld
.
isReadOnly
());
s
.
getCurrentVersion
();
long
old3
=
s
.
store
();
long
old3
=
s
.
commit
();
// the old version is still available
assertEquals
(
"Hello"
,
mOld
.
get
(
"1"
));
...
...
@@ -1033,7 +1044,6 @@ public class TestMVStore extends TestBase {
m
.
put
(
"1"
,
"Hi"
);
assertEquals
(
"Welt"
,
m
.
remove
(
"2"
));
s
.
store
();
s
.
close
();
s
=
openStore
(
fileName
);
...
...
@@ -1064,14 +1074,12 @@ public class TestMVStore extends TestBase {
for
(
int
i
=
0
;
i
<
1000
;
i
++)
{
m
.
put
(
i
,
"Hello World"
);
}
s
.
store
();
s
.
close
();
long
len
=
FileUtils
.
size
(
fileName
);
s
=
openStore
(
fileName
);
s
.
setRetentionTime
(
0
);
m
=
s
.
openMap
(
"data"
);
m
.
clear
();
s
.
store
();
s
.
compact
(
100
);
s
.
close
();
long
len2
=
FileUtils
.
size
(
fileName
);
...
...
@@ -1091,7 +1099,7 @@ public class TestMVStore extends TestBase {
}
assertEquals
(
1000
,
m
.
size
());
assertEquals
(
285
,
s
.
getUnsavedPageCount
());
s
.
store
();
s
.
commit
();
assertEquals
(
2
,
s
.
getFileStore
().
getWriteCount
());
s
.
close
();
...
...
@@ -1099,13 +1107,27 @@ public class TestMVStore extends TestBase {
m
=
s
.
openMap
(
"data"
);
m
.
clear
();
assertEquals
(
0
,
m
.
size
());
s
.
store
();
s
.
commit
();
// ensure only nodes are read, but not leaves
assertEquals
(
42
,
s
.
getFileStore
().
getReadCount
());
assertEquals
(
1
,
s
.
getFileStore
().
getWriteCount
());
s
.
close
();
}
private
void
testRollback
()
{
MVStore
s
=
MVStore
.
open
(
null
);
MVMap
<
Integer
,
Integer
>
m
=
s
.
openMap
(
"m"
);
m
.
put
(
1
,
-
1
);
s
.
commit
();
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
m
.
put
(
1
,
i
);
s
.
rollback
();
assertEquals
(
i
-
1
,
m
.
get
(
1
).
intValue
());
m
.
put
(
1
,
i
);
s
.
commit
();
}
}
private
void
testRollbackStored
()
{
String
fileName
=
getBaseDir
()
+
"/testRollback.h3"
;
FileUtils
.
delete
(
fileName
);
...
...
@@ -1129,7 +1151,7 @@ public class TestMVStore extends TestBase {
// so a new version is created
m
.
put
(
"1"
,
"Hello"
);
long
v2
=
s
.
store
();
long
v2
=
s
.
commit
();
assertEquals
(
2
,
v2
);
assertEquals
(
2
,
s
.
getCurrentVersion
());
assertFalse
(
s
.
hasUnsavedChanges
());
...
...
@@ -1155,7 +1177,7 @@ public class TestMVStore extends TestBase {
assertNull
(
meta
.
get
(
"name.data1"
));
assertNull
(
m0
.
get
(
"1"
));
assertEquals
(
"Hello"
,
m
.
get
(
"1"
));
assertEquals
(
2
,
s
.
store
());
assertEquals
(
2
,
s
.
commit
());
s
.
close
();
s
=
openStore
(
fileName
);
...
...
@@ -1179,7 +1201,6 @@ public class TestMVStore extends TestBase {
assertEquals
(
3
,
s
.
getCurrentVersion
());
m
=
s
.
openMap
(
"data"
);
m
.
put
(
"1"
,
"Hi"
);
s
.
store
();
s
.
close
();
s
=
openStore
(
fileName
);
...
...
@@ -1243,7 +1264,7 @@ public class TestMVStore extends TestBase {
MVMap
<
String
,
String
>
data
=
s
.
openMap
(
"data"
);
data
.
put
(
"1"
,
"Hello"
);
data
.
put
(
"2"
,
"World"
);
s
.
store
();
s
.
commit
();
assertEquals
(
1
,
s
.
getCurrentVersion
());
assertTrue
(
m
.
containsKey
(
"chunk.1"
));
assertFalse
(
m
.
containsKey
(
"chunk.2"
));
...
...
@@ -1252,7 +1273,7 @@ public class TestMVStore extends TestBase {
assertEquals
(
"name:data"
,
m
.
get
(
"map."
+
id
));
assertTrue
(
m
.
containsKey
(
"chunk.1"
));
assertEquals
(
"Hello"
,
data
.
put
(
"1"
,
"Hallo"
));
s
.
store
();
s
.
commit
();
assertEquals
(
"name:data"
,
m
.
get
(
"map."
+
id
));
assertTrue
(
m
.
get
(
"root.1"
).
length
()
>
0
);
assertTrue
(
m
.
containsKey
(
"chunk.1"
));
...
...
@@ -1324,10 +1345,9 @@ public class TestMVStore extends TestBase {
m
.
put
(
i
,
o
);
i
++;
if
(
i
%
10000
==
0
)
{
s
.
store
();
s
.
commit
();
}
}
s
.
store
();
s
.
close
();
// System.out.println(prof.getTop(5));
// System.out.println("store time " + (System.currentTimeMillis() - t));
...
...
@@ -1356,7 +1376,7 @@ public class TestMVStore extends TestBase {
// p = new Profiler();
//p.startCollecting();
// t = System.currentTimeMillis();
s
.
store
();
s
.
commit
();
// System.out.println("store: " + (System.currentTimeMillis() - t));
// System.out.println(p.getTop(5));
assertEquals
(
"hello 0"
,
m
.
remove
(
0
));
...
...
@@ -1364,7 +1384,6 @@ public class TestMVStore extends TestBase {
for
(
int
i
=
1
;
i
<
count
;
i
++)
{
assertEquals
(
"hello "
+
i
,
m
.
get
(
i
));
}
s
.
store
();
s
.
close
();
s
=
openStore
(
fileName
);
...
...
@@ -1376,7 +1395,7 @@ public class TestMVStore extends TestBase {
for
(
int
i
=
1
;
i
<
count
;
i
++)
{
m
.
remove
(
i
);
}
s
.
store
();
s
.
commit
();
assertNull
(
m
.
get
(
0
));
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
assertNull
(
m
.
get
(
i
));
...
...
@@ -1394,7 +1413,7 @@ public class TestMVStore extends TestBase {
for
(
int
i
=
j
*
factor
;
i
<
10
*
factor
;
i
++)
{
m
.
put
(
i
,
"Hello"
+
j
);
}
s
.
store
();
s
.
commit
();
}
s
.
close
();
...
...
@@ -1450,7 +1469,6 @@ public class TestMVStore extends TestBase {
for
(
int
i
=
0
;
i
<
100
;
i
++)
{
m
.
put
(
j
+
i
,
"Hello "
+
j
);
}
s
.
store
();
s
.
compact
(
80
);
s
.
close
();
long
len
=
FileUtils
.
size
(
fileName
);
...
...
@@ -1468,7 +1486,6 @@ public class TestMVStore extends TestBase {
for
(
int
i
=
0
;
i
<
100
;
i
++)
{
m
.
remove
(
i
);
}
s
.
store
();
s
.
compact
(
80
);
s
.
close
();
// len = FileUtils.size(fileName);
...
...
@@ -1492,12 +1509,11 @@ public class TestMVStore extends TestBase {
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
m
.
put
(
i
,
"Hello"
);
}
s
.
store
();
s
.
commit
();
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
assertEquals
(
"Hello"
,
m
.
get
(
i
));
assertEquals
(
"Hello"
,
m
.
remove
(
i
));
}
s
.
store
();
s
.
close
();
long
len
=
FileUtils
.
size
(
fileName
);
if
(
initialLength
==
0
)
{
...
...
@@ -1584,7 +1600,6 @@ public class TestMVStore extends TestBase {
si
.
put
(
"Test"
,
10
);
MVMap
<
String
,
String
>
ss
=
s
.
openMap
(
"stringString"
);
ss
.
put
(
"Hello"
,
"World"
);
s
.
store
();
s
.
close
();
s
=
openStore
(
fileName
);
is
=
s
.
openMap
(
"intString"
);
...
...
@@ -1608,7 +1623,7 @@ public class TestMVStore extends TestBase {
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
m
.
put
(
i
,
"hello "
+
i
);
}
s
.
store
();
s
.
commit
();
it
=
m
.
keyIterator
(
null
);
it
.
next
();
assertThrows
(
UnsupportedOperationException
.
class
,
it
).
remove
();
...
...
@@ -1639,7 +1654,6 @@ public class TestMVStore extends TestBase {
for
(
int
i
=
0
;
i
<
3
;
i
++)
{
m
.
put
(
i
,
"hello "
+
i
);
}
s
.
store
();
// closing twice should be fine
s
.
close
();
s
.
close
();
...
...
@@ -1653,14 +1667,13 @@ public class TestMVStore extends TestBase {
for
(
int
i
=
0
;
i
<
3
;
i
++)
{
m
.
put
(
i
,
"hello "
+
i
);
}
s
.
store
();
s
.
commit
();
assertEquals
(
"hello 0"
,
m
.
remove
(
0
));
assertNull
(
m
.
get
(
0
));
for
(
int
i
=
1
;
i
<
3
;
i
++)
{
assertEquals
(
"hello "
+
i
,
m
.
get
(
i
));
}
s
.
store
();
s
.
close
();
s
=
openStore
(
fileName
);
...
...
@@ -1686,8 +1699,7 @@ public class TestMVStore extends TestBase {
for
(
int
i
=
0
;;
i
++)
{
map
.
put
(
i
,
data
);
if
(
i
%
10000
==
0
)
{
long
version
=
store
.
commit
();
store
.
setRetainVersion
(
version
);
store
.
commit
();
long
time
=
System
.
currentTimeMillis
();
if
(
time
-
last
>
2000
)
{
long
mb
=
store
.
getFileStore
().
size
()
/
1024
/
1024
;
...
...
h2/src/test/org/h2/test/store/TestRandomMapOps.java
浏览文件 @
5f5eb72d
...
...
@@ -92,7 +92,7 @@ public class TestRandomMapOps extends TestBase {
for
(;
op
<
size
;
op
++)
{
int
k
=
r
.
nextInt
(
100
);
byte
[]
v
=
new
byte
[
r
.
nextInt
(
10
)
*
10
];
int
type
=
r
.
nextInt
(
1
3
);
int
type
=
r
.
nextInt
(
1
2
);
switch
(
type
)
{
case
0
:
case
1
:
...
...
@@ -109,23 +109,19 @@ public class TestRandomMapOps extends TestBase {
map
.
remove
(
k
);
break
;
case
6
:
log
(
op
,
k
,
v
,
"s.store()"
);
s
.
store
();
break
;
case
7
:
log
(
op
,
k
,
v
,
"s.compact(90)"
);
s
.
compact
(
90
);
break
;
case
8
:
case
7
:
log
(
op
,
k
,
v
,
"m.clear()"
);
m
.
clear
();
map
.
clear
();
break
;
case
9
:
case
8
:
log
(
op
,
k
,
v
,
"s.commit()"
);
s
.
commit
();
break
;
case
10
:
case
9
:
log
(
op
,
k
,
v
,
"s.commit()"
);
s
.
commit
();
log
(
op
,
k
,
v
,
"s.close()"
);
...
...
@@ -135,13 +131,13 @@ public class TestRandomMapOps extends TestBase {
log
(
op
,
k
,
v
,
"m = s.openMap(\"data\")"
);
m
=
s
.
openMap
(
"data"
);
break
;
case
1
1
:
case
1
0
:
log
(
op
,
k
,
v
,
"s.commit()"
);
s
.
commit
();
log
(
op
,
k
,
v
,
"s.compactMoveChunks()"
);
s
.
compactMoveChunks
();
break
;
case
1
2
:
case
1
1
:
log
(
op
,
k
,
v
,
"m.getKeyIndex({0})"
);
ArrayList
<
Integer
>
keyList
=
new
ArrayList
<
Integer
>(
map
.
keySet
());
int
index
=
Collections
.
binarySearch
(
keyList
,
k
,
null
);
...
...
@@ -165,13 +161,12 @@ public class TestRandomMapOps extends TestBase {
assertEquals
(
map
.
lastKey
(),
m
.
lastKey
());
}
}
s
.
store
();
s
.
close
();
}
private
static
MVStore
openStore
(
String
fileName
)
{
MVStore
s
=
new
MVStore
.
Builder
().
fileName
(
fileName
).
pageSplitSize
(
50
).
writeDelay
(
0
).
open
();
pageSplitSize
(
50
).
autoCommitDisabled
(
).
open
();
s
.
setRetentionTime
(
0
);
return
s
;
}
...
...
h2/src/test/org/h2/test/store/TestStreamStore.java
浏览文件 @
5f5eb72d
...
...
@@ -65,7 +65,7 @@ public class TestStreamStore extends TestBase {
for
(
int
i
=
0
;
i
<
100
;
i
++)
{
streamStore
.
put
(
new
RandomStream
(
size
,
i
));
}
s
.
store
();
s
.
commit
();
MVMap
<
Long
,
byte
[]>
map
=
s
.
openMap
(
"data"
);
assertTrue
(
"size: "
+
map
.
size
(),
map
.
sizeAsLong
()
>=
100
);
s
.
close
();
...
...
@@ -77,7 +77,7 @@ public class TestStreamStore extends TestBase {
for
(
int
i
=
0
;
i
<
100
;
i
++)
{
streamStore
.
put
(
new
RandomStream
(
size
,
-
i
));
}
s
.
store
();
s
.
commit
();
long
readCount
=
s
.
getFileStore
().
getReadCount
();
// the read count should be low because new blocks
// are appended at the end (not between existing blocks)
...
...
@@ -92,7 +92,7 @@ public class TestStreamStore extends TestBase {
return
new
StreamStore
(
map
)
{
@Override
protected
void
onStore
(
int
len
)
{
if
(
s
.
getUnsavedPageCount
()
>
s
.
get
UnsavedPageCountMax
()
/
2
)
{
if
(
s
.
getUnsavedPageCount
()
>
s
.
get
AutoCommitPageCount
()
/
2
)
{
s
.
commit
();
}
}
...
...
@@ -111,12 +111,11 @@ public class TestStreamStore extends TestBase {
@Override
protected
void
onStore
(
int
len
)
{
count
.
incrementAndGet
();
s
.
store
();
s
.
commit
();
}
};
long
size
=
1
*
1024
*
1024
;
streamStore
.
put
(
new
RandomStream
(
size
,
0
));
s
.
store
();
s
.
close
();
assertEquals
(
4
,
count
.
get
());
}
...
...
h2/src/test/org/h2/test/store/TestTransactionStore.java
浏览文件 @
5f5eb72d
...
...
@@ -86,7 +86,7 @@ public class TestTransactionStore extends TestBase {
for
(
int
i
=
0
;
!
stop
;
i
++)
{
state
.
set
(
i
);
other
.
put
(
i
,
value
);
store
.
store
();
store
.
commit
();
}
}
};
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论