Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
f898ba35
提交
f898ba35
authored
12月 14, 2012
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
MVStore: table engine
上级
18808fa8
隐藏空白字符变更
内嵌
并排
正在显示
15 个修改的文件
包含
526 行增加
和
103 行删除
+526
-103
BaseIndex.java
h2/src/main/org/h2/index/BaseIndex.java
+1
-1
MVMap.java
h2/src/main/org/h2/mvstore/MVMap.java
+14
-7
MVStore.java
h2/src/main/org/h2/mvstore/MVStore.java
+53
-19
MVDelegateIndex.java
h2/src/main/org/h2/mvstore/db/MVDelegateIndex.java
+2
-13
MVPrimaryIndex.java
h2/src/main/org/h2/mvstore/db/MVPrimaryIndex.java
+32
-8
MVSecondaryIndex.java
h2/src/main/org/h2/mvstore/db/MVSecondaryIndex.java
+48
-17
MVTable.java
h2/src/main/org/h2/mvstore/db/MVTable.java
+240
-13
help.csv
h2/src/main/org/h2/res/help.csv
+4
-0
TableBase.java
h2/src/main/org/h2/table/TableBase.java
+1
-1
TestAll.java
h2/src/test/org/h2/test/TestAll.java
+23
-21
TestBase.java
h2/src/test/org/h2/test/TestBase.java
+3
-0
test.properties
h2/src/test/org/h2/test/bench/test.properties
+1
-0
TestMVStore.java
h2/src/test/org/h2/test/store/TestMVStore.java
+3
-3
TestMVTableEngine.java
h2/src/test/org/h2/test/store/TestMVTableEngine.java
+99
-0
test-1.3.txt
h2/src/test/org/h2/test/test-1.3.txt
+2
-0
没有找到文件。
h2/src/main/org/h2/index/BaseIndex.java
浏览文件 @
f898ba35
...
@@ -194,7 +194,7 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
...
@@ -194,7 +194,7 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
* @return true if one of the columns is null and multiple nulls in unique
* @return true if one of the columns is null and multiple nulls in unique
* indexes are allowed
* indexes are allowed
*/
*/
boolean
containsNullAndAllowMultipleNull
(
SearchRow
newRow
)
{
protected
boolean
containsNullAndAllowMultipleNull
(
SearchRow
newRow
)
{
Mode
mode
=
database
.
getMode
();
Mode
mode
=
database
.
getMode
();
if
(
mode
.
uniqueIndexSingleNull
)
{
if
(
mode
.
uniqueIndexSingleNull
)
{
return
false
;
return
false
;
...
...
h2/src/main/org/h2/mvstore/MVMap.java
浏览文件 @
f898ba35
...
@@ -39,7 +39,6 @@ public class MVMap<K, V> extends AbstractMap<K, V>
...
@@ -39,7 +39,6 @@ public class MVMap<K, V> extends AbstractMap<K, V>
protected
volatile
Page
root
;
protected
volatile
Page
root
;
private
int
id
;
private
int
id
;
private
String
name
;
private
long
createVersion
;
private
long
createVersion
;
private
final
DataType
keyType
;
private
final
DataType
keyType
;
private
final
DataType
valueType
;
private
final
DataType
valueType
;
...
@@ -63,7 +62,6 @@ public class MVMap<K, V> extends AbstractMap<K, V>
...
@@ -63,7 +62,6 @@ public class MVMap<K, V> extends AbstractMap<K, V>
public
void
open
(
MVStore
store
,
HashMap
<
String
,
String
>
config
)
{
public
void
open
(
MVStore
store
,
HashMap
<
String
,
String
>
config
)
{
this
.
store
=
store
;
this
.
store
=
store
;
this
.
id
=
Integer
.
parseInt
(
config
.
get
(
"id"
));
this
.
id
=
Integer
.
parseInt
(
config
.
get
(
"id"
));
this
.
name
=
config
.
get
(
"name"
);
this
.
createVersion
=
Long
.
parseLong
(
config
.
get
(
"createVersion"
));
this
.
createVersion
=
Long
.
parseLong
(
config
.
get
(
"createVersion"
));
}
}
...
@@ -480,7 +478,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
...
@@ -480,7 +478,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
if
(
this
!=
store
.
getMetaMap
())
{
if
(
this
!=
store
.
getMetaMap
())
{
checkWrite
();
checkWrite
();
root
.
removeAllRecursive
();
root
.
removeAllRecursive
();
store
.
removeMap
(
name
);
store
.
removeMap
(
id
);
close
();
close
();
}
}
}
}
...
@@ -781,7 +779,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
...
@@ -781,7 +779,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
* @return the name
* @return the name
*/
*/
public
String
getName
()
{
public
String
getName
()
{
return
name
;
return
store
.
getMapName
(
id
)
;
}
}
public
MVStore
getStore
()
{
public
MVStore
getStore
()
{
...
@@ -891,6 +889,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
...
@@ -891,6 +889,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
}
}
public
long
getSize
()
{
public
long
getSize
()
{
checkOpen
();
return
root
.
getTotalCount
();
return
root
.
getTotalCount
();
}
}
...
@@ -933,7 +932,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
...
@@ -933,7 +932,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
// not found
// not found
if
(
i
==
-
1
)
{
if
(
i
==
-
1
)
{
// smaller than all in-memory versions
// smaller than all in-memory versions
return
store
.
openMapVersion
(
version
,
name
,
this
);
return
store
.
openMapVersion
(
version
,
id
,
this
);
}
}
i
=
-
i
-
2
;
i
=
-
i
-
2
;
}
}
...
@@ -954,7 +953,6 @@ public class MVMap<K, V> extends AbstractMap<K, V>
...
@@ -954,7 +953,6 @@ public class MVMap<K, V> extends AbstractMap<K, V>
m
.
readOnly
=
true
;
m
.
readOnly
=
true
;
HashMap
<
String
,
String
>
config
=
New
.
hashMap
();
HashMap
<
String
,
String
>
config
=
New
.
hashMap
();
config
.
put
(
"id"
,
String
.
valueOf
(
id
));
config
.
put
(
"id"
,
String
.
valueOf
(
id
));
config
.
put
(
"name"
,
name
);
config
.
put
(
"createVersion"
,
String
.
valueOf
(
createVersion
));
config
.
put
(
"createVersion"
,
String
.
valueOf
(
createVersion
));
m
.
open
(
store
,
config
);
m
.
open
(
store
,
config
);
m
.
root
=
root
;
m
.
root
=
root
;
...
@@ -1010,7 +1008,6 @@ public class MVMap<K, V> extends AbstractMap<K, V>
...
@@ -1010,7 +1008,6 @@ public class MVMap<K, V> extends AbstractMap<K, V>
public
String
asString
()
{
public
String
asString
()
{
StringBuilder
buff
=
new
StringBuilder
();
StringBuilder
buff
=
new
StringBuilder
();
DataUtils
.
appendMap
(
buff
,
"id"
,
id
);
DataUtils
.
appendMap
(
buff
,
"id"
,
id
);
DataUtils
.
appendMap
(
buff
,
"name"
,
name
);
DataUtils
.
appendMap
(
buff
,
"type"
,
getType
());
DataUtils
.
appendMap
(
buff
,
"type"
,
getType
());
DataUtils
.
appendMap
(
buff
,
"createVersion"
,
createVersion
);
DataUtils
.
appendMap
(
buff
,
"createVersion"
,
createVersion
);
if
(
keyType
!=
null
)
{
if
(
keyType
!=
null
)
{
...
@@ -1022,6 +1019,16 @@ public class MVMap<K, V> extends AbstractMap<K, V>
...
@@ -1022,6 +1019,16 @@ public class MVMap<K, V> extends AbstractMap<K, V>
return
buff
.
toString
();
return
buff
.
toString
();
}
}
/**
* Rename the map.
*
* @param newMapName the name name
*/
public
void
rename
(
String
newMapName
)
{
checkWrite
();
store
.
renameMap
(
this
,
newMapName
);
}
public
String
toString
()
{
public
String
toString
()
{
return
asString
();
return
asString
();
}
}
...
...
h2/src/main/org/h2/mvstore/MVStore.java
浏览文件 @
f898ba35
...
@@ -43,8 +43,13 @@ header:
...
@@ -43,8 +43,13 @@ header:
H:3,...
H:3,...
TODO:
TODO:
- automated 'kill process' and 'power failure' test
- after rollback: is a regular save ok?
- cache: change API to better match guava / Android
- rename a map
- MVStore: improved API thanks to Simo Tripodi
- implement table engine for H2
- implement table engine for H2
- automated 'kill process' and 'power failure' test
- maybe split database into multiple files, to speed up compact
- maybe split database into multiple files, to speed up compact
- auto-compact from time to time and on close
- 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)
...
@@ -150,6 +155,7 @@ public class MVStore {
...
@@ -150,6 +155,7 @@ public class MVStore {
private
MVMap
<
String
,
String
>
meta
;
private
MVMap
<
String
,
String
>
meta
;
private
final
HashMap
<
String
,
MVMap
<?,
?>>
maps
=
New
.
hashMap
();
private
final
HashMap
<
String
,
MVMap
<?,
?>>
maps
=
New
.
hashMap
();
private
final
HashMap
<
Integer
,
String
>
mapIdName
=
New
.
hashMap
();
/**
/**
* The set of maps with potentially unsaved changes.
* The set of maps with potentially unsaved changes.
...
@@ -225,14 +231,14 @@ public class MVStore {
...
@@ -225,14 +231,14 @@ public class MVStore {
* Open an old, stored version of a map.
* Open an old, stored version of a map.
*
*
* @param version the version
* @param version the version
* @param
name the map name
* @param
mapId the map id
* @param template the template map
* @param template the template map
* @return the read-only map
* @return the read-only map
*/
*/
@SuppressWarnings
(
"unchecked"
)
@SuppressWarnings
(
"unchecked"
)
<
T
extends
MVMap
<?,
?>>
T
openMapVersion
(
long
version
,
String
name
,
MVMap
<?,
?>
template
)
{
<
T
extends
MVMap
<?,
?>>
T
openMapVersion
(
long
version
,
int
mapId
,
MVMap
<?,
?>
template
)
{
MVMap
<
String
,
String
>
oldMeta
=
getMetaMap
(
version
);
MVMap
<
String
,
String
>
oldMeta
=
getMetaMap
(
version
);
String
r
=
oldMeta
.
get
(
"root."
+
template
.
getId
()
);
String
r
=
oldMeta
.
get
(
"root."
+
mapId
);
long
rootPos
=
r
==
null
?
0
:
Long
.
parseLong
(
r
);
long
rootPos
=
r
==
null
?
0
:
Long
.
parseLong
(
r
);
MVMap
<?,
?>
m
=
template
.
openReadOnly
();
MVMap
<?,
?>
m
=
template
.
openReadOnly
();
m
.
setRootPos
(
rootPos
,
version
);
m
.
setRootPos
(
rootPos
,
version
);
...
@@ -292,10 +298,12 @@ public class MVStore {
...
@@ -292,10 +298,12 @@ public class MVStore {
m
=
template
;
m
=
template
;
String
config
=
meta
.
get
(
"map."
+
name
);
String
config
=
meta
.
get
(
"map."
+
name
);
long
root
;
long
root
;
int
id
;
HashMap
<
String
,
String
>
c
;
HashMap
<
String
,
String
>
c
;
if
(
config
==
null
)
{
if
(
config
==
null
)
{
c
=
New
.
hashMap
();
c
=
New
.
hashMap
();
c
.
put
(
"id"
,
Integer
.
toString
(++
lastMapId
));
id
=
++
lastMapId
;
c
.
put
(
"id"
,
Integer
.
toString
(
id
));
c
.
put
(
"name"
,
name
);
c
.
put
(
"name"
,
name
);
c
.
put
(
"createVersion"
,
Long
.
toString
(
currentVersion
));
c
.
put
(
"createVersion"
,
Long
.
toString
(
currentVersion
));
m
.
open
(
this
,
c
);
m
.
open
(
this
,
c
);
...
@@ -303,11 +311,13 @@ public class MVStore {
...
@@ -303,11 +311,13 @@ public class MVStore {
root
=
0
;
root
=
0
;
}
else
{
}
else
{
c
=
DataUtils
.
parseMap
(
config
);
c
=
DataUtils
.
parseMap
(
config
);
String
r
=
meta
.
get
(
"root."
+
c
.
get
(
"id"
));
id
=
Integer
.
parseInt
(
c
.
get
(
"id"
));
String
r
=
meta
.
get
(
"root."
+
id
);
root
=
r
==
null
?
0
:
Long
.
parseLong
(
r
);
root
=
r
==
null
?
0
:
Long
.
parseLong
(
r
);
}
}
m
.
open
(
this
,
c
);
m
.
open
(
this
,
c
);
m
.
setRootPos
(
root
,
-
1
);
m
.
setRootPos
(
root
,
-
1
);
mapIdName
.
put
(
id
,
name
);
maps
.
put
(
name
,
m
);
maps
.
put
(
name
,
m
);
return
(
T
)
m
;
return
(
T
)
m
;
}
}
...
@@ -357,13 +367,15 @@ public class MVStore {
...
@@ -357,13 +367,15 @@ public class MVStore {
/**
/**
* Remove a map.
* Remove a map.
*
*
* @param
name the map name
* @param
id the map id
*/
*/
void
removeMap
(
String
name
)
{
void
removeMap
(
int
id
)
{
MVMap
<?,
?>
map
=
maps
.
remove
(
name
);
String
name
=
mapIdName
.
get
(
id
);
meta
.
remove
(
"map."
+
name
);
meta
.
remove
(
"map."
+
name
);
meta
.
remove
(
"root."
+
map
.
getId
());
meta
.
remove
(
"root."
+
id
);
mapsChanged
.
remove
(
map
.
getId
());
mapsChanged
.
remove
(
id
);
mapIdName
.
remove
(
id
);
maps
.
remove
(
name
);
}
}
private
DataType
getDataType
(
Class
<?>
clazz
)
{
private
DataType
getDataType
(
Class
<?>
clazz
)
{
...
@@ -560,6 +572,7 @@ public class MVStore {
...
@@ -560,6 +572,7 @@ public class MVStore {
chunks
.
clear
();
chunks
.
clear
();
cache
.
clear
();
cache
.
clear
();
maps
.
clear
();
maps
.
clear
();
mapIdName
.
clear
();
mapsChanged
.
clear
();
mapsChanged
.
clear
();
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
throw
DataUtils
.
illegalStateException
(
"Closing failed for file "
+
fileName
,
e
);
throw
DataUtils
.
illegalStateException
(
"Closing failed for file "
+
fileName
,
e
);
...
@@ -987,12 +1000,7 @@ public class MVStore {
...
@@ -987,12 +1000,7 @@ public class MVStore {
if
(
mapId
==
0
)
{
if
(
mapId
==
0
)
{
return
meta
;
return
meta
;
}
}
for
(
MVMap
<?,
?>
m
:
maps
.
values
())
{
return
maps
.
get
(
mapIdName
.
get
(
mapId
));
if
(
m
.
getId
()
==
mapId
)
{
return
m
;
}
}
return
null
;
}
}
/**
/**
...
@@ -1274,13 +1282,15 @@ public class MVStore {
...
@@ -1274,13 +1282,15 @@ public class MVStore {
readMeta
();
readMeta
();
}
}
}
}
int
todoRollbackMapNames
;
for
(
MVMap
<?,
?>
m
:
maps
.
values
())
{
for
(
MVMap
<?,
?>
m
:
maps
.
values
())
{
int
id
=
m
.
getId
();
if
(
m
.
getCreateVersion
()
>=
version
)
{
if
(
m
.
getCreateVersion
()
>=
version
)
{
m
.
close
();
m
.
close
();
removeMap
(
m
.
getName
()
);
removeMap
(
id
);
}
else
{
}
else
{
if
(
loadFromFile
)
{
if
(
loadFromFile
)
{
String
r
=
meta
.
get
(
"root."
+
m
.
getId
()
);
String
r
=
meta
.
get
(
"root."
+
id
);
long
root
=
r
==
null
?
0
:
Long
.
parseLong
(
r
);
long
root
=
r
==
null
?
0
:
Long
.
parseLong
(
r
);
m
.
setRootPos
(
root
,
version
);
m
.
setRootPos
(
root
,
version
);
}
}
...
@@ -1367,4 +1377,28 @@ public class MVStore {
...
@@ -1367,4 +1377,28 @@ public class MVStore {
return
DataUtils
.
appendMap
(
new
StringBuilder
(),
config
).
toString
();
return
DataUtils
.
appendMap
(
new
StringBuilder
(),
config
).
toString
();
}
}
void
renameMap
(
MVMap
<?,
?>
map
,
String
newName
)
{
checkOpen
();
if
(
map
==
meta
)
{
throw
DataUtils
.
unsupportedOperationException
(
"Renaming the meta map is not allowed"
);
}
if
(
map
.
getName
().
equals
(
newName
))
{
return
;
}
if
(
meta
.
containsKey
(
"map."
+
newName
))
{
throw
DataUtils
.
illegalArgumentException
(
"A map named "
+
newName
+
" already exists"
);
}
int
id
=
map
.
getId
();
String
oldName
=
mapIdName
.
remove
(
id
);
maps
.
remove
(
oldName
);
String
value
=
meta
.
remove
(
"map."
+
oldName
);
meta
.
put
(
"map."
+
newName
,
value
);
maps
.
put
(
newName
,
map
);
mapIdName
.
put
(
id
,
newName
);
}
String
getMapName
(
int
id
)
{
return
mapIdName
.
get
(
id
);
}
}
}
h2/src/main/org/h2/mvstore/db/MVDelegateIndex.java
浏览文件 @
f898ba35
...
@@ -43,9 +43,7 @@ public class MVDelegateIndex extends BaseIndex {
...
@@ -43,9 +43,7 @@ public class MVDelegateIndex extends BaseIndex {
}
}
public
boolean
canGetFirstOrLast
()
{
public
boolean
canGetFirstOrLast
()
{
return
false
;
return
true
;
// TODO
// return true;
}
}
public
void
close
(
Session
session
)
{
public
void
close
(
Session
session
)
{
...
@@ -61,16 +59,7 @@ public class MVDelegateIndex extends BaseIndex {
...
@@ -61,16 +59,7 @@ public class MVDelegateIndex extends BaseIndex {
}
}
public
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
{
public
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
{
return
null
;
return
mainIndex
.
findFirstOrLast
(
session
,
first
);
// Cursor cursor;
// if (first) {
// cursor = mainIndex.find(session, Long.MIN_VALUE, Long.MAX_VALUE, false);
// } else {
// long x = mainIndex.getLastKey();
// cursor = mainIndex.find(session, x, x, false);
// }
// cursor.next();
// return cursor;
}
}
public
Cursor
findNext
(
Session
session
,
SearchRow
higherThan
,
SearchRow
last
)
{
public
Cursor
findNext
(
Session
session
,
SearchRow
higherThan
,
SearchRow
last
)
{
...
...
h2/src/main/org/h2/mvstore/db/MVPrimaryIndex.java
浏览文件 @
f898ba35
...
@@ -6,6 +6,8 @@
...
@@ -6,6 +6,8 @@
*/
*/
package
org
.
h2
.
mvstore
.
db
;
package
org
.
h2
.
mvstore
.
db
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.Iterator
;
import
java.util.Iterator
;
import
org.h2.constant.ErrorCode
;
import
org.h2.constant.ErrorCode
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Constants
;
...
@@ -20,6 +22,7 @@ import org.h2.mvstore.type.ObjectDataType;
...
@@ -20,6 +22,7 @@ import org.h2.mvstore.type.ObjectDataType;
import
org.h2.result.Row
;
import
org.h2.result.Row
;
import
org.h2.result.SearchRow
;
import
org.h2.result.SearchRow
;
import
org.h2.result.SortOrder
;
import
org.h2.result.SortOrder
;
import
org.h2.table.Column
;
import
org.h2.table.IndexColumn
;
import
org.h2.table.IndexColumn
;
import
org.h2.value.Value
;
import
org.h2.value.Value
;
import
org.h2.value.ValueNull
;
import
org.h2.value.ValueNull
;
...
@@ -45,11 +48,16 @@ public class MVPrimaryIndex extends BaseIndex {
...
@@ -45,11 +48,16 @@ public class MVPrimaryIndex extends BaseIndex {
ValueArrayDataType
t
=
new
ValueArrayDataType
(
ValueArrayDataType
t
=
new
ValueArrayDataType
(
db
.
getCompareMode
(),
db
,
sortTypes
);
db
.
getCompareMode
(),
db
,
sortTypes
);
map
=
new
MVMap
<
Long
,
Value
[]>(
new
ObjectDataType
(),
t
);
map
=
new
MVMap
<
Long
,
Value
[]>(
new
ObjectDataType
(),
t
);
map
=
table
.
getStore
().
openMap
(
getName
(),
map
);
map
=
table
.
getStore
().
openMap
(
getName
()
+
"_"
+
getId
()
,
map
);
Long
k
=
map
.
lastKey
();
Long
k
=
map
.
lastKey
();
nextKey
=
k
==
null
?
0
:
k
+
1
;
nextKey
=
k
==
null
?
0
:
k
+
1
;
}
}
public
void
renameTable
(
String
newName
)
{
rename
(
newName
+
"_DATA"
);
map
.
rename
(
newName
+
"_DATA_"
+
getId
());
}
public
String
getCreateSQL
()
{
public
String
getCreateSQL
()
{
return
null
;
return
null
;
}
}
...
@@ -147,6 +155,12 @@ public class MVPrimaryIndex extends BaseIndex {
...
@@ -147,6 +155,12 @@ public class MVPrimaryIndex extends BaseIndex {
return
cost
;
return
cost
;
}
}
public
int
getColumnIndex
(
Column
col
)
{
// can not use this index - use the delegate index instead
return
-
1
;
}
@Override
@Override
public
void
remove
(
Session
session
)
{
public
void
remove
(
Session
session
)
{
if
(!
map
.
isClosed
())
{
if
(!
map
.
isClosed
())
{
...
@@ -161,19 +175,22 @@ public class MVPrimaryIndex extends BaseIndex {
...
@@ -161,19 +175,22 @@ public class MVPrimaryIndex extends BaseIndex {
@Override
@Override
public
boolean
canGetFirstOrLast
()
{
public
boolean
canGetFirstOrLast
()
{
return
fals
e
;
return
tru
e
;
}
}
@Override
@Override
public
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
{
public
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
{
// return first ? map.firstKey() : map.lastKey();
if
(
map
.
getSize
()
==
0
)
{
// TODO get first / last
return
new
MVStoreCursor
(
session
,
Collections
.<
Long
>
emptyList
().
iterator
(),
0
);
return
null
;
}
long
key
=
first
?
map
.
firstKey
()
:
map
.
lastKey
();
MVStoreCursor
cursor
=
new
MVStoreCursor
(
session
,
Arrays
.
asList
(
key
).
iterator
(),
key
);
cursor
.
next
();
return
cursor
;
}
}
@Override
@Override
public
boolean
needRebuild
()
{
public
boolean
needRebuild
()
{
// TODO Auto-generated method stub
return
false
;
return
false
;
}
}
...
@@ -188,7 +205,8 @@ public class MVPrimaryIndex extends BaseIndex {
...
@@ -188,7 +205,8 @@ public class MVPrimaryIndex extends BaseIndex {
}
}
public
long
getDiskSpaceUsed
()
{
public
long
getDiskSpaceUsed
()
{
return
0
;
// TODO
// TODO estimate disk space usage
return
0
;
}
}
@Override
@Override
...
@@ -249,7 +267,9 @@ public class MVPrimaryIndex extends BaseIndex {
...
@@ -249,7 +267,9 @@ public class MVPrimaryIndex extends BaseIndex {
@Override
@Override
public
Row
get
()
{
public
Row
get
()
{
if
(
row
==
null
)
{
if
(
row
==
null
)
{
row
=
getRow
(
session
,
current
);
if
(
current
!=
null
)
{
row
=
getRow
(
session
,
current
);
}
}
}
return
row
;
return
row
;
}
}
...
@@ -277,4 +297,8 @@ public class MVPrimaryIndex extends BaseIndex {
...
@@ -277,4 +297,8 @@ public class MVPrimaryIndex extends BaseIndex {
}
}
public
boolean
isRowIdIndex
()
{
return
true
;
}
}
}
h2/src/main/org/h2/mvstore/db/MVSecondaryIndex.java
浏览文件 @
f898ba35
...
@@ -6,6 +6,8 @@
...
@@ -6,6 +6,8 @@
*/
*/
package
org
.
h2
.
mvstore
.
db
;
package
org
.
h2
.
mvstore
.
db
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Iterator
;
import
java.util.Iterator
;
import
org.h2.constant.ErrorCode
;
import
org.h2.constant.ErrorCode
;
import
org.h2.engine.Database
;
import
org.h2.engine.Database
;
...
@@ -21,6 +23,7 @@ import org.h2.result.SearchRow;
...
@@ -21,6 +23,7 @@ import org.h2.result.SearchRow;
import
org.h2.result.SortOrder
;
import
org.h2.result.SortOrder
;
import
org.h2.table.Column
;
import
org.h2.table.Column
;
import
org.h2.table.IndexColumn
;
import
org.h2.table.IndexColumn
;
import
org.h2.util.New
;
import
org.h2.value.Value
;
import
org.h2.value.Value
;
import
org.h2.value.ValueLong
;
import
org.h2.value.ValueLong
;
...
@@ -48,7 +51,7 @@ public class MVSecondaryIndex extends BaseIndex {
...
@@ -48,7 +51,7 @@ public class MVSecondaryIndex extends BaseIndex {
ValueArrayDataType
t
=
new
ValueArrayDataType
(
ValueArrayDataType
t
=
new
ValueArrayDataType
(
db
.
getCompareMode
(),
db
,
sortTypes
);
db
.
getCompareMode
(),
db
,
sortTypes
);
map
=
new
MVMap
<
Value
[],
Long
>(
t
,
new
ObjectDataType
());
map
=
new
MVMap
<
Value
[],
Long
>(
t
,
new
ObjectDataType
());
map
=
table
.
getStore
().
openMap
(
getName
(),
map
);
map
=
table
.
getStore
().
openMap
(
getName
()
+
"_"
+
getId
()
,
map
);
}
}
@Override
@Override
...
@@ -56,13 +59,24 @@ public class MVSecondaryIndex extends BaseIndex {
...
@@ -56,13 +59,24 @@ public class MVSecondaryIndex extends BaseIndex {
// ok
// ok
}
}
public
void
rename
(
String
newName
)
{
map
.
rename
(
newName
+
"_"
+
getId
());
super
.
rename
(
newName
);
}
@Override
@Override
public
void
add
(
Session
session
,
Row
row
)
{
public
void
add
(
Session
session
,
Row
row
)
{
Value
[]
array
=
getKey
(
row
);
Value
[]
array
=
getKey
(
row
);
if
(
indexType
.
isUnique
())
{
if
(
indexType
.
isUnique
())
{
array
[
keyColumns
-
1
]
=
ValueLong
.
get
(
0
);
array
[
keyColumns
-
1
]
=
ValueLong
.
get
(
0
);
if
(
map
.
containsKey
(
array
))
{
Value
[]
key
=
map
.
ceilingKey
(
array
);
throw
getDuplicateKeyException
();
if
(
key
!=
null
)
{
SearchRow
r2
=
getRow
(
key
);
if
(
compareRows
(
row
,
r2
)
==
0
)
{
if
(!
containsNullAndAllowMultipleNull
(
r2
))
{
throw
getDuplicateKeyException
();
}
}
}
}
}
}
array
[
keyColumns
-
1
]
=
ValueLong
.
get
(
row
.
getKey
());
array
[
keyColumns
-
1
]
=
ValueLong
.
get
(
row
.
getKey
());
...
@@ -103,6 +117,19 @@ public class MVSecondaryIndex extends BaseIndex {
...
@@ -103,6 +117,19 @@ public class MVSecondaryIndex extends BaseIndex {
return
array
;
return
array
;
}
}
SearchRow
getRow
(
Value
[]
array
)
{
SearchRow
searchRow
=
mvTable
.
getTemplateRow
();
searchRow
.
setKey
((
array
[
array
.
length
-
1
]).
getLong
());
Column
[]
cols
=
getColumns
();
for
(
int
i
=
0
;
i
<
array
.
length
-
1
;
i
++)
{
Column
c
=
cols
[
i
];
int
idx
=
c
.
getColumnId
();
Value
v
=
array
[
i
];
searchRow
.
setValue
(
idx
,
v
);
}
return
searchRow
;
}
public
MVTable
getTable
()
{
public
MVTable
getTable
()
{
return
mvTable
;
return
mvTable
;
}
}
...
@@ -126,17 +153,24 @@ public class MVSecondaryIndex extends BaseIndex {
...
@@ -126,17 +153,24 @@ public class MVSecondaryIndex extends BaseIndex {
@Override
@Override
public
boolean
canGetFirstOrLast
()
{
public
boolean
canGetFirstOrLast
()
{
return
fals
e
;
return
tru
e
;
}
}
@Override
@Override
public
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
{
public
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
{
return
null
;
if
(
map
.
getSize
()
==
0
)
{
return
new
MVStoreCursor
(
session
,
Collections
.<
Value
[]>
emptyList
().
iterator
(),
null
);
}
Value
[]
key
=
first
?
map
.
firstKey
()
:
map
.
lastKey
();
ArrayList
<
Value
[]>
list
=
New
.
arrayList
();
list
.
add
(
key
);
MVStoreCursor
cursor
=
new
MVStoreCursor
(
session
,
list
.
iterator
(),
null
);
cursor
.
next
();
return
cursor
;
}
}
@Override
@Override
public
boolean
needRebuild
()
{
public
boolean
needRebuild
()
{
// TODO there should be a better way
return
map
.
getSize
()
==
0
;
return
map
.
getSize
()
==
0
;
}
}
...
@@ -151,7 +185,8 @@ public class MVSecondaryIndex extends BaseIndex {
...
@@ -151,7 +185,8 @@ public class MVSecondaryIndex extends BaseIndex {
}
}
public
long
getDiskSpaceUsed
()
{
public
long
getDiskSpaceUsed
()
{
return
0
;
// TODO
// TODO estimate disk space usage
return
0
;
}
}
@Override
@Override
...
@@ -180,7 +215,10 @@ public class MVSecondaryIndex extends BaseIndex {
...
@@ -180,7 +215,10 @@ public class MVSecondaryIndex extends BaseIndex {
@Override
@Override
public
Row
get
()
{
public
Row
get
()
{
if
(
row
==
null
)
{
if
(
row
==
null
)
{
row
=
mvTable
.
getRow
(
session
,
getSearchRow
().
getKey
());
SearchRow
r
=
getSearchRow
();
if
(
r
!=
null
)
{
row
=
mvTable
.
getRow
(
session
,
r
.
getKey
());
}
}
}
return
row
;
return
row
;
}
}
...
@@ -188,15 +226,8 @@ public class MVSecondaryIndex extends BaseIndex {
...
@@ -188,15 +226,8 @@ public class MVSecondaryIndex extends BaseIndex {
@Override
@Override
public
SearchRow
getSearchRow
()
{
public
SearchRow
getSearchRow
()
{
if
(
searchRow
==
null
)
{
if
(
searchRow
==
null
)
{
Value
[]
array
=
current
;
if
(
current
!=
null
)
{
Column
[]
cols
=
getColumns
();
searchRow
=
getRow
(
current
);
searchRow
=
mvTable
.
getTemplateRow
();
searchRow
.
setKey
((
array
[
array
.
length
-
1
]).
getLong
());
for
(
int
i
=
0
;
i
<
array
.
length
-
1
;
i
++)
{
Column
c
=
cols
[
i
];
int
idx
=
c
.
getColumnId
();
Value
v
=
array
[
i
];
searchRow
.
setValue
(
idx
,
v
);
}
}
}
}
return
searchRow
;
return
searchRow
;
...
...
h2/src/main/org/h2/mvstore/db/MVTable.java
浏览文件 @
f898ba35
...
@@ -9,6 +9,8 @@ package org.h2.mvstore.db;
...
@@ -9,6 +9,8 @@ package org.h2.mvstore.db;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.Comparator
;
import
java.util.Comparator
;
import
java.util.HashSet
;
import
java.util.Set
;
import
org.h2.api.DatabaseEventListener
;
import
org.h2.api.DatabaseEventListener
;
import
org.h2.command.ddl.CreateTableData
;
import
org.h2.command.ddl.CreateTableData
;
import
org.h2.constant.ErrorCode
;
import
org.h2.constant.ErrorCode
;
...
@@ -23,12 +25,14 @@ import org.h2.index.Index;
...
@@ -23,12 +25,14 @@ import org.h2.index.Index;
import
org.h2.index.IndexType
;
import
org.h2.index.IndexType
;
import
org.h2.index.MultiVersionIndex
;
import
org.h2.index.MultiVersionIndex
;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.message.Trace
;
import
org.h2.mvstore.MVStore
;
import
org.h2.mvstore.MVStore
;
import
org.h2.result.Row
;
import
org.h2.result.Row
;
import
org.h2.result.SortOrder
;
import
org.h2.result.SortOrder
;
import
org.h2.schema.SchemaObject
;
import
org.h2.schema.SchemaObject
;
import
org.h2.table.Column
;
import
org.h2.table.Column
;
import
org.h2.table.IndexColumn
;
import
org.h2.table.IndexColumn
;
import
org.h2.table.RegularTable
;
import
org.h2.table.Table
;
import
org.h2.table.Table
;
import
org.h2.table.TableBase
;
import
org.h2.table.TableBase
;
import
org.h2.util.MathUtils
;
import
org.h2.util.MathUtils
;
...
@@ -47,12 +51,23 @@ public class MVTable extends TableBase {
...
@@ -47,12 +51,23 @@ public class MVTable extends TableBase {
private
ArrayList
<
Index
>
indexes
=
New
.
arrayList
();
private
ArrayList
<
Index
>
indexes
=
New
.
arrayList
();
private
long
lastModificationId
;
private
long
lastModificationId
;
private
long
rowCount
;
private
long
rowCount
;
private
volatile
Session
lockExclusive
;
private
HashSet
<
Session
>
lockShared
=
New
.
hashSet
();
private
final
Trace
traceLock
;
/**
* True if one thread ever was waiting to lock this table. This is to avoid
* calling notifyAll if no session was ever waiting to lock this table. If
* set, the flag stays. In theory, it could be reset, however not sure when.
*/
private
boolean
waitForLock
;
public
MVTable
(
CreateTableData
data
,
String
storeName
,
MVStore
store
)
{
public
MVTable
(
CreateTableData
data
,
String
storeName
,
MVStore
store
)
{
super
(
data
);
super
(
data
);
this
.
storeName
=
storeName
;
this
.
storeName
=
storeName
;
this
.
store
=
store
;
this
.
store
=
store
;
this
.
hidden
=
data
.
isHidden
;
this
.
hidden
=
data
.
isHidden
;
traceLock
=
database
.
getTrace
(
Trace
.
LOCK
);
}
}
void
init
(
Session
session
)
{
void
init
(
Session
session
)
{
...
@@ -67,7 +82,227 @@ public class MVTable extends TableBase {
...
@@ -67,7 +82,227 @@ public class MVTable extends TableBase {
@Override
@Override
public
void
lock
(
Session
session
,
boolean
exclusive
,
boolean
force
)
{
public
void
lock
(
Session
session
,
boolean
exclusive
,
boolean
force
)
{
// TODO locking
int
lockMode
=
database
.
getLockMode
();
if
(
lockMode
==
Constants
.
LOCK_MODE_OFF
)
{
return
;
}
if
(!
force
&&
database
.
isMultiVersion
())
{
// MVCC: update, delete, and insert use a shared lock.
// Select doesn't lock except when using FOR UPDATE and
// the system property h2.selectForUpdateMvcc
// is not enabled
if
(
exclusive
)
{
exclusive
=
false
;
}
else
{
if
(
lockExclusive
==
null
)
{
return
;
}
}
}
if
(
lockExclusive
==
session
)
{
return
;
}
synchronized
(
database
)
{
try
{
doLock
(
session
,
lockMode
,
exclusive
);
}
finally
{
session
.
setWaitForLock
(
null
);
}
}
}
public
void
rename
(
String
newName
)
{
super
.
rename
(
newName
);
primaryIndex
.
renameTable
(
newName
);
}
private
void
doLock
(
Session
session
,
int
lockMode
,
boolean
exclusive
)
{
traceLock
(
session
,
exclusive
,
"requesting for"
);
// don't get the current time unless necessary
long
max
=
0
;
boolean
checkDeadlock
=
false
;
while
(
true
)
{
if
(
lockExclusive
==
session
)
{
return
;
}
if
(
exclusive
)
{
if
(
lockExclusive
==
null
)
{
if
(
lockShared
.
isEmpty
())
{
traceLock
(
session
,
exclusive
,
"added for"
);
session
.
addLock
(
this
);
lockExclusive
=
session
;
return
;
}
else
if
(
lockShared
.
size
()
==
1
&&
lockShared
.
contains
(
session
))
{
traceLock
(
session
,
exclusive
,
"add (upgraded) for "
);
lockExclusive
=
session
;
return
;
}
}
}
else
{
if
(
lockExclusive
==
null
)
{
if
(
lockMode
==
Constants
.
LOCK_MODE_READ_COMMITTED
)
{
if
(!
database
.
isMultiThreaded
()
&&
!
database
.
isMultiVersion
())
{
// READ_COMMITTED: a read lock is acquired,
// but released immediately after the operation
// is complete.
// When allowing only one thread, no lock is
// required.
// Row level locks work like read committed.
return
;
}
}
if
(!
lockShared
.
contains
(
session
))
{
traceLock
(
session
,
exclusive
,
"ok"
);
session
.
addLock
(
this
);
lockShared
.
add
(
session
);
}
return
;
}
}
session
.
setWaitForLock
(
this
);
if
(
checkDeadlock
)
{
ArrayList
<
Session
>
sessions
=
checkDeadlock
(
session
,
null
,
null
);
if
(
sessions
!=
null
)
{
throw
DbException
.
get
(
ErrorCode
.
DEADLOCK_1
,
getDeadlockDetails
(
sessions
));
}
}
else
{
// check for deadlocks from now on
checkDeadlock
=
true
;
}
long
now
=
System
.
currentTimeMillis
();
if
(
max
==
0
)
{
// try at least one more time
max
=
now
+
session
.
getLockTimeout
();
}
else
if
(
now
>=
max
)
{
traceLock
(
session
,
exclusive
,
"timeout after "
+
session
.
getLockTimeout
());
throw
DbException
.
get
(
ErrorCode
.
LOCK_TIMEOUT_1
,
getName
());
}
try
{
traceLock
(
session
,
exclusive
,
"waiting for"
);
if
(
database
.
getLockMode
()
==
Constants
.
LOCK_MODE_TABLE_GC
)
{
for
(
int
i
=
0
;
i
<
20
;
i
++)
{
long
free
=
Runtime
.
getRuntime
().
freeMemory
();
System
.
gc
();
long
free2
=
Runtime
.
getRuntime
().
freeMemory
();
if
(
free
==
free2
)
{
break
;
}
}
}
// don't wait too long so that deadlocks are detected early
long
sleep
=
Math
.
min
(
Constants
.
DEADLOCK_CHECK
,
max
-
now
);
if
(
sleep
==
0
)
{
sleep
=
1
;
}
waitForLock
=
true
;
database
.
wait
(
sleep
);
}
catch
(
InterruptedException
e
)
{
// ignore
}
}
}
private
static
String
getDeadlockDetails
(
ArrayList
<
Session
>
sessions
)
{
StringBuilder
buff
=
new
StringBuilder
();
for
(
Session
s
:
sessions
)
{
Table
lock
=
s
.
getWaitForLock
();
buff
.
append
(
"\nSession "
).
append
(
s
.
toString
()).
append
(
" is waiting to lock "
).
append
(
lock
.
toString
()).
append
(
" while locking "
);
int
i
=
0
;
for
(
Table
t
:
s
.
getLocks
())
{
if
(
i
++
>
0
)
{
buff
.
append
(
", "
);
}
buff
.
append
(
t
.
toString
());
if
(
t
instanceof
RegularTable
)
{
if
(((
MVTable
)
t
).
lockExclusive
==
s
)
{
buff
.
append
(
" (exclusive)"
);
}
else
{
buff
.
append
(
" (shared)"
);
}
}
}
buff
.
append
(
'.'
);
}
return
buff
.
toString
();
}
public
ArrayList
<
Session
>
checkDeadlock
(
Session
session
,
Session
clash
,
Set
<
Session
>
visited
)
{
// only one deadlock check at any given time
synchronized
(
RegularTable
.
class
)
{
if
(
clash
==
null
)
{
// verification is started
clash
=
session
;
visited
=
New
.
hashSet
();
}
else
if
(
clash
==
session
)
{
// we found a circle where this session is involved
return
New
.
arrayList
();
}
else
if
(
visited
.
contains
(
session
))
{
// we have already checked this session.
// there is a circle, but the sessions in the circle need to
// find it out themselves
return
null
;
}
visited
.
add
(
session
);
ArrayList
<
Session
>
error
=
null
;
for
(
Session
s
:
lockShared
)
{
if
(
s
==
session
)
{
// it doesn't matter if we have locked the object already
continue
;
}
Table
t
=
s
.
getWaitForLock
();
if
(
t
!=
null
)
{
error
=
t
.
checkDeadlock
(
s
,
clash
,
visited
);
if
(
error
!=
null
)
{
error
.
add
(
session
);
break
;
}
}
}
if
(
error
==
null
&&
lockExclusive
!=
null
)
{
Table
t
=
lockExclusive
.
getWaitForLock
();
if
(
t
!=
null
)
{
error
=
t
.
checkDeadlock
(
lockExclusive
,
clash
,
visited
);
if
(
error
!=
null
)
{
error
.
add
(
session
);
}
}
}
return
error
;
}
}
private
void
traceLock
(
Session
session
,
boolean
exclusive
,
String
s
)
{
if
(
traceLock
.
isDebugEnabled
())
{
traceLock
.
debug
(
"{0} {1} {2} {3}"
,
session
.
getId
(),
exclusive
?
"exclusive write lock"
:
"shared read lock"
,
s
,
getName
());
}
}
public
boolean
isLockedExclusively
()
{
return
lockExclusive
!=
null
;
}
public
void
unlock
(
Session
s
)
{
if
(
database
!=
null
)
{
traceLock
(
s
,
lockExclusive
==
s
,
"unlock"
);
if
(
lockExclusive
==
s
)
{
lockExclusive
=
null
;
}
if
(
lockShared
.
size
()
>
0
)
{
lockShared
.
remove
(
s
);
}
// TODO lock: maybe we need we fifo-queue to make sure nobody
// starves. check what other databases do
synchronized
(
database
)
{
if
(
database
.
getSessionCount
()
>
1
&&
waitForLock
)
{
database
.
notifyAll
();
}
}
}
}
}
@Override
@Override
...
@@ -96,17 +331,6 @@ public class MVTable extends TableBase {
...
@@ -96,17 +331,6 @@ public class MVTable extends TableBase {
return
true
;
return
true
;
}
}
@Override
public
void
unlock
(
Session
s
)
{
// TODO locking
}
@Override
public
boolean
isLockedExclusively
()
{
// TODO locking
return
false
;
}
@Override
@Override
public
void
close
(
Session
session
)
{
public
void
close
(
Session
session
)
{
MVTableEngine
.
closeTable
(
storeName
,
this
);
MVTableEngine
.
closeTable
(
storeName
,
this
);
...
@@ -144,6 +368,9 @@ public class MVTable extends TableBase {
...
@@ -144,6 +368,9 @@ public class MVTable extends TableBase {
// mainIndexColumn = -1;
// mainIndexColumn = -1;
// } else {
// } else {
// }
// }
if
(!
database
.
isStarting
()
&&
primaryIndex
.
getRowCount
(
session
)
!=
0
)
{
mainIndexColumn
=
-
1
;
}
if
(
mainIndexColumn
!=
-
1
)
{
if
(
mainIndexColumn
!=
-
1
)
{
primaryIndex
.
setMainIndexColumn
(
mainIndexColumn
);
primaryIndex
.
setMainIndexColumn
(
mainIndexColumn
);
index
=
new
MVDelegateIndex
(
this
,
indexId
,
index
=
new
MVDelegateIndex
(
this
,
indexId
,
...
@@ -346,7 +573,7 @@ public class MVTable extends TableBase {
...
@@ -346,7 +573,7 @@ public class MVTable extends TableBase {
@Override
@Override
public
String
getTableType
()
{
public
String
getTableType
()
{
return
Table
.
EXTERNAL_TABLE_ENGIN
E
;
return
Table
.
TABL
E
;
}
}
@Override
@Override
...
...
h2/src/main/org/h2/res/help.csv
浏览文件 @
f898ba35
...
@@ -1384,6 +1384,10 @@ Truncate a value to the required precision."
...
@@ -1384,6 +1384,10 @@ Truncate a value to the required precision."
{ USER | CURRENT_USER } ()
{ USER | CURRENT_USER } ()
","
","
Returns the name of the current user of this session."
Returns the name of the current user of this session."
"Functions (System)","VERSION","
VERSION()
","
Returns the H2 version as a String."
"System Tables","Information Schema","
"System Tables","Information Schema","
INFORMATION_SCHEMA
INFORMATION_SCHEMA
","
","
...
...
h2/src/main/org/h2/table/TableBase.java
浏览文件 @
f898ba35
...
@@ -67,7 +67,7 @@ public abstract class TableBase extends Table {
...
@@ -67,7 +67,7 @@ public abstract class TableBase extends Table {
buff
.
append
(
column
.
getCreateSQL
());
buff
.
append
(
column
.
getCreateSQL
());
}
}
buff
.
append
(
"\n)"
);
buff
.
append
(
"\n)"
);
if
(
tableEngine
!=
null
)
{
if
(
tableEngine
!=
null
&&
!
tableEngine
.
endsWith
(
getDatabase
().
getSettings
().
defaultTableEngine
)
)
{
buff
.
append
(
"\nENGINE \""
);
buff
.
append
(
"\nENGINE \""
);
buff
.
append
(
tableEngine
);
buff
.
append
(
tableEngine
);
buff
.
append
(
'\"'
);
buff
.
append
(
'\"'
);
...
...
h2/src/test/org/h2/test/TestAll.java
浏览文件 @
f898ba35
...
@@ -110,6 +110,7 @@ import org.h2.test.store.TestConcurrent;
...
@@ -110,6 +110,7 @@ import org.h2.test.store.TestConcurrent;
import
org.h2.test.store.TestDataUtils
;
import
org.h2.test.store.TestDataUtils
;
import
org.h2.test.store.TestMVStore
;
import
org.h2.test.store.TestMVStore
;
import
org.h2.test.store.TestMVRTree
;
import
org.h2.test.store.TestMVRTree
;
import
org.h2.test.store.TestMVTableEngine
;
import
org.h2.test.store.TestObjectDataType
;
import
org.h2.test.store.TestObjectDataType
;
import
org.h2.test.store.TestStreamStore
;
import
org.h2.test.store.TestStreamStore
;
import
org.h2.test.synth.TestBtreeIndex
;
import
org.h2.test.synth.TestBtreeIndex
;
...
@@ -555,23 +556,23 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
...
@@ -555,23 +556,23 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
beforeTest
();
beforeTest
();
// db
// db
new
TestScriptSimple
().
runTest
(
this
);
//
new TestScriptSimple().runTest(this);
new
TestScript
().
runTest
(
this
);
new
TestScript
().
runTest
(
this
);
new
TestAlter
().
runTest
(
this
);
new
TestAlter
().
runTest
(
this
);
new
TestAlterSchemaRename
().
runTest
(
this
);
new
TestAlterSchemaRename
().
runTest
(
this
);
new
TestAutoRecompile
().
runTest
(
this
);
new
TestAutoRecompile
().
runTest
(
this
);
new
TestBitField
().
runTest
(
this
);
new
TestBitField
().
runTest
(
this
);
new
TestBackup
().
runTest
(
this
);
//
new TestBackup().runTest(this);
new
TestBigDb
().
runTest
(
this
);
new
TestBigDb
().
runTest
(
this
);
new
TestBigResult
().
runTest
(
this
);
new
TestBigResult
().
runTest
(
this
);
new
TestCases
().
runTest
(
this
);
// new TestCases().runTest(this); // <<=
new
TestCheckpoint
().
runTest
(
this
);
new
TestCheckpoint
().
runTest
(
this
);
new
TestCluster
().
runTest
(
this
);
//
new TestCluster().runTest(this);
new
TestCompatibility
().
runTest
(
this
);
new
TestCompatibility
().
runTest
(
this
);
new
TestCsv
().
runTest
(
this
);
new
TestCsv
().
runTest
(
this
);
new
TestDateStorage
().
runTest
(
this
);
new
TestDateStorage
().
runTest
(
this
);
new
TestDeadlock
().
runTest
(
this
);
new
TestDeadlock
().
runTest
(
this
);
new
TestEncryptedDb
().
runTest
(
this
);
//
new TestEncryptedDb().runTest(this);
new
TestExclusive
().
runTest
(
this
);
new
TestExclusive
().
runTest
(
this
);
new
TestFullText
().
runTest
(
this
);
new
TestFullText
().
runTest
(
this
);
new
TestFunctionOverload
().
runTest
(
this
);
new
TestFunctionOverload
().
runTest
(
this
);
...
@@ -580,33 +581,33 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
...
@@ -580,33 +581,33 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
new
TestIndex
().
runTest
(
this
);
new
TestIndex
().
runTest
(
this
);
new
TestLargeBlob
().
runTest
(
this
);
new
TestLargeBlob
().
runTest
(
this
);
new
TestLinkedTable
().
runTest
(
this
);
new
TestLinkedTable
().
runTest
(
this
);
new
TestListener
().
runTest
(
this
);
//
new TestListener().runTest(this);
new
TestLob
().
runTest
(
this
);
//
new TestLob().runTest(this);
new
TestMemoryUsage
().
runTest
(
this
);
new
TestMemoryUsage
().
runTest
(
this
);
new
TestMultiConn
().
runTest
(
this
);
new
TestMultiConn
().
runTest
(
this
);
new
TestMultiDimension
().
runTest
(
this
);
new
TestMultiDimension
().
runTest
(
this
);
new
TestMultiThread
().
runTest
(
this
);
new
TestMultiThread
().
runTest
(
this
);
new
TestMultiThreadedKernel
().
runTest
(
this
);
new
TestMultiThreadedKernel
().
runTest
(
this
);
new
TestOpenClose
().
runTest
(
this
);
//
new TestOpenClose().runTest(this);
new
TestOptimizations
().
runTest
(
this
);
//
new TestOptimizations().runTest(this);
new
TestOutOfMemory
().
runTest
(
this
);
//
new TestOutOfMemory().runTest(this);
new
TestPowerOff
().
runTest
(
this
);
//
new TestPowerOff().runTest(this);
new
TestQueryCache
().
runTest
(
this
);
new
TestQueryCache
().
runTest
(
this
);
new
TestReadOnly
().
runTest
(
this
);
//
new TestReadOnly().runTest(this);
new
TestRecursiveQueries
().
runTest
(
this
);
new
TestRecursiveQueries
().
runTest
(
this
);
new
TestRights
().
runTest
(
this
);
new
TestRights
().
runTest
(
this
);
new
TestRunscript
().
runTest
(
this
);
//
new TestRunscript().runTest(this);
new
TestSQLInjection
().
runTest
(
this
);
new
TestSQLInjection
().
runTest
(
this
);
new
TestSessionsLocks
().
runTest
(
this
);
//
new TestSessionsLocks().runTest(this);
new
TestSelectCountNonNullColumn
().
runTest
(
this
);
new
TestSelectCountNonNullColumn
().
runTest
(
this
);
new
TestSequence
().
runTest
(
this
);
new
TestSequence
().
runTest
(
this
);
new
TestSpaceReuse
().
runTest
(
this
);
new
TestSpaceReuse
().
runTest
(
this
);
new
TestSpeed
().
runTest
(
this
);
new
TestSpeed
().
runTest
(
this
);
new
TestTableEngines
().
runTest
(
this
);
new
TestTableEngines
().
runTest
(
this
);
new
TestTempTables
().
runTest
(
this
);
new
TestTempTables
().
runTest
(
this
);
new
TestTransaction
().
runTest
(
this
);
//
new TestTransaction().runTest(this);
new
TestTriggersConstraints
().
runTest
(
this
);
new
TestTriggersConstraints
().
runTest
(
this
);
new
TestTwoPhaseCommit
().
runTest
(
this
);
//
new TestTwoPhaseCommit().runTest(this);
new
TestView
().
runTest
(
this
);
new
TestView
().
runTest
(
this
);
new
TestViewAlterTable
().
runTest
(
this
);
new
TestViewAlterTable
().
runTest
(
this
);
new
TestViewDropView
().
runTest
(
this
);
new
TestViewDropView
().
runTest
(
this
);
...
@@ -623,13 +624,13 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
...
@@ -623,13 +624,13 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
new
TestBatchUpdates
().
runTest
(
this
);
new
TestBatchUpdates
().
runTest
(
this
);
new
TestCallableStatement
().
runTest
(
this
);
new
TestCallableStatement
().
runTest
(
this
);
new
TestCancel
().
runTest
(
this
);
new
TestCancel
().
runTest
(
this
);
new
TestDatabaseEventListener
().
runTest
(
this
);
//
new TestDatabaseEventListener().runTest(this);
new
TestDriver
().
runTest
(
this
);
new
TestDriver
().
runTest
(
this
);
new
TestJavaObject
().
runTest
(
this
);
new
TestJavaObject
().
runTest
(
this
);
new
TestLimitUpdates
().
runTest
(
this
);
new
TestLimitUpdates
().
runTest
(
this
);
new
TestLobApi
().
runTest
(
this
);
new
TestLobApi
().
runTest
(
this
);
new
TestManyJdbcObjects
().
runTest
(
this
);
new
TestManyJdbcObjects
().
runTest
(
this
);
new
TestMetaData
().
runTest
(
this
);
// new TestMetaData().runTest(this); // <<=
new
TestNativeSQL
().
runTest
(
this
);
new
TestNativeSQL
().
runTest
(
this
);
new
TestPreparedStatement
().
runTest
(
this
);
new
TestPreparedStatement
().
runTest
(
this
);
new
TestResultSet
().
runTest
(
this
);
new
TestResultSet
().
runTest
(
this
);
...
@@ -642,10 +643,10 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
...
@@ -642,10 +643,10 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
new
TestConnectionPool
().
runTest
(
this
);
new
TestConnectionPool
().
runTest
(
this
);
new
TestDataSource
().
runTest
(
this
);
new
TestDataSource
().
runTest
(
this
);
new
TestXA
().
runTest
(
this
);
new
TestXA
().
runTest
(
this
);
new
TestXASimple
().
runTest
(
this
);
//
new TestXASimple().runTest(this);
// server
// server
new
TestAutoServer
().
runTest
(
this
);
//
new TestAutoServer().runTest(this);
new
TestNestedLoop
().
runTest
(
this
);
new
TestNestedLoop
().
runTest
(
this
);
new
TestWeb
().
runTest
(
this
);
new
TestWeb
().
runTest
(
this
);
...
@@ -654,7 +655,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
...
@@ -654,7 +655,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
new
TestMvcc2
().
runTest
(
this
);
new
TestMvcc2
().
runTest
(
this
);
new
TestMvcc3
().
runTest
(
this
);
new
TestMvcc3
().
runTest
(
this
);
new
TestMvccMultiThreaded
().
runTest
(
this
);
new
TestMvccMultiThreaded
().
runTest
(
this
);
new
TestRowLocks
().
runTest
(
this
);
//
new TestRowLocks().runTest(this);
// synth
// synth
new
TestBtreeIndex
().
runTest
(
this
);
new
TestBtreeIndex
().
runTest
(
this
);
...
@@ -682,6 +683,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
...
@@ -682,6 +683,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
new
TestDataUtils
().
runTest
(
this
);
new
TestDataUtils
().
runTest
(
this
);
new
TestMVRTree
().
runTest
(
this
);
new
TestMVRTree
().
runTest
(
this
);
new
TestMVStore
().
runTest
(
this
);
new
TestMVStore
().
runTest
(
this
);
new
TestMVTableEngine
().
runTest
(
this
);
new
TestObjectDataType
().
runTest
(
this
);
new
TestObjectDataType
().
runTest
(
this
);
new
TestStreamStore
().
runTest
(
this
);
new
TestStreamStore
().
runTest
(
this
);
...
...
h2/src/test/org/h2/test/TestBase.java
浏览文件 @
f898ba35
...
@@ -31,6 +31,7 @@ import java.util.LinkedList;
...
@@ -31,6 +31,7 @@ import java.util.LinkedList;
import
org.h2.jdbc.JdbcConnection
;
import
org.h2.jdbc.JdbcConnection
;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.message.TraceSystem
;
import
org.h2.message.TraceSystem
;
import
org.h2.mvstore.db.MVTableEngine
;
import
org.h2.store.FileLock
;
import
org.h2.store.FileLock
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.test.utils.ProxyCodeGenerator
;
import
org.h2.test.utils.ProxyCodeGenerator
;
...
@@ -265,6 +266,8 @@ public abstract class TestBase {
...
@@ -265,6 +266,8 @@ public abstract class TestBase {
}
else
{
}
else
{
url
=
name
;
url
=
name
;
}
}
int
test
;
url
=
addOption
(
url
,
"DEFAULT_TABLE_ENGINE"
,
MVTableEngine
.
class
.
getName
());
if
(!
config
.
memory
)
{
if
(!
config
.
memory
)
{
if
(
config
.
smallLog
&&
admin
)
{
if
(
config
.
smallLog
&&
admin
)
{
url
=
addOption
(
url
,
"MAX_LOG_SIZE"
,
"1"
);
url
=
addOption
(
url
,
"MAX_LOG_SIZE"
,
"1"
);
...
...
h2/src/test/org/h2/test/bench/test.properties
浏览文件 @
f898ba35
db1
=
H2, org.h2.Driver, jdbc:h2:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3, sa, sa
db1
=
H2, org.h2.Driver, jdbc:h2:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3, sa, sa
#xdb1 = H2, org.h2.Driver, jdbc:h2:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3;DEFAULT_TABLE_ENGINE=org.h2.mvstore.db.MVTableEngine, sa, sa
#xdb1 = H2, org.h2.Driver, jdbc:h2:data/test;LOG=1;LOCK_TIMEOUT=10000;LOCK_MODE=3;ACCESS_MODE_DATA=rwd, sa, sa
#xdb1 = H2, org.h2.Driver, jdbc:h2:data/test;LOG=1;LOCK_TIMEOUT=10000;LOCK_MODE=3;ACCESS_MODE_DATA=rwd, sa, sa
#xdb2 = H2 (nio), org.h2.Driver, jdbc:h2:nio:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3, sa, sa
#xdb2 = H2 (nio), org.h2.Driver, jdbc:h2:nio:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3, sa, sa
#xdb3 = H2 (nioMapped), org.h2.Driver, jdbc:h2:nioMapped:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3, sa, sa
#xdb3 = H2 (nioMapped), org.h2.Driver, jdbc:h2:nioMapped:data/test;LOCK_TIMEOUT=10000;LOCK_MODE=3, sa, sa
...
...
h2/src/test/org/h2/test/store/TestMVStore.java
浏览文件 @
f898ba35
...
@@ -735,16 +735,16 @@ public class TestMVStore extends TestBase {
...
@@ -735,16 +735,16 @@ public class TestMVStore extends TestBase {
assertTrue
(
m
.
containsKey
(
"chunk.1"
));
assertTrue
(
m
.
containsKey
(
"chunk.1"
));
assertFalse
(
m
.
containsKey
(
"chunk.2"
));
assertFalse
(
m
.
containsKey
(
"chunk.2"
));
assertEquals
(
"id:1,
name:data,
type:btree,createVersion:0,key:,value:"
,
assertEquals
(
"id:1,type:btree,createVersion:0,key:,value:"
,
m
.
get
(
"map.data"
));
m
.
get
(
"map.data"
));
assertTrue
(
m
.
containsKey
(
"chunk.1"
));
assertTrue
(
m
.
containsKey
(
"chunk.1"
));
assertEquals
(
"Hello"
,
data
.
put
(
"1"
,
"Hallo"
));
assertEquals
(
"Hello"
,
data
.
put
(
"1"
,
"Hallo"
));
s
.
store
();
s
.
store
();
assertEquals
(
"id:1,
name:data,
type:btree,createVersion:0,key:,value:"
,
assertEquals
(
"id:1,type:btree,createVersion:0,key:,value:"
,
m
.
get
(
"map.data"
));
m
.
get
(
"map.data"
));
assertTrue
(
m
.
get
(
"root.1"
).
length
()
>
0
);
assertTrue
(
m
.
get
(
"root.1"
).
length
()
>
0
);
assertTrue
(
m
.
containsKey
(
"chunk.1"
));
assertTrue
(
m
.
containsKey
(
"chunk.1"
));
assertEquals
(
"id:1,length:2
8
1,maxLength:288,maxLengthLive:0,"
+
assertEquals
(
"id:1,length:2
7
1,maxLength:288,maxLengthLive:0,"
+
"metaRoot:274877910924,pageCount:2,"
+
"metaRoot:274877910924,pageCount:2,"
+
"start:8192,time:0,version:1"
,
m
.
get
(
"chunk.1"
));
"start:8192,time:0,version:1"
,
m
.
get
(
"chunk.1"
));
...
...
h2/src/test/org/h2/test/store/TestMVTableEngine.java
0 → 100644
浏览文件 @
f898ba35
/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License, Version
* 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html). Initial Developer: H2 Group
*/
package
org
.
h2
.
test
.
store
;
import
java.sql.Connection
;
import
java.sql.ResultSet
;
import
java.sql.Statement
;
import
org.h2.mvstore.db.MVTableEngine
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.test.TestBase
;
/**
* Tests the MVStore in a database.
*/
public
class
TestMVTableEngine
extends
TestBase
{
/**
* Run just this test.
*
* @param a ignored
*/
public
static
void
main
(
String
...
a
)
throws
Exception
{
TestBase
.
createCaller
().
init
().
test
();
}
public
void
test
()
throws
Exception
{
// testCase();
testSimple
();
}
private
void
testCase
()
throws
Exception
{
FileUtils
.
deleteRecursive
(
getBaseDir
(),
true
);
deleteDb
(
"cases"
);
Connection
conn
=
getConnection
(
"cases"
);
Statement
stat
=
conn
.
createStatement
();
conn
=
getConnection
(
"cases"
);
stat
=
conn
.
createStatement
();
stat
.
execute
(
"set max_operation_memory 1"
);
stat
.
execute
(
"create table test(id int)"
);
stat
.
execute
(
"insert into test values(1), (2)"
);
stat
.
execute
(
"create index idx on test(id)"
);
conn
.
setAutoCommit
(
false
);
stat
.
execute
(
"update test set id = id where id=2"
);
stat
.
execute
(
"update test set id = id"
);
conn
.
rollback
();
conn
.
close
();
}
private
void
testSimple
()
throws
Exception
{
FileUtils
.
deleteRecursive
(
getBaseDir
(),
true
);
Connection
conn
=
getConnection
(
"mvstore"
);
Statement
stat
=
conn
.
createStatement
();
// create table test(id int, name varchar) engine "org.h2.mvstore.db.MVStoreTableEngine"
stat
.
execute
(
"create table test(id int primary key, name varchar) engine \""
+
MVTableEngine
.
class
.
getName
()
+
"\""
);
stat
.
execute
(
"insert into test values(1, 'Hello'), (2, 'World')"
);
ResultSet
rs
=
stat
.
executeQuery
(
"select * from test"
);
assertTrue
(
rs
.
next
());
assertEquals
(
1
,
rs
.
getInt
(
1
));
assertEquals
(
"Hello"
,
rs
.
getString
(
2
));
conn
.
close
();
conn
=
getConnection
(
"mvstore"
);
stat
=
conn
.
createStatement
();
rs
=
stat
.
executeQuery
(
"select * from test order by id"
);
assertTrue
(
rs
.
next
());
assertEquals
(
1
,
rs
.
getInt
(
1
));
assertEquals
(
"Hello"
,
rs
.
getString
(
2
));
assertTrue
(
rs
.
next
());
assertEquals
(
2
,
rs
.
getInt
(
1
));
assertEquals
(
"World"
,
rs
.
getString
(
2
));
assertFalse
(
rs
.
next
());
stat
.
execute
(
"delete from test where id = 2"
);
rs
=
stat
.
executeQuery
(
"select * from test order by id"
);
assertTrue
(
rs
.
next
());
assertEquals
(
1
,
rs
.
getInt
(
1
));
assertEquals
(
"Hello"
,
rs
.
getString
(
2
));
assertFalse
(
rs
.
next
());
stat
.
execute
(
"create index idx_name on test(name)"
);
rs
=
stat
.
executeQuery
(
"select * from test where name = 'Hello'"
);
assertTrue
(
rs
.
next
());
assertEquals
(
1
,
rs
.
getInt
(
1
));
assertEquals
(
"Hello"
,
rs
.
getString
(
2
));
assertFalse
(
rs
.
next
());
conn
.
close
();
}
}
h2/src/test/org/h2/test/test-1.3.txt
浏览文件 @
f898ba35
...
@@ -6,11 +6,13 @@ select char(nextval('seq')) as x;
...
@@ -6,11 +6,13 @@ select char(nextval('seq')) as x;
> X
> X
> -
> -
> A
> A
> rows: 1
select char(nextval('seq')) as x;
select char(nextval('seq')) as x;
> X
> X
> -
> -
> B
> B
> rows: 1
drop sequence seq;
drop sequence seq;
> ok
> ok
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论