Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
900b5667
提交
900b5667
authored
11月 06, 2013
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
MVStore: simpler API
上级
e845504a
显示空白字符变更
内嵌
并排
正在显示
11 个修改的文件
包含
179 行增加
和
196 行删除
+179
-196
changelog.html
h2/src/docsrc/html/changelog.html
+1
-0
MVStore.java
h2/src/main/org/h2/mvstore/MVStore.java
+110
-140
OffHeapStore.java
h2/src/main/org/h2/mvstore/OffHeapStore.java
+1
-2
MVTableEngine.java
h2/src/main/org/h2/mvstore/db/MVTableEngine.java
+2
-2
TransactionStore.java
h2/src/main/org/h2/mvstore/db/TransactionStore.java
+7
-6
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+3
-3
TestConcurrent.java
h2/src/test/org/h2/test/store/TestConcurrent.java
+9
-8
TestMVStore.java
h2/src/test/org/h2/test/store/TestMVStore.java
+28
-28
TestMVStoreBenchmark.java
h2/src/test/org/h2/test/store/TestMVStoreBenchmark.java
+6
-2
TestMVTableEngine.java
h2/src/test/org/h2/test/store/TestMVTableEngine.java
+1
-1
TestTransactionStore.java
h2/src/test/org/h2/test/store/TestTransactionStore.java
+11
-4
没有找到文件。
h2/src/docsrc/html/changelog.html
浏览文件 @
900b5667
...
@@ -23,6 +23,7 @@ Change Log
...
@@ -23,6 +23,7 @@ Change Log
</li><li>
Issue 73: MySQL compatibility: support REPLACE, patch by Cemo Koc.
</li><li>
Issue 73: MySQL compatibility: support REPLACE, patch by Cemo Koc.
</li><li>
The spatial index now works in MVCC mode when using the MVStore storage.
</li><li>
The spatial index now works in MVCC mode when using the MVStore storage.
</li><li>
MVStore: concurrency problems have been fixed.
</li><li>
MVStore: concurrency problems have been fixed.
The API has been simplified.
</li><li>
Improve error message when dropping an index that belongs to a constraint,
</li><li>
Improve error message when dropping an index that belongs to a constraint,
specify constraint in error message.
specify constraint in error message.
</li><li>
Issue 518: java.sql.Connection.commit() freezes after LOB modification with EXCLUSIVE connection
</li><li>
Issue 518: java.sql.Connection.commit() freezes after LOB modification with EXCLUSIVE connection
...
...
h2/src/main/org/h2/mvstore/MVStore.java
浏览文件 @
900b5667
...
@@ -59,7 +59,7 @@ TransactionStore:
...
@@ -59,7 +59,7 @@ TransactionStore:
MVStore:
MVStore:
- automated 'kill process' and 'power failure' test
- automated 'kill process' and 'power failure' test
- update checkstyle
- update checkstyle
- auto-compact from time to time and on close
-
feature to
auto-compact from time to time and on close
- test and possibly improve compact operation (for large dbs)
- test and possibly improve compact operation (for large dbs)
- possibly split chunk metadata into immutable and mutable
- possibly split chunk metadata into immutable and mutable
- compact: avoid processing pages using a counting bloom filter
- compact: avoid processing pages using a counting bloom filter
...
@@ -115,6 +115,19 @@ MVStore:
...
@@ -115,6 +115,19 @@ MVStore:
- support log structured merge style operations (blind writes)
- support log structured merge style operations (blind writes)
using one map per level plus bloom filter
using one map per level plus bloom filter
- have a strict call order MVStore -> MVMap -> Page -> FileStore
- have a strict call order MVStore -> MVMap -> Page -> FileStore
- autocommit mode (default) and manual mode
- manual mode: combine commit and store;
rollback only to chunk
- rename writeDelay to commitDelay, default 1 s
- rollback() to rollback to the latest commit; throws exception
in autocommit mode
- fix documentation (including examples)
- autocommit commits, stores, and compacts from time to time;
the background thread should wait at least 90% of the
configured write delay to store changes
- currently, uncommitted changes are stored if there are many transient changes,
and rolled back when opening - is this really needed?
- compact* should also store uncommitted changes (if there are any)
*/
*/
...
@@ -141,6 +154,7 @@ public class MVStore {
...
@@ -141,6 +154,7 @@ public class MVStore {
* The background thread, if any.
* The background thread, if any.
*/
*/
volatile
Thread
backgroundThread
;
volatile
Thread
backgroundThread
;
final
Object
backgroundThreadSync
=
new
Object
();
private
volatile
boolean
reuseSpace
=
true
;
private
volatile
boolean
reuseSpace
=
true
;
...
@@ -176,9 +190,9 @@ public class MVStore {
...
@@ -176,9 +190,9 @@ public class MVStore {
new
ConcurrentHashMap
<
Long
,
HashMap
<
Integer
,
Chunk
>>();
new
ConcurrentHashMap
<
Long
,
HashMap
<
Integer
,
Chunk
>>();
/**
/**
* The metadata map.
* The metadata map.
Write access to this map needs to be synchronized on the store.
*/
*/
private
MVMap
Concurrent
<
String
,
String
>
meta
;
private
MVMap
<
String
,
String
>
meta
;
private
final
ConcurrentHashMap
<
Integer
,
MVMap
<?,
?>>
maps
=
private
final
ConcurrentHashMap
<
Integer
,
MVMap
<?,
?>>
maps
=
new
ConcurrentHashMap
<
Integer
,
MVMap
<?,
?>>();
new
ConcurrentHashMap
<
Integer
,
MVMap
<?,
?>>();
...
@@ -208,6 +222,12 @@ public class MVStore {
...
@@ -208,6 +222,12 @@ public class MVStore {
*/
*/
private
long
lastStoredVersion
;
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)
*/
private
int
unsavedPageCount
;
private
int
unsavedPageCount
;
private
int
unsavedPageCountMax
;
private
int
unsavedPageCountMax
;
private
boolean
storeNeeded
;
private
boolean
storeNeeded
;
...
@@ -220,11 +240,6 @@ public class MVStore {
...
@@ -220,11 +240,6 @@ public class MVStore {
private
long
lastStoreTime
;
private
long
lastStoreTime
;
/**
* To which version to roll back when opening the store after a crash.
*/
private
long
lastCommittedVersion
;
/**
/**
* The earliest chunk to retain, if any.
* The earliest chunk to retain, if any.
*/
*/
...
@@ -235,6 +250,8 @@ public class MVStore {
...
@@ -235,6 +250,8 @@ public class MVStore {
*/
*/
private
volatile
long
currentStoreVersion
=
-
1
;
private
volatile
long
currentStoreVersion
=
-
1
;
private
Thread
currentStoreThread
;
private
volatile
boolean
metaChanged
;
private
volatile
boolean
metaChanged
;
/**
/**
...
@@ -256,7 +273,7 @@ public class MVStore {
...
@@ -256,7 +273,7 @@ public class MVStore {
pageSplitSize
=
o
==
null
?
6
*
1024
:
(
Integer
)
o
;
pageSplitSize
=
o
==
null
?
6
*
1024
:
(
Integer
)
o
;
o
=
config
.
get
(
"backgroundExceptionHandler"
);
o
=
config
.
get
(
"backgroundExceptionHandler"
);
this
.
backgroundExceptionHandler
=
(
UncaughtExceptionHandler
)
o
;
this
.
backgroundExceptionHandler
=
(
UncaughtExceptionHandler
)
o
;
meta
=
new
MVMap
Concurrent
<
String
,
String
>(
StringDataType
.
INSTANCE
,
StringDataType
.
INSTANCE
);
meta
=
new
MVMap
<
String
,
String
>(
StringDataType
.
INSTANCE
,
StringDataType
.
INSTANCE
);
HashMap
<
String
,
String
>
c
=
New
.
hashMap
();
HashMap
<
String
,
String
>
c
=
New
.
hashMap
();
c
.
put
(
"id"
,
"0"
);
c
.
put
(
"id"
,
"0"
);
c
.
put
(
"createVersion"
,
Long
.
toString
(
currentVersion
));
c
.
put
(
"createVersion"
,
Long
.
toString
(
currentVersion
));
...
@@ -320,10 +337,6 @@ public class MVStore {
...
@@ -320,10 +337,6 @@ public class MVStore {
readMeta
();
readMeta
();
}
}
}
}
long
rollback
=
DataUtils
.
parseLong
(
meta
.
get
(
"rollbackOnOpen"
),
-
1
);
if
(
rollback
!=
-
1
)
{
rollbackTo
(
rollback
);
}
}
catch
(
IllegalStateException
e
)
{
}
catch
(
IllegalStateException
e
)
{
try
{
try
{
closeStore
(
false
);
closeStore
(
false
);
...
@@ -337,7 +350,6 @@ public class MVStore {
...
@@ -337,7 +350,6 @@ public class MVStore {
}
}
}
}
lastStoreTime
=
getTime
();
lastStoreTime
=
getTime
();
this
.
lastCommittedVersion
=
currentVersion
;
// setWriteDelay starts the thread, but only if
// setWriteDelay starts the thread, but only if
// the parameter is different than the current value
// the parameter is different than the current value
...
@@ -403,7 +415,7 @@ public class MVStore {
...
@@ -403,7 +415,7 @@ public class MVStore {
* @param builder the map builder
* @param builder the map builder
* @return the map
* @return the map
*/
*/
public
<
M
extends
MVMap
<
K
,
V
>,
K
,
V
>
M
openMap
(
String
name
,
MVMap
.
MapBuilder
<
M
,
K
,
V
>
builder
)
{
public
synchronized
<
M
extends
MVMap
<
K
,
V
>,
K
,
V
>
M
openMap
(
String
name
,
MVMap
.
MapBuilder
<
M
,
K
,
V
>
builder
)
{
checkOpen
();
checkOpen
();
String
x
=
meta
.
get
(
"name."
+
name
);
String
x
=
meta
.
get
(
"name."
+
name
);
int
id
;
int
id
;
...
@@ -445,17 +457,17 @@ public class MVStore {
...
@@ -445,17 +457,17 @@ public class MVStore {
* Get the metadata map. This data is for informational purposes only. The
* Get the metadata map. This data is for informational purposes only. The
* data is subject to change in future versions.
* data is subject to change in future versions.
* <p>
* <p>
* The data
should not be modified (doing so may corrupt the store). Writing
* The data
in this map should not be modified (changing system data may
*
to it is not always detected as a modification, so that changes to it
*
corrupt the store). If modifications are needed, they need be
*
might not be stored
.
*
synchronized on the store
.
* <p>
* <p>
* It contains the following entries:
* The metadata map contains the following entries:
*
* <pre>
* <pre>
* chunk.{chunkId} = {chunk metadata}
* name.{name} = {mapId}
* name.{name} = {mapId}
* map.{mapId} = {map metadata}
* map.{mapId} = {map metadata}
* root.{mapId} = {root position}
* root.{mapId} = {root position}
*
chunk.{chunkId} = {chunk metadata
}
*
setting.storeVersion = {version
}
* </pre>
* </pre>
*
*
* @return the metadata map
* @return the metadata map
...
@@ -636,9 +648,8 @@ public class MVStore {
...
@@ -636,9 +648,8 @@ public class MVStore {
}
}
/**
/**
* Close the file and the store. If there are any committed but unsaved
* Close the file and the store. If there are any uncommitted changes, they
* changes, they are written to disk first. If any temporary data was
* are written to disk first. All open maps are closed.
* written but not committed, this is rolled back. All open maps are closed.
* <p>
* <p>
* It is not allowed to concurrently call close and store.
* It is not allowed to concurrently call close and store.
*/
*/
...
@@ -648,18 +659,8 @@ public class MVStore {
...
@@ -648,18 +659,8 @@ public class MVStore {
}
}
if
(
fileStore
!=
null
&&
!
fileStore
.
isReadOnly
())
{
if
(
fileStore
!=
null
&&
!
fileStore
.
isReadOnly
())
{
stopBackgroundThread
();
stopBackgroundThread
();
if
(
hasUnsavedChanges
())
{
if
(
currentStoreVersion
>=
0
)
{
store
();
// in this case, store is called manually in another thread
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_WRITING_FAILED
,
"Can not close while storing"
);
}
if
(
hasUnsavedChanges
()
||
lastCommittedVersion
!=
currentVersion
)
{
rollbackTo
(
lastCommittedVersion
);
metaChanged
=
true
;
store
(
false
);
}
}
}
}
closeStore
(
true
);
closeStore
(
true
);
...
@@ -739,17 +740,6 @@ public class MVStore {
...
@@ -739,17 +740,6 @@ public class MVStore {
return
c
;
return
c
;
}
}
/**
* Increment the current version, without committing the changes.
*
* @return the new version
*/
public
long
incrementVersion
()
{
long
v
=
++
currentVersion
;
setWriteVersion
(
v
);
return
v
;
}
private
void
setWriteVersion
(
long
version
)
{
private
void
setWriteVersion
(
long
version
)
{
for
(
MVMap
<?,
?>
map
:
maps
.
values
())
{
for
(
MVMap
<?,
?>
map
:
maps
.
values
())
{
map
.
setWriteVersion
(
version
);
map
.
setWriteVersion
(
version
);
...
@@ -768,11 +758,11 @@ public class MVStore {
...
@@ -768,11 +758,11 @@ public class MVStore {
* @return the new version
* @return the new version
*/
*/
public
long
commit
()
{
public
long
commit
()
{
long
v
=
incrementVersion
();
if
(
fileStore
!=
null
)
{
lastCommittedVersion
=
v
;
return
store
();
if
(
writeDelay
==
0
)
{
store
(
false
);
}
}
long
v
=
++
currentVersion
;
setWriteVersion
(
v
);
return
v
;
return
v
;
}
}
...
@@ -781,29 +771,17 @@ public class MVStore {
...
@@ -781,29 +771,17 @@ public class MVStore {
* there are no unsaved changes, otherwise it increments the current version
* there are no unsaved changes, otherwise it increments the current version
* and stores the data (for file based stores).
* and stores the data (for file based stores).
* <p>
* <p>
*
O
ne store operation may run at any time.
*
At most o
ne store operation may run at any time.
*
*
* @return the new version (incremented if there were changes)
* @return the new version (incremented if there were changes)
*/
*/
public
long
store
()
{
public
synchronized
long
store
()
{
checkOpen
();
return
store
(
false
);
}
/**
* Store changes. Changes that are marked as temporary are rolled back after
* a restart.
*
* @param temp whether the changes are only temporary (not committed), and
* should be rolled back after a crash
* @return the new version (incremented if there were changes)
*/
private
synchronized
long
store
(
boolean
temp
)
{
if
(
closed
)
{
if
(
closed
)
{
return
currentVersion
;
return
currentVersion
;
}
}
if
(
fileStore
==
null
)
{
if
(
fileStore
==
null
)
{
return
incrementVersion
();
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_WRITING_FAILED
,
"This is an in-memory store"
);
}
}
if
(
currentStoreVersion
>=
0
)
{
if
(
currentStoreVersion
>=
0
)
{
// store is possibly called within store, if the meta map changed
// store is possibly called within store, if the meta map changed
...
@@ -818,37 +796,24 @@ public class MVStore {
...
@@ -818,37 +796,24 @@ public class MVStore {
}
}
try
{
try
{
currentStoreVersion
=
currentVersion
;
currentStoreVersion
=
currentVersion
;
return
storeNow
(
temp
);
currentStoreThread
=
Thread
.
currentThread
();
return
storeNow
();
}
finally
{
}
finally
{
// in any case reset the current store version,
// in any case reset the current store version,
// to allow closing the store
// to allow closing the store
currentStoreVersion
=
-
1
;
currentStoreVersion
=
-
1
;
currentStoreThread
=
null
;
}
}
}
}
private
long
storeNow
(
boolean
temp
)
{
private
long
storeNow
()
{
int
currentUnsavedPageCount
=
unsavedPageCount
;
int
currentUnsavedPageCount
=
unsavedPageCount
;
long
storeVersion
=
currentStoreVersion
;
long
storeVersion
=
currentStoreVersion
;
long
version
=
++
currentVersion
;
long
version
=
++
currentVersion
;
setWriteVersion
(
version
);
long
time
=
getTime
();
long
time
=
getTime
();
lastStoreTime
=
time
;
lastStoreTime
=
time
;
if
(
temp
)
{
meta
.
put
(
"rollbackOnOpen"
,
Long
.
toString
(
lastCommittedVersion
));
// find the oldest chunk to retain
long
minVersion
=
Long
.
MAX_VALUE
;
Chunk
minChunk
=
null
;
for
(
Chunk
c
:
chunks
.
values
())
{
if
(
c
.
version
<
minVersion
)
{
minVersion
=
c
.
version
;
minChunk
=
c
;
}
}
retainChunk
=
minChunk
;
}
else
{
lastCommittedVersion
=
version
;
meta
.
remove
(
"rollbackOnOpen"
);
retainChunk
=
null
;
retainChunk
=
null
;
}
// the last chunk was not completely correct in the last store()
// the last chunk was not completely correct in the last store()
// this needs to be updated now (it's better not to update right after
// this needs to be updated now (it's better not to update right after
...
@@ -983,10 +948,9 @@ public class MVStore {
...
@@ -983,10 +948,9 @@ 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
)
{
metaChanged
=
false
;
metaChanged
=
false
;
lastStoredVersion
=
storeVersion
;
lastStoredVersion
=
storeVersion
;
}
return
version
;
return
version
;
}
}
...
@@ -1053,7 +1017,7 @@ public class MVStore {
...
@@ -1053,7 +1017,7 @@ public class MVStore {
if
(
v
>
storeVersion
)
{
if
(
v
>
storeVersion
)
{
continue
;
continue
;
}
}
Map
<
Integer
,
Chunk
>
freed
=
e
.
getValue
();
Hash
Map
<
Integer
,
Chunk
>
freed
=
e
.
getValue
();
for
(
Chunk
f
:
freed
.
values
())
{
for
(
Chunk
f
:
freed
.
values
())
{
Chunk
c
=
chunks
.
get
(
f
.
id
);
Chunk
c
=
chunks
.
get
(
f
.
id
);
if
(
c
==
null
)
{
if
(
c
==
null
)
{
...
@@ -1146,6 +1110,9 @@ public class MVStore {
...
@@ -1146,6 +1110,9 @@ public class MVStore {
* @return if there are any changes
* @return if there are any changes
*/
*/
public
boolean
hasUnsavedChanges
()
{
public
boolean
hasUnsavedChanges
()
{
;
// TODO maybe private; rename to hasUncommittedChanges
checkOpen
();
checkOpen
();
if
(
metaChanged
)
{
if
(
metaChanged
)
{
return
true
;
return
true
;
...
@@ -1281,7 +1248,7 @@ public class MVStore {
...
@@ -1281,7 +1248,7 @@ public class MVStore {
}
}
/**
/**
* Force all changes to be written to the storage. The default
* Force all
stored
changes to be written to the storage. The default
* implementation calls FileChannel.force(true).
* implementation calls FileChannel.force(true).
*/
*/
public
void
sync
()
{
public
void
sync
()
{
...
@@ -1484,12 +1451,14 @@ public class MVStore {
...
@@ -1484,12 +1451,14 @@ public class MVStore {
Chunk
c
=
getChunk
(
pos
);
Chunk
c
=
getChunk
(
pos
);
long
version
=
currentVersion
;
long
version
=
currentVersion
;
if
(
map
==
meta
&&
currentStoreVersion
>=
0
)
{
if
(
map
==
meta
&&
currentStoreVersion
>=
0
)
{
if
(
Thread
.
currentThread
()
==
currentStoreThread
)
{
// if the meta map is modified while storing,
// if the meta map is modified while storing,
// then this freed page needs to be registered
// then this freed page needs to be registered
// with the stored chunk, so that the old chunk
// with the stored chunk, so that the old chunk
// can be re-used
// can be re-used
version
=
currentStoreVersion
;
version
=
currentStoreVersion
;
}
}
}
registerFreePage
(
version
,
c
.
id
,
DataUtils
.
getPageMaxLength
(
pos
),
1
);
registerFreePage
(
version
,
c
.
id
,
DataUtils
.
getPageMaxLength
(
pos
),
1
);
}
}
...
@@ -1663,9 +1632,8 @@ public class MVStore {
...
@@ -1663,9 +1632,8 @@ public class MVStore {
}
}
/**
/**
* Get the maximum number of unsaved pages. If this number is exceeded,
* Get the maximum number of unsaved pages. If this number is exceeded, the
* the unsaved changes are stored to disk, including uncommitted changes.
* unsaved changes are stored to disk.
* Saved uncommitted changes are rolled back when opening the store.
*
*
* @return the number of maximum unsaved pages
* @return the number of maximum unsaved pages
*/
*/
...
@@ -1677,8 +1645,8 @@ public class MVStore {
...
@@ -1677,8 +1645,8 @@ public class MVStore {
* Increment the number of unsaved pages.
* Increment the number of unsaved pages.
*/
*/
void
registerUnsavedPage
()
{
void
registerUnsavedPage
()
{
unsavedPageCount
++
;
int
count
=
++
unsavedPageCount
;
if
(
unsavedPageC
ount
>
unsavedPageCountMax
&&
unsavedPageCountMax
>
0
)
{
if
(
c
ount
>
unsavedPageCountMax
&&
unsavedPageCountMax
>
0
)
{
storeNeeded
=
true
;
storeNeeded
=
true
;
}
}
}
}
...
@@ -1689,7 +1657,7 @@ public class MVStore {
...
@@ -1689,7 +1657,7 @@ public class MVStore {
void
beforeWrite
()
{
void
beforeWrite
()
{
if
(
storeNeeded
)
{
if
(
storeNeeded
)
{
storeNeeded
=
false
;
storeNeeded
=
false
;
store
(
true
);
store
();
}
}
}
}
...
@@ -1711,12 +1679,22 @@ public class MVStore {
...
@@ -1711,12 +1679,22 @@ public class MVStore {
*
*
* @param version the new store version
* @param version the new store version
*/
*/
public
void
setStoreVersion
(
int
version
)
{
public
synchronized
void
setStoreVersion
(
int
version
)
{
checkOpen
();
checkOpen
();
markMetaChanged
();
markMetaChanged
();
meta
.
put
(
"setting.storeVersion"
,
Integer
.
toString
(
version
));
meta
.
put
(
"setting.storeVersion"
,
Integer
.
toString
(
version
));
}
}
/**
* Revert to the beginning of the current version.
*/
public
void
rollback
()
{
;
// TODO document and test
rollbackTo
(
currentVersion
);
}
/**
/**
* Revert to the beginning of the given version. All later changes (stored
* Revert to the beginning of the given version. All later changes (stored
* or not) are forgotten. All maps that were created later are closed. A
* or not) are forgotten. All maps that were created later are closed. A
...
@@ -1741,7 +1719,6 @@ public class MVStore {
...
@@ -1741,7 +1719,6 @@ public class MVStore {
freedPageSpace
.
clear
();
freedPageSpace
.
clear
();
currentVersion
=
version
;
currentVersion
=
version
;
setWriteVersion
(
version
);
setWriteVersion
(
version
);
lastCommittedVersion
=
version
;
metaChanged
=
false
;
metaChanged
=
false
;
return
;
return
;
}
}
...
@@ -1816,12 +1793,10 @@ public class MVStore {
...
@@ -1816,12 +1793,10 @@ public class MVStore {
// rollback might have rolled back the stored chunk metadata as well
// rollback might have rolled back the stored chunk metadata as well
Chunk
c
=
chunks
.
get
(
lastChunkId
-
1
);
Chunk
c
=
chunks
.
get
(
lastChunkId
-
1
);
if
(
c
!=
null
)
{
if
(
c
!=
null
)
{
markMetaChanged
();
meta
.
put
(
"chunk."
+
c
.
id
,
c
.
asString
());
meta
.
put
(
"chunk."
+
c
.
id
,
c
.
asString
());
}
}
currentVersion
=
version
;
currentVersion
=
version
;
setWriteVersion
(
version
);
setWriteVersion
(
version
);
lastCommittedVersion
=
version
;
}
}
private
void
revertTemp
(
long
storeVersion
)
{
private
void
revertTemp
(
long
storeVersion
)
{
...
@@ -1847,15 +1822,6 @@ public class MVStore {
...
@@ -1847,15 +1822,6 @@ public class MVStore {
return
currentVersion
;
return
currentVersion
;
}
}
/**
* Get the last committed version.
*
* @return the version
*/
public
long
getCommittedVersion
()
{
return
lastCommittedVersion
;
}
/**
/**
* Get the file store.
* Get the file store.
*
*
...
@@ -1889,7 +1855,7 @@ public class MVStore {
...
@@ -1889,7 +1855,7 @@ public class MVStore {
* @param map the map
* @param map the map
* @param newName the new name
* @param newName the new name
*/
*/
public
void
renameMap
(
MVMap
<?,
?>
map
,
String
newName
)
{
public
synchronized
void
renameMap
(
MVMap
<?,
?>
map
,
String
newName
)
{
checkOpen
();
checkOpen
();
DataUtils
.
checkArgument
(
map
!=
meta
,
DataUtils
.
checkArgument
(
map
!=
meta
,
"Renaming the meta map is not allowed"
);
"Renaming the meta map is not allowed"
);
...
@@ -1912,7 +1878,7 @@ public class MVStore {
...
@@ -1912,7 +1878,7 @@ public class MVStore {
*
*
* @param map the map
* @param map the map
*/
*/
public
void
removeMap
(
MVMap
<?,
?>
map
)
{
public
synchronized
void
removeMap
(
MVMap
<?,
?>
map
)
{
checkOpen
();
checkOpen
();
DataUtils
.
checkArgument
(
map
!=
meta
,
DataUtils
.
checkArgument
(
map
!=
meta
,
"Removing the meta map is not allowed"
);
"Removing the meta map is not allowed"
);
...
@@ -1932,7 +1898,7 @@ public class MVStore {
...
@@ -1932,7 +1898,7 @@ public class MVStore {
* @param id the map id
* @param id the map id
* @return the name
* @return the name
*/
*/
String
getMapName
(
int
id
)
{
synchronized
String
getMapName
(
int
id
)
{
String
m
=
meta
.
get
(
"map."
+
id
);
String
m
=
meta
.
get
(
"map."
+
id
);
return
DataUtils
.
parseMap
(
m
).
get
(
"name"
);
return
DataUtils
.
parseMap
(
m
).
get
(
"name"
);
}
}
...
@@ -1941,14 +1907,13 @@ public class MVStore {
...
@@ -1941,14 +1907,13 @@ public class MVStore {
* Store all unsaved changes, if there are any that are committed.
* Store all unsaved changes, if there are any that are committed.
*/
*/
void
storeInBackground
()
{
void
storeInBackground
()
{
if
(
closed
||
unsavedPageCount
==
0
)
{
if
(
unsavedPageCount
==
0
||
closed
)
{
return
;
return
;
}
}
// could also store when there are many unsaved pages,
// could also store when there are many unsaved pages,
// but according to a test it doesn't really help
// but according to a test it doesn't really help
if
(
lastStoredVersion
>=
lastCommittedVersion
)
{
return
;
}
long
time
=
getTime
();
long
time
=
getTime
();
if
(
time
<=
lastStoreTime
+
writeDelay
)
{
if
(
time
<=
lastStoreTime
+
writeDelay
)
{
return
;
return
;
...
@@ -1957,7 +1922,7 @@ public class MVStore {
...
@@ -1957,7 +1922,7 @@ public class MVStore {
return
;
return
;
}
}
try
{
try
{
store
(
true
);
store
();
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
if
(
backgroundExceptionHandler
!=
null
)
{
if
(
backgroundExceptionHandler
!=
null
)
{
backgroundExceptionHandler
.
uncaughtException
(
null
,
e
);
backgroundExceptionHandler
.
uncaughtException
(
null
,
e
);
...
@@ -1981,13 +1946,13 @@ public class MVStore {
...
@@ -1981,13 +1946,13 @@ public class MVStore {
}
}
private
void
stopBackgroundThread
()
{
private
void
stopBackgroundThread
()
{
if
(
backgroundThread
==
null
)
{
Thread
t
=
backgroundThread
;
if
(
t
==
null
)
{
return
;
return
;
}
}
Thread
t
=
backgroundThread
;
backgroundThread
=
null
;
backgroundThread
=
null
;
synchronized
(
this
)
{
synchronized
(
backgroundThreadSync
)
{
notify
();
backgroundThreadSync
.
notifyAll
();
}
}
try
{
try
{
t
.
join
();
t
.
join
();
...
@@ -1997,13 +1962,12 @@ public class MVStore {
...
@@ -1997,13 +1962,12 @@ public class MVStore {
}
}
/**
/**
* Set the maximum delay in milliseconds to store committed changes (for
* Set the maximum delay in milliseconds to commit changes.
* file-based stores).
* <p>
* <p>
* The default is 1000, meaning c
ommitted changes are stor
ed after at
* The default is 1000, meaning c
hanges are committ
ed after at
* most one second.
* most one second.
* <p>
* <p>
* When the value is set to -1, c
ommitted c
hanges are only written when
* When the value is set to -1, changes are only written when
* calling the store method. When the value is set to 0, committed
* calling the store method. When the value is set to 0, committed
* changes are immediately written on a commit, but please note this
* changes are immediately written on a commit, but please note this
* decreases performance and does still not guarantee the disk will
* decreases performance and does still not guarantee the disk will
...
@@ -2012,6 +1976,8 @@ public class MVStore {
...
@@ -2012,6 +1976,8 @@ public class MVStore {
* @param millis the maximum delay
* @param millis the maximum delay
*/
*/
public
void
setWriteDelay
(
int
millis
)
{
public
void
setWriteDelay
(
int
millis
)
{
;
// TODO rename to commitDelay
if
(
writeDelay
==
millis
)
{
if
(
writeDelay
==
millis
)
{
return
;
return
;
}
}
...
@@ -2050,12 +2016,17 @@ public class MVStore {
...
@@ -2050,12 +2016,17 @@ public class MVStore {
@Override
@Override
public
void
run
()
{
public
void
run
()
{
while
(
store
.
backgroundThread
!=
null
)
{
while
(
true
)
{
synchronized
(
store
)
{
Thread
t
=
store
.
backgroundThread
;
if
(
t
==
null
)
{
break
;
}
Object
sync
=
store
.
backgroundThreadSync
;
synchronized
(
sync
)
{
try
{
try
{
s
tore
.
wait
(
sleep
);
s
ync
.
wait
(
sleep
);
}
catch
(
InterruptedException
e
)
{
}
catch
(
InterruptedException
e
)
{
// ignore
continue
;
}
}
}
}
store
.
storeInBackground
();
store
.
storeInBackground
();
...
@@ -2145,9 +2116,8 @@ public class MVStore {
...
@@ -2145,9 +2116,8 @@ public class MVStore {
/**
/**
* Set the size of the write buffer, in MB (for file-based stores).
* Set the size of the write buffer, in MB (for file-based stores).
* Changes are automatically stored if the buffer grows larger than
* Unless auto-commit is disabled, changes are automatically stored if
* this. However, unless the changes are committed later on, they are
* the buffer grows larger than this.
* rolled back when opening the store.
* <p>
* <p>
* The default is 4 MB.
* The default is 4 MB.
* <p>
* <p>
...
...
h2/src/main/org/h2/mvstore/OffHeapStore.java
浏览文件 @
900b5667
...
@@ -121,8 +121,7 @@ public class OffHeapStore extends FileStore {
...
@@ -121,8 +121,7 @@ public class OffHeapStore extends FileStore {
@Override
@Override
public
void
close
()
{
public
void
close
()
{
truncate
(
0
);
// do nothing (keep the data until it is garbage collected)
freeSpace
.
clear
();
}
}
@Override
@Override
...
...
h2/src/main/org/h2/mvstore/db/MVTableEngine.java
浏览文件 @
900b5667
...
@@ -260,7 +260,7 @@ public class MVTableEngine implements TableEngine {
...
@@ -260,7 +260,7 @@ public class MVTableEngine implements TableEngine {
public
void
compactFile
(
long
maxCompactTime
)
{
public
void
compactFile
(
long
maxCompactTime
)
{
store
.
setRetentionTime
(
0
);
store
.
setRetentionTime
(
0
);
long
start
=
System
.
currentTimeMillis
();
long
start
=
System
.
currentTimeMillis
();
while
(
store
.
compact
(
9
0
))
{
while
(
store
.
compact
(
9
9
))
{
store
.
sync
();
store
.
sync
();
long
time
=
System
.
currentTimeMillis
()
-
start
;
long
time
=
System
.
currentTimeMillis
()
-
start
;
if
(
time
>
maxCompactTime
)
{
if
(
time
>
maxCompactTime
)
{
...
@@ -280,7 +280,7 @@ public class MVTableEngine implements TableEngine {
...
@@ -280,7 +280,7 @@ public class MVTableEngine implements TableEngine {
public
void
close
(
long
maxCompactTime
)
{
public
void
close
(
long
maxCompactTime
)
{
if
(!
store
.
isClosed
()
&&
store
.
getFileStore
()
!=
null
)
{
if
(!
store
.
isClosed
()
&&
store
.
getFileStore
()
!=
null
)
{
if
(!
store
.
getFileStore
().
isReadOnly
())
{
if
(!
store
.
getFileStore
().
isReadOnly
())
{
store
.
stor
e
();
transactionStore
.
clos
e
();
long
start
=
System
.
currentTimeMillis
();
long
start
=
System
.
currentTimeMillis
();
while
(
store
.
compact
(
90
))
{
while
(
store
.
compact
(
90
))
{
long
time
=
System
.
currentTimeMillis
()
-
start
;
long
time
=
System
.
currentTimeMillis
()
-
start
;
...
...
h2/src/main/org/h2/mvstore/db/TransactionStore.java
浏览文件 @
900b5667
...
@@ -170,8 +170,10 @@ public class TransactionStore {
...
@@ -170,8 +170,10 @@ public class TransactionStore {
public
synchronized
void
close
()
{
public
synchronized
void
close
()
{
// to avoid losing transaction ids
// to avoid losing transaction ids
settings
.
put
(
LAST_TRANSACTION_ID
,
""
+
lastTransactionId
);
settings
.
put
(
LAST_TRANSACTION_ID
,
""
+
lastTransactionId
);
if
(
store
.
getFileStore
()
!=
null
)
{
store
.
store
();
store
.
store
();
}
}
}
/**
/**
* Begin a new transaction.
* Begin a new transaction.
...
@@ -191,7 +193,6 @@ public class TransactionStore {
...
@@ -191,7 +193,6 @@ public class TransactionStore {
private
void
commitIfNeeded
()
{
private
void
commitIfNeeded
()
{
if
(
store
.
getUnsavedPageCount
()
>
MAX_UNSAVED_PAGES
)
{
if
(
store
.
getUnsavedPageCount
()
>
MAX_UNSAVED_PAGES
)
{
if
(
store
.
getFileStore
()
!=
null
)
{
if
(
store
.
getFileStore
()
!=
null
)
{
store
.
commit
();
store
.
store
();
store
.
store
();
}
}
}
}
...
@@ -354,10 +355,10 @@ public class TransactionStore {
...
@@ -354,10 +355,10 @@ public class TransactionStore {
firstOpenTransaction
=
-
1
;
firstOpenTransaction
=
-
1
;
}
}
if
(
store
.
getWriteDelay
()
==
0
)
{
if
(
store
.
getWriteDelay
()
==
0
)
{
if
(
store
.
getFileStore
()
=
=
null
)
{
if
(
store
.
getFileStore
()
!
=
null
)
{
return
;
store
.
store
()
;
}
}
store
.
commit
()
;
return
;
}
}
// to avoid having to store the transaction log,
// to avoid having to store the transaction log,
// if there is no open transaction,
// if there is no open transaction,
...
@@ -1207,7 +1208,7 @@ public class TransactionStore {
...
@@ -1207,7 +1208,7 @@ public class TransactionStore {
*/
*/
public
Iterator
<
K
>
keyIterator
(
K
from
,
boolean
includeUncommitted
)
{
public
Iterator
<
K
>
keyIterator
(
K
from
,
boolean
includeUncommitted
)
{
Cursor
<
K
>
it
=
map
.
keyIterator
(
from
);
Cursor
<
K
>
it
=
map
.
keyIterator
(
from
);
return
wrapIterator
(
it
,
false
);
return
wrapIterator
(
it
,
includeUncommitted
);
}
}
/**
/**
...
...
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
900b5667
...
@@ -470,18 +470,18 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
...
@@ -470,18 +470,18 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
prof
.
interval
=
1
;
prof
.
interval
=
1
;
prof
.
startCollecting
();
prof
.
startCollecting
();
if
(
test
.
mvStore
)
{
if
(
test
.
mvStore
)
{
TestPerformance
.
main
(
"-init"
,
"-db"
,
"9"
,
"-size"
,
"1000
0
"
);
TestPerformance
.
main
(
"-init"
,
"-db"
,
"9"
,
"-size"
,
"1000"
);
}
else
{
}
else
{
TestPerformance
.
main
(
"-init"
,
"-db"
,
"1"
);
TestPerformance
.
main
(
"-init"
,
"-db"
,
"1"
);
}
}
prof
.
stopCollecting
();
prof
.
stopCollecting
();
System
.
out
.
println
(
prof
.
getTop
(
3
));
System
.
out
.
println
(
prof
.
getTop
(
3
0
));
if
(
test
.
mvStore
)
{
if
(
test
.
mvStore
)
{
prof
=
new
Profiler
();
prof
=
new
Profiler
();
prof
.
depth
=
16
;
prof
.
depth
=
16
;
prof
.
interval
=
1
;
prof
.
interval
=
1
;
prof
.
startCollecting
();
prof
.
startCollecting
();
TestPerformance
.
main
(
"-init"
,
"-db"
,
"1"
,
"-size"
,
"1000
0
"
);
TestPerformance
.
main
(
"-init"
,
"-db"
,
"1"
,
"-size"
,
"1000"
);
prof
.
stopCollecting
();
prof
.
stopCollecting
();
System
.
out
.
println
(
prof
.
getTop
(
3
));
System
.
out
.
println
(
prof
.
getTop
(
3
));
}
}
...
...
h2/src/test/org/h2/test/store/TestConcurrent.java
浏览文件 @
900b5667
...
@@ -43,7 +43,6 @@ public class TestConcurrent extends TestMVStore {
...
@@ -43,7 +43,6 @@ public class TestConcurrent extends TestMVStore {
@Override
@Override
public
void
test
()
throws
Exception
{
public
void
test
()
throws
Exception
{
FileUtils
.
deleteRecursive
(
getBaseDir
(),
true
);
FileUtils
.
deleteRecursive
(
getBaseDir
(),
true
);
FileUtils
.
createDirectories
(
getBaseDir
());
FileUtils
.
createDirectories
(
getBaseDir
());
FileUtils
.
deleteRecursive
(
"memFS:"
,
false
);
FileUtils
.
deleteRecursive
(
"memFS:"
,
false
);
...
@@ -110,7 +109,7 @@ public class TestConcurrent extends TestMVStore {
...
@@ -110,7 +109,7 @@ public class TestConcurrent extends TestMVStore {
m
.
clear
();
m
.
clear
();
s
.
removeMap
(
m
);
s
.
removeMap
(
m
);
if
(
x
%
5
==
0
)
{
if
(
x
%
5
==
0
)
{
s
.
incrementVersion
();
s
.
commit
();
}
}
}
}
task
.
get
();
task
.
get
();
...
@@ -124,9 +123,9 @@ public class TestConcurrent extends TestMVStore {
...
@@ -124,9 +123,9 @@ public class TestConcurrent extends TestMVStore {
}
}
}
}
assertEquals
(
1
,
chunkCount
);
assertEquals
(
1
,
chunkCount
);
s
.
close
();
s
.
close
();
}
}
FileUtils
.
deleteRecursive
(
"memFS:"
,
false
);
}
}
private
void
testConcurrentStoreAndRemoveMap
()
throws
InterruptedException
{
private
void
testConcurrentStoreAndRemoveMap
()
throws
InterruptedException
{
...
@@ -159,6 +158,7 @@ public class TestConcurrent extends TestMVStore {
...
@@ -159,6 +158,7 @@ public class TestConcurrent extends TestMVStore {
}
}
task
.
get
();
task
.
get
();
s
.
close
();
s
.
close
();
FileUtils
.
deleteRecursive
(
"memFS:"
,
false
);
}
}
private
void
testConcurrentStoreAndClose
()
throws
InterruptedException
{
private
void
testConcurrentStoreAndClose
()
throws
InterruptedException
{
...
@@ -200,6 +200,7 @@ public class TestConcurrent extends TestMVStore {
...
@@ -200,6 +200,7 @@ public class TestConcurrent extends TestMVStore {
}
}
s
.
close
();
s
.
close
();
}
}
FileUtils
.
deleteRecursive
(
"memFS:"
,
false
);
}
}
/**
/**
...
@@ -249,7 +250,7 @@ public class TestConcurrent extends TestMVStore {
...
@@ -249,7 +250,7 @@ public class TestConcurrent extends TestMVStore {
}
}
m
.
get
(
rand
.
nextInt
(
size
));
m
.
get
(
rand
.
nextInt
(
size
));
}
}
s
.
incrementVersion
();
s
.
commit
();
Thread
.
sleep
(
1
);
Thread
.
sleep
(
1
);
}
}
task
.
get
();
task
.
get
();
...
@@ -341,7 +342,7 @@ public class TestConcurrent extends TestMVStore {
...
@@ -341,7 +342,7 @@ public class TestConcurrent extends TestMVStore {
for
(
int
k
=
0
;
k
<
10000
;
k
++)
{
for
(
int
k
=
0
;
k
<
10000
;
k
++)
{
Iterator
<
Integer
>
it
=
map
.
keyIterator
(
r
.
nextInt
(
len
));
Iterator
<
Integer
>
it
=
map
.
keyIterator
(
r
.
nextInt
(
len
));
long
old
=
s
.
getCurrentVersion
();
long
old
=
s
.
getCurrentVersion
();
s
.
incrementVersion
();
s
.
commit
();
s
.
setRetainVersion
(
old
-
100
);
s
.
setRetainVersion
(
old
-
100
);
while
(
map
.
getVersion
()
==
old
)
{
while
(
map
.
getVersion
()
==
old
)
{
Thread
.
yield
();
Thread
.
yield
();
...
@@ -423,7 +424,7 @@ public class TestConcurrent extends TestMVStore {
...
@@ -423,7 +424,7 @@ public class TestConcurrent extends TestMVStore {
notDetected
.
incrementAndGet
();
notDetected
.
incrementAndGet
();
}
}
}
}
s
.
incrementVersion
();
s
.
commit
();
Thread
.
sleep
(
1
);
Thread
.
sleep
(
1
);
}
}
task
.
get
();
task
.
get
();
...
@@ -438,7 +439,7 @@ public class TestConcurrent extends TestMVStore {
...
@@ -438,7 +439,7 @@ public class TestConcurrent extends TestMVStore {
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
m
.
put
(
i
,
x
);
m
.
put
(
i
,
x
);
}
}
s
.
incrementVersion
();
s
.
commit
();
Task
task
=
new
Task
()
{
Task
task
=
new
Task
()
{
@Override
@Override
public
void
call
()
throws
Exception
{
public
void
call
()
throws
Exception
{
...
@@ -462,7 +463,7 @@ public class TestConcurrent extends TestMVStore {
...
@@ -462,7 +463,7 @@ public class TestConcurrent extends TestMVStore {
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
m
.
put
(
i
,
x
);
m
.
put
(
i
,
x
);
}
}
s
.
incrementVersion
();
s
.
commit
();
Thread
.
sleep
(
1
);
Thread
.
sleep
(
1
);
}
}
task
.
get
();
task
.
get
();
...
...
h2/src/test/org/h2/test/store/TestMVStore.java
浏览文件 @
900b5667
...
@@ -148,7 +148,7 @@ public class TestMVStore extends TestBase {
...
@@ -148,7 +148,7 @@ public class TestMVStore extends TestBase {
s
.
store
();
s
.
store
();
}
}
assertTrue
(
1000
<
offHeap
.
getWriteCount
());
assertTrue
(
1000
<
offHeap
.
getWriteCount
());
//
s.close();
s
.
close
();
s
=
new
MVStore
.
Builder
().
s
=
new
MVStore
.
Builder
().
fileStore
(
offHeap
).
fileStore
(
offHeap
).
...
@@ -253,7 +253,6 @@ public class TestMVStore extends TestBase {
...
@@ -253,7 +253,6 @@ public class TestMVStore extends TestBase {
m
=
s
.
openMap
(
"data"
);
m
=
s
.
openMap
(
"data"
);
s
.
getFileStore
().
getFile
().
close
();
s
.
getFileStore
().
getFile
().
close
();
m
.
put
(
1
,
"Hello"
);
m
.
put
(
1
,
"Hello"
);
s
.
commit
();
for
(
int
i
=
0
;
i
<
100
;
i
++)
{
for
(
int
i
=
0
;
i
<
100
;
i
++)
{
if
(
exRef
.
get
()
!=
null
)
{
if
(
exRef
.
get
()
!=
null
)
{
break
;
break
;
...
@@ -330,19 +329,19 @@ public class TestMVStore extends TestBase {
...
@@ -330,19 +329,19 @@ public class TestMVStore extends TestBase {
fileName
(
fileName
).
fileName
(
fileName
).
open
();
open
();
m
=
s
.
openMap
(
"data"
);
m
=
s
.
openMap
(
"data"
);
assert
Fals
e
(
m
.
containsKey
(
1
));
assert
Tru
e
(
m
.
containsKey
(
1
));
m
.
put
(
1
,
data
);
m
.
put
(
-
1
,
data
);
s
.
commit
();
s
.
store
();
m
.
put
(
2
,
data
);
m
.
put
(
-
2
,
data
);
s
.
close
();
s
.
close
();
s
=
new
MVStore
.
Builder
().
s
=
new
MVStore
.
Builder
().
fileName
(
fileName
).
fileName
(
fileName
).
open
();
open
();
m
=
s
.
openMap
(
"data"
);
m
=
s
.
openMap
(
"data"
);
assertTrue
(
m
.
containsKey
(
1
));
assertTrue
(
m
.
containsKey
(
-
1
));
assert
False
(
m
.
containsKey
(
2
));
assert
True
(
m
.
containsKey
(-
2
));
s
.
close
();
s
.
close
();
FileUtils
.
delete
(
fileName
);
FileUtils
.
delete
(
fileName
);
...
@@ -377,7 +376,7 @@ public class TestMVStore extends TestBase {
...
@@ -377,7 +376,7 @@ public class TestMVStore extends TestBase {
m
.
put
(
1
,
"Hello"
);
m
.
put
(
1
,
"Hello"
);
s
.
store
();
s
.
store
();
long
v
=
s
.
getCurrentVersion
();
long
v
=
s
.
getCurrentVersion
();
m
.
put
(
2
,
"World"
);
m
.
put
(
2
,
"World
.
"
);
Thread
.
sleep
(
5
);
Thread
.
sleep
(
5
);
// must not store, as nothing has been committed yet
// must not store, as nothing has been committed yet
s
.
closeImmediately
();
s
.
closeImmediately
();
...
@@ -386,9 +385,11 @@ public class TestMVStore extends TestBase {
...
@@ -386,9 +385,11 @@ public class TestMVStore extends TestBase {
open
();
open
();
s
.
setWriteDelay
(
1
);
s
.
setWriteDelay
(
1
);
m
=
s
.
openMap
(
"data"
);
m
=
s
.
openMap
(
"data"
);
assertEquals
(
null
,
m
.
get
(
2
));
assertEquals
(
"World."
,
m
.
get
(
2
));
m
.
put
(
2
,
"World"
);
m
.
put
(
2
,
"World"
);
s
.
commit
();
s
.
commit
();
s
.
store
();
v
=
s
.
getCurrentVersion
();
m
.
put
(
3
,
"!"
);
m
.
put
(
3
,
"!"
);
for
(
int
i
=
100
;
i
>
0
;
i
--)
{
for
(
int
i
=
100
;
i
>
0
;
i
--)
{
...
@@ -400,7 +401,7 @@ public class TestMVStore extends TestBase {
...
@@ -400,7 +401,7 @@ public class TestMVStore extends TestBase {
}
}
Thread
.
sleep
(
1
);
Thread
.
sleep
(
1
);
}
}
s
.
close
();
s
.
close
Immediately
();
s
=
new
MVStore
.
Builder
().
s
=
new
MVStore
.
Builder
().
fileName
(
fileName
).
fileName
(
fileName
).
...
@@ -408,7 +409,7 @@ public class TestMVStore extends TestBase {
...
@@ -408,7 +409,7 @@ public class TestMVStore extends TestBase {
m
=
s
.
openMap
(
"data"
);
m
=
s
.
openMap
(
"data"
);
assertEquals
(
"Hello"
,
m
.
get
(
1
));
assertEquals
(
"Hello"
,
m
.
get
(
1
));
assertEquals
(
"World"
,
m
.
get
(
2
));
assertEquals
(
"World"
,
m
.
get
(
2
));
assert
False
(
m
.
containsKey
(
3
));
assert
Equals
(
"!"
,
m
.
get
(
3
));
s
.
close
();
s
.
close
();
FileUtils
.
delete
(
fileName
);
FileUtils
.
delete
(
fileName
);
...
@@ -517,7 +518,7 @@ public class TestMVStore extends TestBase {
...
@@ -517,7 +518,7 @@ public class TestMVStore extends TestBase {
MVMap
<
Integer
,
Integer
>
map
;
MVMap
<
Integer
,
Integer
>
map
;
map
=
s
.
openMap
(
"hello"
);
map
=
s
.
openMap
(
"hello"
);
map
.
put
(
1
,
10
);
map
.
put
(
1
,
10
);
long
old
=
s
.
incrementVersion
();
long
old
=
s
.
commit
();
s
.
renameMap
(
map
,
"world"
);
s
.
renameMap
(
map
,
"world"
);
map
.
put
(
2
,
20
);
map
.
put
(
2
,
20
);
assertEquals
(
"world"
,
map
.
getName
());
assertEquals
(
"world"
,
map
.
getName
());
...
@@ -557,7 +558,7 @@ public class TestMVStore extends TestBase {
...
@@ -557,7 +558,7 @@ public class TestMVStore extends TestBase {
s
.
store
();
s
.
store
();
s
.
close
();
s
.
close
();
int
[]
expectedReadsForCacheSize
=
{
int
[]
expectedReadsForCacheSize
=
{
3405
,
2590
,
1924
,
1440
,
110
3
,
956
,
918
3405
,
2590
,
1924
,
1440
,
110
8
,
956
,
918
};
};
for
(
int
cacheSize
=
0
;
cacheSize
<=
6
;
cacheSize
+=
4
)
{
for
(
int
cacheSize
=
0
;
cacheSize
<=
6
;
cacheSize
+=
4
)
{
s
=
new
MVStore
.
Builder
().
s
=
new
MVStore
.
Builder
().
...
@@ -816,8 +817,10 @@ public class TestMVStore extends TestBase {
...
@@ -816,8 +817,10 @@ public class TestMVStore extends TestBase {
MVStore
s
=
MVStore
.
open
(
fileName
);
MVStore
s
=
MVStore
.
open
(
fileName
);
assertEquals
(
0
,
s
.
getCurrentVersion
());
assertEquals
(
0
,
s
.
getCurrentVersion
());
assertEquals
(
0
,
s
.
getStoreVersion
());
assertEquals
(
0
,
s
.
getStoreVersion
());
s
.
setStoreVersion
(
0
);
s
.
store
();
s
.
setStoreVersion
(
1
);
s
.
setStoreVersion
(
1
);
s
.
close
();
s
.
close
Immediately
();
s
=
MVStore
.
open
(
fileName
);
s
=
MVStore
.
open
(
fileName
);
assertEquals
(
1
,
s
.
getCurrentVersion
());
assertEquals
(
1
,
s
.
getCurrentVersion
());
assertEquals
(
0
,
s
.
getStoreVersion
());
assertEquals
(
0
,
s
.
getStoreVersion
());
...
@@ -840,7 +843,7 @@ public class TestMVStore extends TestBase {
...
@@ -840,7 +843,7 @@ public class TestMVStore extends TestBase {
map
.
put
(
i
,
10
*
i
);
map
.
put
(
i
,
10
*
i
);
}
}
Iterator
<
Integer
>
it
=
map
.
keySet
().
iterator
();
Iterator
<
Integer
>
it
=
map
.
keySet
().
iterator
();
s
.
incrementVersion
();
s
.
commit
();
for
(
int
i
=
0
;
i
<
len
;
i
+=
2
)
{
for
(
int
i
=
0
;
i
<
len
;
i
+=
2
)
{
map
.
remove
(
i
);
map
.
remove
(
i
);
}
}
...
@@ -916,7 +919,7 @@ public class TestMVStore extends TestBase {
...
@@ -916,7 +919,7 @@ public class TestMVStore extends TestBase {
long
oldVersion
=
s
.
getCurrentVersion
();
long
oldVersion
=
s
.
getCurrentVersion
();
// from now on, the old version is read-only
// from now on, the old version is read-only
s
.
incrementVersion
();
s
.
commit
();
// more changes, in the new version
// more changes, in the new version
// changes can be rolled back if required
// changes can be rolled back if required
...
@@ -976,7 +979,7 @@ public class TestMVStore extends TestBase {
...
@@ -976,7 +979,7 @@ public class TestMVStore extends TestBase {
if
(
op
==
1
)
{
if
(
op
==
1
)
{
m
.
put
(
"1"
,
""
+
s
.
getCurrentVersion
());
m
.
put
(
"1"
,
""
+
s
.
getCurrentVersion
());
}
}
s
.
incrementVersion
();
s
.
commit
();
}
}
for
(
int
j
=
0
;
j
<
s
.
getCurrentVersion
();
j
++)
{
for
(
int
j
=
0
;
j
<
s
.
getCurrentVersion
();
j
++)
{
MVMap
<
String
,
String
>
old
=
m
.
openVersion
(
j
);
MVMap
<
String
,
String
>
old
=
m
.
openVersion
(
j
);
...
@@ -997,14 +1000,14 @@ public class TestMVStore extends TestBase {
...
@@ -997,14 +1000,14 @@ public class TestMVStore extends TestBase {
MVMap
<
String
,
String
>
m
;
MVMap
<
String
,
String
>
m
;
m
=
s
.
openMap
(
"data"
);
m
=
s
.
openMap
(
"data"
);
long
first
=
s
.
getCurrentVersion
();
long
first
=
s
.
getCurrentVersion
();
s
.
incrementVersion
();
s
.
commit
();
m
.
put
(
"1"
,
"Hello"
);
m
.
put
(
"1"
,
"Hello"
);
m
.
put
(
"2"
,
"World"
);
m
.
put
(
"2"
,
"World"
);
for
(
int
i
=
10
;
i
<
20
;
i
++)
{
for
(
int
i
=
10
;
i
<
20
;
i
++)
{
m
.
put
(
""
+
i
,
"data"
);
m
.
put
(
""
+
i
,
"data"
);
}
}
long
old
=
s
.
getCurrentVersion
();
long
old
=
s
.
getCurrentVersion
();
s
.
incrementVersion
();
s
.
commit
();
m
.
put
(
"1"
,
"Hallo"
);
m
.
put
(
"1"
,
"Hallo"
);
m
.
put
(
"2"
,
"Welt"
);
m
.
put
(
"2"
,
"Welt"
);
MVMap
<
String
,
String
>
mFirst
;
MVMap
<
String
,
String
>
mFirst
;
...
@@ -1119,7 +1122,7 @@ public class TestMVStore extends TestBase {
...
@@ -1119,7 +1122,7 @@ public class TestMVStore extends TestBase {
assertTrue
(
s
.
hasUnsavedChanges
());
assertTrue
(
s
.
hasUnsavedChanges
());
MVMap
<
String
,
String
>
m0
=
s
.
openMap
(
"data0"
);
MVMap
<
String
,
String
>
m0
=
s
.
openMap
(
"data0"
);
m
.
put
(
"1"
,
"Hello"
);
m
.
put
(
"1"
,
"Hello"
);
assertEquals
(
1
,
s
.
incrementVersion
());
assertEquals
(
1
,
s
.
commit
());
s
.
rollbackTo
(
1
);
s
.
rollbackTo
(
1
);
assertEquals
(
1
,
s
.
getCurrentVersion
());
assertEquals
(
1
,
s
.
getCurrentVersion
());
assertEquals
(
"Hello"
,
m
.
get
(
"1"
));
assertEquals
(
"Hello"
,
m
.
get
(
"1"
));
...
@@ -1167,16 +1170,13 @@ public class TestMVStore extends TestBase {
...
@@ -1167,16 +1170,13 @@ public class TestMVStore extends TestBase {
assertEquals
(
"Hello"
,
m
.
get
(
"1"
));
assertEquals
(
"Hello"
,
m
.
get
(
"1"
));
assertFalse
(
m0
.
isReadOnly
());
assertFalse
(
m0
.
isReadOnly
());
m
.
put
(
"1"
,
"Hallo"
);
m
.
put
(
"1"
,
"Hallo"
);
s
.
incrementVersion
();
s
.
commit
();
long
v3
=
s
.
getCurrentVersion
();
long
v3
=
s
.
getCurrentVersion
();
assertEquals
(
3
,
v3
);
assertEquals
(
3
,
v3
);
long
v4
=
s
.
store
();
assertEquals
(
4
,
v4
);
assertEquals
(
4
,
s
.
getCurrentVersion
());
s
.
close
();
s
.
close
();
s
=
openStore
(
fileName
);
s
=
openStore
(
fileName
);
assertEquals
(
4
,
s
.
getCurrentVersion
());
assertEquals
(
3
,
s
.
getCurrentVersion
());
m
=
s
.
openMap
(
"data"
);
m
=
s
.
openMap
(
"data"
);
m
.
put
(
"1"
,
"Hi"
);
m
.
put
(
"1"
,
"Hi"
);
s
.
store
();
s
.
store
();
...
@@ -1185,7 +1185,7 @@ public class TestMVStore extends TestBase {
...
@@ -1185,7 +1185,7 @@ public class TestMVStore extends TestBase {
s
=
openStore
(
fileName
);
s
=
openStore
(
fileName
);
m
=
s
.
openMap
(
"data"
);
m
=
s
.
openMap
(
"data"
);
assertEquals
(
"Hi"
,
m
.
get
(
"1"
));
assertEquals
(
"Hi"
,
m
.
get
(
"1"
));
s
.
rollbackTo
(
v
4
);
s
.
rollbackTo
(
v
3
);
assertEquals
(
"Hallo"
,
m
.
get
(
"1"
));
assertEquals
(
"Hallo"
,
m
.
get
(
"1"
));
s
.
close
();
s
.
close
();
...
@@ -1212,7 +1212,7 @@ public class TestMVStore extends TestBase {
...
@@ -1212,7 +1212,7 @@ public class TestMVStore extends TestBase {
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
m2
.
put
(
""
+
i
,
"Test"
);
m2
.
put
(
""
+
i
,
"Test"
);
}
}
long
v1
=
s
.
incrementVersion
();
long
v1
=
s
.
commit
();
assertEquals
(
1
,
v1
);
assertEquals
(
1
,
v1
);
assertEquals
(
1
,
s
.
getCurrentVersion
());
assertEquals
(
1
,
s
.
getCurrentVersion
());
MVMap
<
String
,
String
>
m1
=
s
.
openMap
(
"data1"
);
MVMap
<
String
,
String
>
m1
=
s
.
openMap
(
"data1"
);
...
...
h2/src/test/org/h2/test/store/TestMVStoreBenchmark.java
浏览文件 @
900b5667
...
@@ -73,7 +73,7 @@ public class TestMVStoreBenchmark extends TestBase {
...
@@ -73,7 +73,7 @@ public class TestMVStoreBenchmark extends TestBase {
}
}
private
static
long
[]
getMemoryUsed
(
int
count
,
int
size
)
{
private
long
[]
getMemoryUsed
(
int
count
,
int
size
)
{
long
hash
,
tree
,
mv
;
long
hash
,
tree
,
mv
;
ArrayList
<
Map
<
Integer
,
String
>>
mapList
;
ArrayList
<
Map
<
Integer
,
String
>>
mapList
;
long
mem
;
long
mem
;
...
@@ -107,6 +107,10 @@ public class TestMVStoreBenchmark extends TestBase {
...
@@ -107,6 +107,10 @@ public class TestMVStoreBenchmark extends TestBase {
mv
=
getMemory
()
-
mem
;
mv
=
getMemory
()
-
mem
;
mapList
.
size
();
mapList
.
size
();
trace
(
"hash: "
+
hash
/
1024
/
1024
+
" mb"
);
trace
(
"tree: "
+
tree
/
1024
/
1024
+
" mb"
);
trace
(
"mv: "
+
mv
/
1024
/
1024
+
" mb"
);
return
new
long
[]{
hash
,
tree
,
mv
};
return
new
long
[]{
hash
,
tree
,
mv
};
}
}
...
@@ -179,7 +183,7 @@ public class TestMVStoreBenchmark extends TestBase {
...
@@ -179,7 +183,7 @@ public class TestMVStoreBenchmark extends TestBase {
}
}
time
=
System
.
currentTimeMillis
()
-
time
;
time
=
System
.
currentTimeMillis
()
-
time
;
}
}
// System.out.println
(map.getClass().getName() + ": " + time);
trace
(
map
.
getClass
().
getName
()
+
": "
+
time
);
return
time
;
return
time
;
}
}
...
...
h2/src/test/org/h2/test/store/TestMVTableEngine.java
浏览文件 @
900b5667
...
@@ -141,7 +141,7 @@ public class TestMVTableEngine extends TestBase {
...
@@ -141,7 +141,7 @@ public class TestMVTableEngine extends TestBase {
conn
.
close
();
conn
.
close
();
long
sizeNew
=
FileUtils
.
size
(
getBaseDir
()
+
"/mvstore"
long
sizeNew
=
FileUtils
.
size
(
getBaseDir
()
+
"/mvstore"
+
Constants
.
SUFFIX_MV_FILE
);
+
Constants
.
SUFFIX_MV_FILE
);
assertTrue
(
sizeNew
<
sizeOld
);
assertTrue
(
"new: "
+
sizeNew
+
" old: "
+
sizeOld
,
sizeNew
<
sizeOld
);
}
}
private
void
testTwoPhaseCommit
()
throws
Exception
{
private
void
testTwoPhaseCommit
()
throws
Exception
{
...
...
h2/src/test/org/h2/test/store/TestTransactionStore.java
浏览文件 @
900b5667
...
@@ -59,6 +59,7 @@ public class TestTransactionStore extends TestBase {
...
@@ -59,6 +59,7 @@ public class TestTransactionStore extends TestBase {
private
void
testStopWhileCommitting
()
throws
Exception
{
private
void
testStopWhileCommitting
()
throws
Exception
{
String
fileName
=
getBaseDir
()
+
"/testStopWhileCommitting.h3"
;
String
fileName
=
getBaseDir
()
+
"/testStopWhileCommitting.h3"
;
FileUtils
.
delete
(
fileName
);
FileUtils
.
delete
(
fileName
);
Random
r
=
new
Random
(
0
);
for
(
int
i
=
0
;
i
<
10
;)
{
for
(
int
i
=
0
;
i
<
10
;)
{
MVStore
s
;
MVStore
s
;
...
@@ -100,6 +101,16 @@ public class TestTransactionStore extends TestBase {
...
@@ -100,6 +101,16 @@ public class TestTransactionStore extends TestBase {
task
.
get
();
task
.
get
();
store
.
close
();
store
.
close
();
s
=
MVStore
.
open
(
fileName
);
s
=
MVStore
.
open
(
fileName
);
// roll back a bit, until we have some undo log entries
assertTrue
(
s
.
hasMap
(
"undoLog"
));
for
(
int
back
=
0
;
back
<
100
;
back
++)
{
int
minus
=
r
.
nextInt
(
10
);
s
.
rollbackTo
(
Math
.
max
(
0
,
s
.
getCurrentVersion
()
-
minus
));
MVMap
<?,
?>
undo
=
s
.
openMap
(
"undoLog"
);
if
(
undo
.
size
()
>
0
)
{
break
;
}
}
ts
=
new
TransactionStore
(
s
);
ts
=
new
TransactionStore
(
s
);
List
<
Transaction
>
list
=
ts
.
getOpenTransactions
();
List
<
Transaction
>
list
=
ts
.
getOpenTransactions
();
if
(
list
.
size
()
!=
0
)
{
if
(
list
.
size
()
!=
0
)
{
...
@@ -111,10 +122,6 @@ public class TestTransactionStore extends TestBase {
...
@@ -111,10 +122,6 @@ public class TestTransactionStore extends TestBase {
s
.
close
();
s
.
close
();
FileUtils
.
delete
(
fileName
);
FileUtils
.
delete
(
fileName
);
assertFalse
(
FileUtils
.
exists
(
fileName
));
assertFalse
(
FileUtils
.
exists
(
fileName
));
FileUtils
.
delete
(
fileName
);
assertFalse
(
FileUtils
.
exists
(
fileName
));
s
.
close
();
FileUtils
.
delete
(
fileName
);
}
}
}
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论