Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
a921dc87
提交
a921dc87
authored
12月 12, 2012
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
MVStore: table engine
上级
3791fdca
全部展开
显示空白字符变更
内嵌
并排
正在显示
20 个修改的文件
包含
2002 行增加
和
15 行删除
+2002
-15
changelog.html
h2/src/docsrc/html/changelog.html
+12
-3
Parser.java
h2/src/main/org/h2/command/Parser.java
+2
-0
DropDatabase.java
h2/src/main/org/h2/command/ddl/DropDatabase.java
+5
-0
Constants.java
h2/src/main/org/h2/engine/Constants.java
+5
-0
Session.java
h2/src/main/org/h2/engine/Session.java
+8
-6
BaseIndex.java
h2/src/main/org/h2/index/BaseIndex.java
+3
-2
Index.java
h2/src/main/org/h2/index/Index.java
+1
-1
MVDelegateIndex.java
h2/src/main/org/h2/mvstore/db/MVDelegateIndex.java
+121
-0
MVPrimaryIndex.java
h2/src/main/org/h2/mvstore/db/MVPrimaryIndex.java
+276
-0
MVSecondaryIndex.java
h2/src/main/org/h2/mvstore/db/MVSecondaryIndex.java
+223
-0
MVTable.java
h2/src/main/org/h2/mvstore/db/MVTable.java
+436
-0
MVTableEngine.java
h2/src/main/org/h2/mvstore/db/MVTableEngine.java
+89
-0
ValueArrayDataType.java
h2/src/main/org/h2/mvstore/db/ValueArrayDataType.java
+751
-0
ValueDataTypeFactory.java
h2/src/main/org/h2/mvstore/db/ValueDataTypeFactory.java
+45
-0
package.html
h2/src/main/org/h2/mvstore/db/package.html
+15
-0
DbContents.java
h2/src/main/org/h2/server/web/DbContents.java
+1
-1
Data.java
h2/src/main/org/h2/store/Data.java
+1
-1
FileLister.java
h2/src/main/org/h2/store/FileLister.java
+2
-0
RegularTable.java
h2/src/main/org/h2/table/RegularTable.java
+1
-1
Recover.java
h2/src/main/org/h2/tools/Recover.java
+5
-0
没有找到文件。
h2/src/docsrc/html/changelog.html
浏览文件 @
a921dc87
...
@@ -18,14 +18,23 @@ Change Log
...
@@ -18,14 +18,23 @@ Change Log
<h1>
Change Log
</h1>
<h1>
Change Log
</h1>
<h2>
Next Version (unreleased)
</h2>
<h2>
Next Version (unreleased)
</h2>
<ul><li>
MVStore: store the file header also at the end of each chunk,
<ul><li>
New table engine "org.h2.mvstore.db.MVTableEngine"
that internally uses the MVStore to persist data.
To try it out, append ";DEFAULT_TABLE_ENGINE=org.h2.mvstore.db.MVTableEngine"
to the database URL.
This is still very experimental, and many features are not supported yet.
The data is stored in a file with the suffix ".mv.db".
</li><li>
New connection setting "DEFAULT_TABLE_ENGINE" to use a specific
table engine if none is set explicitly. This is to simplify testing
the MVStore table engine.
</li><li>
MVStore: store the file header also at the end of each chunk,
which results in a further reduced number of write operations.
which results in a further reduced number of write operations.
</li><li>
MVStore: a map implementation that supports concurrent operations.
</li><li>
MVStore: a map implementation that supports concurrent operations.
</li><li>
MVStore: unified exception handling; the version is included in the messages.
</li><li>
MVStore: unified exception handling; the version is included in the messages.
</li><li>
MVStore: old data is now retained for 45 seconds by default.
</li><li>
MVStore: old data is now retained for 45 seconds by default.
</ul><li>
MVStore: compress is now disabled by default, and can be enabled on request.
</ul><li>
MVStore: compress is now disabled by default, and can be enabled on request.
</ul><li>
Support ALTER TABLE ADD ... AFTER. Patch from Andrew Gaul
argaul@gmail.com
. Fixes issue 401.
</ul><li>
Support ALTER TABLE ADD ... AFTER. Patch from Andrew Gaul
(argaul at gmail.com)
. Fixes issue 401.
</ul><li>
support "SELECT version()". Patch from Andrew Gaul
argaul@gmail.com
. Fixes issue 406.
</ul><li>
support "SELECT version()". Patch from Andrew Gaul. Fixes issue 406.
</ul><li>
Improved OSGi support. H2 now registers itself as a DataSourceFactory service. Fixes issue 365.
</ul><li>
Improved OSGi support. H2 now registers itself as a DataSourceFactory service. Fixes issue 365.
</li></ul>
</li></ul>
...
...
h2/src/main/org/h2/command/Parser.java
浏览文件 @
a921dc87
...
@@ -5278,6 +5278,8 @@ public class Parser {
...
@@ -5278,6 +5278,8 @@ public class Parser {
}
}
if
(
readIf
(
"ENGINE"
))
{
if
(
readIf
(
"ENGINE"
))
{
command
.
setTableEngine
(
readUniqueIdentifier
());
command
.
setTableEngine
(
readUniqueIdentifier
());
}
else
if
(
database
.
getSettings
().
defaultTableEngine
!=
null
)
{
command
.
setTableEngine
(
database
.
getSettings
().
defaultTableEngine
);
}
}
if
(
temp
)
{
if
(
temp
)
{
if
(
readIf
(
"ON"
))
{
if
(
readIf
(
"ON"
))
{
...
...
h2/src/main/org/h2/command/ddl/DropDatabase.java
浏览文件 @
a921dc87
...
@@ -68,6 +68,11 @@ public class DropDatabase extends DefineCommand {
...
@@ -68,6 +68,11 @@ public class DropDatabase extends DefineCommand {
db
.
removeSchemaObject
(
session
,
t
);
db
.
removeSchemaObject
(
session
,
t
);
}
}
}
}
for
(
Table
t
:
tables
)
{
if
(
t
.
getName
()
!=
null
&&
Table
.
EXTERNAL_TABLE_ENGINE
.
equals
(
t
.
getTableType
())
&&
!
t
.
isHidden
())
{
db
.
removeSchemaObject
(
session
,
t
);
}
}
session
.
findLocalTempTable
(
null
);
session
.
findLocalTempTable
(
null
);
ArrayList
<
SchemaObject
>
list
=
New
.
arrayList
();
ArrayList
<
SchemaObject
>
list
=
New
.
arrayList
();
list
.
addAll
(
db
.
getAllSchemaObjects
(
DbObject
.
SEQUENCE
));
list
.
addAll
(
db
.
getAllSchemaObjects
(
DbObject
.
SEQUENCE
));
...
...
h2/src/main/org/h2/engine/Constants.java
浏览文件 @
a921dc87
...
@@ -423,6 +423,11 @@ public class Constants {
...
@@ -423,6 +423,11 @@ public class Constants {
*/
*/
public
static
final
String
SUFFIX_PAGE_FILE
=
".h2.db"
;
public
static
final
String
SUFFIX_PAGE_FILE
=
".h2.db"
;
/**
* The file name suffix of a MVStore file.
*/
public
static
final
String
SUFFIX_MV_FILE
=
".mv.db"
;
/**
/**
* The file name suffix of temporary files.
* The file name suffix of temporary files.
*/
*/
...
...
h2/src/main/org/h2/engine/Session.java
浏览文件 @
a921dc87
...
@@ -606,6 +606,7 @@ public class Session extends SessionWithState {
...
@@ -606,6 +606,7 @@ public class Session extends SessionWithState {
}
}
undoLog
.
add
(
log
);
undoLog
.
add
(
log
);
}
else
{
}
else
{
if
(
database
.
isMultiVersion
())
{
// see also UndoLogRecord.commit
// see also UndoLogRecord.commit
ArrayList
<
Index
>
indexes
=
table
.
getIndexes
();
ArrayList
<
Index
>
indexes
=
table
.
getIndexes
();
for
(
int
i
=
0
,
size
=
indexes
.
size
();
i
<
size
;
i
++)
{
for
(
int
i
=
0
,
size
=
indexes
.
size
();
i
<
size
;
i
++)
{
...
@@ -615,6 +616,7 @@ public class Session extends SessionWithState {
...
@@ -615,6 +616,7 @@ public class Session extends SessionWithState {
row
.
commit
();
row
.
commit
();
}
}
}
}
}
/**
/**
* Unlock all read locks. This is done if the transaction isolation mode is
* Unlock all read locks. This is done if the transaction isolation mode is
...
...
h2/src/main/org/h2/index/BaseIndex.java
浏览文件 @
a921dc87
...
@@ -72,11 +72,12 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
...
@@ -72,11 +72,12 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
}
}
/**
/**
* Create a duplicate key exception with a message that contains the index name
* Create a duplicate key exception with a message that contains the index
* name.
*
*
* @return the exception
* @return the exception
*/
*/
DbException
getDuplicateKeyException
()
{
protected
DbException
getDuplicateKeyException
()
{
String
sql
=
getName
()
+
" ON "
+
table
.
getSQL
()
+
"("
+
getColumnListSQL
()
+
")"
;
String
sql
=
getName
()
+
" ON "
+
table
.
getSQL
()
+
"("
+
getColumnListSQL
()
+
")"
;
DbException
e
=
DbException
.
get
(
ErrorCode
.
DUPLICATE_KEY_1
,
sql
);
DbException
e
=
DbException
.
get
(
ErrorCode
.
DUPLICATE_KEY_1
,
sql
);
e
.
setSource
(
this
);
e
.
setSource
(
this
);
...
...
h2/src/main/org/h2/index/Index.java
浏览文件 @
a921dc87
...
@@ -203,7 +203,7 @@ public interface Index extends SchemaObject {
...
@@ -203,7 +203,7 @@ public interface Index extends SchemaObject {
/**
/**
* Commit the operation for a row. This is only important for multi-version
* Commit the operation for a row. This is only important for multi-version
* indexes.
* indexes.
The method is only called if multi-version is enabled.
*
*
* @param operation the operation type
* @param operation the operation type
* @param row the row
* @param row the row
...
...
h2/src/main/org/h2/mvstore/db/MVDelegateIndex.java
0 → 100644
浏览文件 @
a921dc87
/*
* 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
.
mvstore
.
db
;
import
org.h2.engine.Session
;
import
org.h2.index.BaseIndex
;
import
org.h2.index.Cursor
;
import
org.h2.index.IndexType
;
import
org.h2.message.DbException
;
import
org.h2.result.Row
;
import
org.h2.result.SearchRow
;
import
org.h2.table.Column
;
import
org.h2.table.IndexColumn
;
/**
* An index that delegates indexing to another index.
*/
public
class
MVDelegateIndex
extends
BaseIndex
{
private
final
MVPrimaryIndex
mainIndex
;
public
MVDelegateIndex
(
MVTable
table
,
int
id
,
String
name
,
MVPrimaryIndex
mainIndex
,
IndexType
indexType
)
{
IndexColumn
[]
cols
=
IndexColumn
.
wrap
(
new
Column
[]
{
table
.
getColumn
(
mainIndex
.
getMainIndexColumn
())});
this
.
initBaseIndex
(
table
,
id
,
name
,
cols
,
indexType
);
this
.
mainIndex
=
mainIndex
;
if
(!
database
.
isPersistent
()
||
id
<
0
)
{
throw
DbException
.
throwInternalError
(
""
+
name
);
}
}
public
void
add
(
Session
session
,
Row
row
)
{
// nothing to do
}
public
boolean
canFindNext
()
{
return
false
;
}
public
boolean
canGetFirstOrLast
()
{
return
false
;
// TODO
// return true;
}
public
void
close
(
Session
session
)
{
// nothing to do
}
public
Cursor
find
(
Session
session
,
SearchRow
first
,
SearchRow
last
)
{
long
min
=
mainIndex
.
getKey
(
first
,
Long
.
MIN_VALUE
,
Long
.
MIN_VALUE
);
// ifNull is MIN_VALUE as well, because the column is never NULL
// so avoid returning all rows (returning one row is OK)
long
max
=
mainIndex
.
getKey
(
last
,
Long
.
MAX_VALUE
,
Long
.
MIN_VALUE
);
return
mainIndex
.
find
(
session
,
min
,
max
);
}
public
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
{
return
null
;
// 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
)
{
throw
DbException
.
throwInternalError
();
}
public
int
getColumnIndex
(
Column
col
)
{
if
(
col
.
getColumnId
()
==
mainIndex
.
getMainIndexColumn
())
{
return
0
;
}
return
-
1
;
}
public
double
getCost
(
Session
session
,
int
[]
masks
)
{
return
10
*
getCostRangeIndex
(
masks
,
mainIndex
.
getRowCount
(
session
));
}
public
boolean
needRebuild
()
{
return
false
;
}
public
void
remove
(
Session
session
,
Row
row
)
{
// nothing to do
}
public
void
remove
(
Session
session
)
{
mainIndex
.
setMainIndexColumn
(-
1
);
// TODO remove map?
// session.getDatabase().getPageStore().removeMeta(this, session);
}
public
void
truncate
(
Session
session
)
{
// nothing to do
}
public
void
checkRename
()
{
// ok
}
public
long
getRowCount
(
Session
session
)
{
return
mainIndex
.
getRowCount
(
session
);
}
public
long
getRowCountApproximation
()
{
return
mainIndex
.
getRowCountApproximation
();
}
}
h2/src/main/org/h2/mvstore/db/MVPrimaryIndex.java
0 → 100644
浏览文件 @
a921dc87
/*
* 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
.
mvstore
.
db
;
import
java.util.Iterator
;
import
org.h2.constant.ErrorCode
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Database
;
import
org.h2.engine.Session
;
import
org.h2.index.BaseIndex
;
import
org.h2.index.Cursor
;
import
org.h2.index.IndexType
;
import
org.h2.message.DbException
;
import
org.h2.mvstore.MVMap
;
import
org.h2.mvstore.type.ObjectDataType
;
import
org.h2.result.Row
;
import
org.h2.result.SearchRow
;
import
org.h2.result.SortOrder
;
import
org.h2.table.IndexColumn
;
import
org.h2.value.Value
;
import
org.h2.value.ValueNull
;
/**
* A table stored in a MVStore.
*/
public
class
MVPrimaryIndex
extends
BaseIndex
{
protected
final
MVTable
mvTable
;
protected
MVMap
<
Long
,
Value
[]>
map
;
private
long
nextKey
;
private
int
mainIndexColumn
=
-
1
;
public
MVPrimaryIndex
(
Database
db
,
MVTable
table
,
int
id
,
IndexColumn
[]
columns
,
IndexType
indexType
)
{
this
.
mvTable
=
table
;
initBaseIndex
(
table
,
id
,
table
.
getName
()
+
"_DATA"
,
columns
,
indexType
);
int
[]
sortTypes
=
new
int
[
columns
.
length
];
for
(
int
i
=
0
;
i
<
columns
.
length
;
i
++)
{
sortTypes
[
i
]
=
SortOrder
.
ASCENDING
;
}
ValueArrayDataType
t
=
new
ValueArrayDataType
(
db
.
getCompareMode
(),
db
,
sortTypes
);
map
=
new
MVMap
<
Long
,
Value
[]>(
new
ObjectDataType
(),
t
);
map
=
table
.
getStore
().
openMap
(
getName
(),
map
);
Long
k
=
map
.
lastKey
();
nextKey
=
k
==
null
?
0
:
k
+
1
;
}
public
String
getCreateSQL
()
{
return
null
;
}
public
String
getPlanSQL
()
{
return
table
.
getSQL
()
+
".tableScan"
;
}
public
void
setMainIndexColumn
(
int
mainIndexColumn
)
{
this
.
mainIndexColumn
=
mainIndexColumn
;
}
public
int
getMainIndexColumn
()
{
return
mainIndexColumn
;
}
@Override
public
void
close
(
Session
session
)
{
// ok
}
@Override
public
void
add
(
Session
session
,
Row
row
)
{
if
(
mainIndexColumn
==
-
1
)
{
row
.
setKey
(
nextKey
++);
}
else
{
Long
c
=
row
.
getValue
(
mainIndexColumn
).
getLong
();
row
.
setKey
(
c
);
}
Value
[]
array
=
new
Value
[
columns
.
length
];
for
(
int
i
=
0
;
i
<
array
.
length
;
i
++)
{
array
[
i
]
=
row
.
getValue
(
i
);
}
if
(
map
.
containsKey
(
row
.
getKey
()))
{
String
sql
=
"PRIMARY KEY ON "
+
table
.
getSQL
();
if
(
mainIndexColumn
>=
0
&&
mainIndexColumn
<
indexColumns
.
length
)
{
sql
+=
"("
+
indexColumns
[
mainIndexColumn
].
getSQL
()
+
")"
;
}
DbException
e
=
DbException
.
get
(
ErrorCode
.
DUPLICATE_KEY_1
,
sql
);
e
.
setSource
(
this
);
throw
e
;
}
map
.
put
(
row
.
getKey
(),
array
);
}
@Override
public
void
remove
(
Session
session
,
Row
row
)
{
Value
[]
old
=
map
.
remove
(
row
.
getKey
());
if
(
old
==
null
)
{
throw
DbException
.
get
(
ErrorCode
.
ROW_NOT_FOUND_WHEN_DELETING_1
,
getSQL
()
+
": "
+
row
.
getKey
());
}
}
@Override
public
Cursor
find
(
Session
session
,
SearchRow
first
,
SearchRow
last
)
{
long
min
,
max
;
if
(
first
==
null
||
mainIndexColumn
<
0
)
{
min
=
Long
.
MIN_VALUE
;
}
else
{
Value
v
=
first
.
getValue
(
mainIndexColumn
);
if
(
v
==
null
)
{
min
=
0
;
}
else
{
min
=
v
.
getLong
();
}
}
if
(
last
==
null
||
mainIndexColumn
<
0
)
{
max
=
Long
.
MAX_VALUE
;
}
else
{
Value
v
=
last
.
getValue
(
mainIndexColumn
);
if
(
v
==
null
)
{
max
=
Long
.
MAX_VALUE
;
}
else
{
max
=
v
.
getLong
();
}
}
return
new
MVStoreCursor
(
session
,
map
.
keyIterator
(
min
),
max
);
}
public
MVTable
getTable
()
{
return
mvTable
;
}
public
Row
getRow
(
Session
session
,
long
key
)
{
Value
[]
array
=
map
.
get
(
key
);
Row
row
=
new
Row
(
array
,
0
);
row
.
setKey
(
key
);
return
row
;
}
@Override
public
double
getCost
(
Session
session
,
int
[]
masks
)
{
long
cost
=
10
*
(
map
.
getSize
()
+
Constants
.
COST_ROW_OFFSET
);
return
cost
;
}
@Override
public
void
remove
(
Session
session
)
{
if
(!
map
.
isClosed
())
{
map
.
removeMap
();
}
}
@Override
public
void
truncate
(
Session
session
)
{
map
.
clear
();
}
@Override
public
boolean
canGetFirstOrLast
()
{
return
false
;
}
@Override
public
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
{
// return first ? map.firstKey() : map.lastKey();
// TODO get first / last
return
null
;
}
@Override
public
boolean
needRebuild
()
{
// TODO Auto-generated method stub
return
false
;
}
@Override
public
long
getRowCount
(
Session
session
)
{
return
map
.
getSize
();
}
@Override
public
long
getRowCountApproximation
()
{
return
map
.
getSize
();
}
@Override
public
void
checkRename
()
{
// ok
}
/**
* Get the key from the row.
*
* @param row the row
* @param ifEmpty the value to use if the row is empty
* @param ifNull the value to use if the column is NULL
* @return the key
*/
long
getKey
(
SearchRow
row
,
long
ifEmpty
,
long
ifNull
)
{
if
(
row
==
null
)
{
return
ifEmpty
;
}
Value
v
=
row
.
getValue
(
mainIndexColumn
);
if
(
v
==
null
)
{
throw
DbException
.
throwInternalError
(
row
.
toString
());
}
else
if
(
v
==
ValueNull
.
INSTANCE
)
{
return
ifNull
;
}
return
v
.
getLong
();
}
/**
* Search for a specific row or a set of rows.
*
* @param session the session
* @param first the key of the first row
* @param last the key of the last row
* @return the cursor
*/
Cursor
find
(
Session
session
,
long
first
,
long
last
)
{
return
new
MVStoreCursor
(
session
,
map
.
keyIterator
(
first
),
last
);
}
/**
* A cursor.
*/
class
MVStoreCursor
implements
Cursor
{
private
final
Session
session
;
private
final
Iterator
<
Long
>
it
;
private
final
long
last
;
private
Long
current
;
private
Row
row
;
public
MVStoreCursor
(
Session
session
,
Iterator
<
Long
>
it
,
long
last
)
{
this
.
session
=
session
;
this
.
it
=
it
;
this
.
last
=
last
;
}
@Override
public
Row
get
()
{
if
(
row
==
null
)
{
row
=
getRow
(
session
,
current
);
}
return
row
;
}
@Override
public
SearchRow
getSearchRow
()
{
return
get
();
}
@Override
public
boolean
next
()
{
current
=
it
.
next
();
if
(
current
!=
null
&&
current
>
last
)
{
current
=
null
;
}
row
=
null
;
return
current
!=
null
;
}
@Override
public
boolean
previous
()
{
// TODO previous
return
false
;
}
}
}
h2/src/main/org/h2/mvstore/db/MVSecondaryIndex.java
0 → 100644
浏览文件 @
a921dc87
/*
* 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
.
mvstore
.
db
;
import
java.util.Iterator
;
import
org.h2.constant.ErrorCode
;
import
org.h2.engine.Database
;
import
org.h2.engine.Session
;
import
org.h2.index.BaseIndex
;
import
org.h2.index.Cursor
;
import
org.h2.index.IndexType
;
import
org.h2.message.DbException
;
import
org.h2.mvstore.MVMap
;
import
org.h2.mvstore.type.ObjectDataType
;
import
org.h2.result.Row
;
import
org.h2.result.SearchRow
;
import
org.h2.result.SortOrder
;
import
org.h2.table.Column
;
import
org.h2.table.IndexColumn
;
import
org.h2.value.Value
;
import
org.h2.value.ValueLong
;
/**
* A table stored in a MVStore.
*/
public
class
MVSecondaryIndex
extends
BaseIndex
{
protected
final
MVTable
mvTable
;
protected
final
int
keyColumns
;
protected
MVMap
<
Value
[],
Long
>
map
;
public
MVSecondaryIndex
(
Database
db
,
MVTable
table
,
int
id
,
String
indexName
,
IndexColumn
[]
columns
,
IndexType
indexType
)
{
this
.
mvTable
=
table
;
initBaseIndex
(
table
,
id
,
indexName
,
columns
,
indexType
);
// always store the row key in the map key,
// even for unique indexes, as some of the index columns could be null
keyColumns
=
columns
.
length
+
1
;
int
[]
sortTypes
=
new
int
[
keyColumns
];
for
(
int
i
=
0
;
i
<
columns
.
length
;
i
++)
{
sortTypes
[
i
]
=
columns
[
i
].
sortType
;
}
sortTypes
[
keyColumns
-
1
]
=
SortOrder
.
ASCENDING
;
ValueArrayDataType
t
=
new
ValueArrayDataType
(
db
.
getCompareMode
(),
db
,
sortTypes
);
map
=
new
MVMap
<
Value
[],
Long
>(
t
,
new
ObjectDataType
());
map
=
table
.
getStore
().
openMap
(
getName
(),
map
);
}
@Override
public
void
close
(
Session
session
)
{
// ok
}
@Override
public
void
add
(
Session
session
,
Row
row
)
{
Value
[]
array
=
getKey
(
row
);
if
(
indexType
.
isUnique
())
{
array
[
keyColumns
-
1
]
=
ValueLong
.
get
(
0
);
if
(
map
.
containsKey
(
array
))
{
throw
getDuplicateKeyException
();
}
}
array
[
keyColumns
-
1
]
=
ValueLong
.
get
(
row
.
getKey
());
map
.
put
(
array
,
Long
.
valueOf
(
0
));
}
@Override
public
void
remove
(
Session
session
,
Row
row
)
{
Value
[]
array
=
getKey
(
row
);
Long
old
=
map
.
remove
(
array
);
if
(
old
==
null
)
{
if
(
old
==
null
)
{
throw
DbException
.
get
(
ErrorCode
.
ROW_NOT_FOUND_WHEN_DELETING_1
,
getSQL
()
+
": "
+
row
.
getKey
());
}
}
}
@Override
public
Cursor
find
(
Session
session
,
SearchRow
first
,
SearchRow
last
)
{
Value
[]
min
=
getKey
(
first
);
return
new
MVStoreCursor
(
session
,
map
.
keyIterator
(
min
),
last
);
}
private
Value
[]
getKey
(
SearchRow
r
)
{
if
(
r
==
null
)
{
return
null
;
}
Value
[]
array
=
new
Value
[
keyColumns
];
for
(
int
i
=
0
;
i
<
columns
.
length
;
i
++)
{
Column
c
=
columns
[
i
];
int
idx
=
c
.
getColumnId
();
if
(
r
!=
null
)
{
array
[
i
]
=
r
.
getValue
(
idx
);
}
}
array
[
keyColumns
-
1
]
=
ValueLong
.
get
(
r
.
getKey
());
return
array
;
}
public
MVTable
getTable
()
{
return
mvTable
;
}
@Override
public
double
getCost
(
Session
session
,
int
[]
masks
)
{
return
10
*
getCostRangeIndex
(
masks
,
map
.
getSize
());
}
@Override
public
void
remove
(
Session
session
)
{
if
(!
map
.
isClosed
())
{
map
.
removeMap
();
}
}
@Override
public
void
truncate
(
Session
session
)
{
map
.
clear
();
}
@Override
public
boolean
canGetFirstOrLast
()
{
return
false
;
}
@Override
public
Cursor
findFirstOrLast
(
Session
session
,
boolean
first
)
{
return
null
;
}
@Override
public
boolean
needRebuild
()
{
// TODO there should be a better way
return
map
.
getSize
()
==
0
;
}
@Override
public
long
getRowCount
(
Session
session
)
{
return
map
.
getSize
();
}
@Override
public
long
getRowCountApproximation
()
{
return
map
.
getSize
();
}
@Override
public
void
checkRename
()
{
// ok
}
/**
* A cursor.
*/
class
MVStoreCursor
implements
Cursor
{
private
final
Session
session
;
private
final
Iterator
<
Value
[]>
it
;
private
final
SearchRow
last
;
private
Value
[]
current
;
private
SearchRow
searchRow
;
private
Row
row
;
public
MVStoreCursor
(
Session
session
,
Iterator
<
Value
[]>
it
,
SearchRow
last
)
{
this
.
session
=
session
;
this
.
it
=
it
;
this
.
last
=
last
;
}
@Override
public
Row
get
()
{
if
(
row
==
null
)
{
row
=
mvTable
.
getRow
(
session
,
getSearchRow
().
getKey
());
}
return
row
;
}
@Override
public
SearchRow
getSearchRow
()
{
if
(
searchRow
==
null
)
{
Value
[]
array
=
current
;
Column
[]
cols
=
getColumns
();
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
;
}
@Override
public
boolean
next
()
{
current
=
it
.
next
();
searchRow
=
null
;
if
(
current
!=
null
)
{
if
(
last
!=
null
&&
compareRows
(
getSearchRow
(),
last
)
>
0
)
{
searchRow
=
null
;
current
=
null
;
}
}
row
=
null
;
return
current
!=
null
;
}
@Override
public
boolean
previous
()
{
// TODO previous
return
false
;
}
}
}
h2/src/main/org/h2/mvstore/db/MVTable.java
0 → 100644
浏览文件 @
a921dc87
差异被折叠。
点击展开。
h2/src/main/org/h2/mvstore/db/MVTableEngine.java
0 → 100644
浏览文件 @
a921dc87
/*
* 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
.
mvstore
.
db
;
import
java.util.ArrayList
;
import
java.util.Map
;
import
java.util.WeakHashMap
;
import
org.h2.api.TableEngine
;
import
org.h2.command.ddl.CreateTableData
;
import
org.h2.constant.ErrorCode
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Database
;
import
org.h2.message.DbException
;
import
org.h2.mvstore.MVStore
;
import
org.h2.mvstore.MVStoreBuilder
;
import
org.h2.mvstore.type.DataTypeFactory
;
import
org.h2.table.TableBase
;
import
org.h2.upgrade.v1_1.util.New
;
/**
* A table engine that internally uses the MVStore.
*/
public
class
MVTableEngine
implements
TableEngine
{
static
final
Map
<
String
,
Store
>
STORES
=
new
WeakHashMap
<
String
,
Store
>();
@Override
public
TableBase
createTable
(
CreateTableData
data
)
{
Database
db
=
data
.
session
.
getDatabase
();
String
storeName
=
db
.
getDatabasePath
();
MVStoreBuilder
storeBuilder
;
Store
store
;
DataTypeFactory
f
=
new
ValueDataTypeFactory
(
db
.
getCompareMode
(),
db
);
if
(
storeName
==
null
)
{
storeBuilder
=
MVStoreBuilder
.
inMemory
();
storeBuilder
.
with
(
f
);
store
=
new
Store
(
db
,
storeBuilder
.
open
());
}
else
{
synchronized
(
STORES
)
{
store
=
STORES
.
get
(
storeName
);
if
(
store
==
null
)
{
storeBuilder
=
MVStoreBuilder
.
fileBased
(
storeName
+
Constants
.
SUFFIX_MV_FILE
);
storeBuilder
.
with
(
f
);
store
=
new
Store
(
db
,
storeBuilder
.
open
());
STORES
.
put
(
storeName
,
store
);
}
else
if
(
store
.
db
!=
db
)
{
throw
DbException
.
get
(
ErrorCode
.
DATABASE_ALREADY_OPEN_1
,
storeName
);
}
}
}
MVTable
table
=
new
MVTable
(
data
,
storeName
,
store
.
store
);
store
.
openTables
.
add
(
table
);
table
.
init
(
data
.
session
);
return
table
;
}
static
void
closeTable
(
String
storeName
,
MVTable
table
)
{
synchronized
(
STORES
)
{
Store
store
=
STORES
.
get
(
storeName
);
store
.
openTables
.
remove
(
table
);
if
(
store
.
openTables
.
size
()
==
0
)
{
store
.
store
.
store
();
store
.
store
.
close
();
STORES
.
remove
(
storeName
);
}
}
}
/**
* A store with open tables.
*/
static
class
Store
{
final
Database
db
;
final
MVStore
store
;
final
ArrayList
<
MVTable
>
openTables
=
New
.
arrayList
();
public
Store
(
Database
db
,
MVStore
store
)
{
this
.
db
=
db
;
this
.
store
=
store
;
}
}
}
h2/src/main/org/h2/mvstore/db/ValueArrayDataType.java
0 → 100644
浏览文件 @
a921dc87
差异被折叠。
点击展开。
h2/src/main/org/h2/mvstore/db/ValueDataTypeFactory.java
0 → 100644
浏览文件 @
a921dc87
/*
* 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
.
mvstore
.
db
;
import
org.h2.mvstore.type.DataType
;
import
org.h2.mvstore.type.DataTypeFactory
;
import
org.h2.store.DataHandler
;
import
org.h2.value.CompareMode
;
/**
* A data type factory for rows.
*/
public
class
ValueDataTypeFactory
implements
DataTypeFactory
{
private
final
CompareMode
compareMode
;
private
final
DataHandler
handler
;
private
DataTypeFactory
parent
;
ValueDataTypeFactory
(
CompareMode
compareMode
,
DataHandler
handler
)
{
this
.
compareMode
=
compareMode
;
this
.
handler
=
handler
;
}
@Override
public
void
setParent
(
DataTypeFactory
parent
)
{
this
.
parent
=
parent
;
}
@Override
public
DataType
buildDataType
(
String
s
)
{
if
(
s
.
startsWith
(
ValueArrayDataType
.
PREFIX
))
{
return
ValueArrayDataType
.
fromString
(
compareMode
,
handler
,
s
);
}
return
parent
.
buildDataType
(
s
);
}
@Override
public
String
getDataType
(
Class
<?>
objectClass
)
{
return
parent
.
getDataType
(
objectClass
);
}
}
h2/src/main/org/h2/mvstore/db/package.html
0 → 100644
浏览文件 @
a921dc87
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!--
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
-->
<html
xmlns=
"http://www.w3.org/1999/xhtml"
lang=
"en"
xml:lang=
"en"
>
<head><meta
http-equiv=
"Content-Type"
content=
"text/html;charset=utf-8"
/><title>
Javadoc package documentation
</title></head><body
style=
"font: 9pt/130% Tahoma, Arial, Helvetica, sans-serif; font-weight: normal;"
><p>
Helper classes to use the MVStore in the H2 database.
</p></body></html>
\ No newline at end of file
h2/src/main/org/h2/server/web/DbContents.java
浏览文件 @
a921dc87
...
@@ -137,7 +137,7 @@ public class DbContents {
...
@@ -137,7 +137,7 @@ public class DbContents {
}
}
schemas
[
i
]
=
schema
;
schemas
[
i
]
=
schema
;
String
[]
tableTypes
=
{
"TABLE"
,
"SYSTEM TABLE"
,
"VIEW"
,
"SYSTEM VIEW"
,
String
[]
tableTypes
=
{
"TABLE"
,
"SYSTEM TABLE"
,
"VIEW"
,
"SYSTEM VIEW"
,
"TABLE LINK"
,
"SYNONYM"
};
"TABLE LINK"
,
"SYNONYM"
,
"EXTERNAL"
};
schema
.
readTables
(
meta
,
tableTypes
);
schema
.
readTables
(
meta
,
tableTypes
);
}
}
if
(
defaultSchema
==
null
)
{
if
(
defaultSchema
==
null
)
{
...
...
h2/src/main/org/h2/store/Data.java
浏览文件 @
a921dc87
...
@@ -873,7 +873,7 @@ public class Data {
...
@@ -873,7 +873,7 @@ public class Data {
* @param handler the data handler for lobs
* @param handler the data handler for lobs
* @return the number of bytes required to store this value
* @return the number of bytes required to store this value
*/
*/
p
rivate
static
int
getValueLen
(
Value
v
,
DataHandler
handler
)
{
p
ublic
static
int
getValueLen
(
Value
v
,
DataHandler
handler
)
{
if
(
v
==
ValueNull
.
INSTANCE
)
{
if
(
v
==
ValueNull
.
INSTANCE
)
{
return
1
;
return
1
;
}
}
...
...
h2/src/main/org/h2/store/FileLister.java
浏览文件 @
a921dc87
...
@@ -86,6 +86,8 @@ public class FileLister {
...
@@ -86,6 +86,8 @@ public class FileLister {
ok
=
true
;
ok
=
true
;
}
else
if
(
f
.
endsWith
(
Constants
.
SUFFIX_PAGE_FILE
))
{
}
else
if
(
f
.
endsWith
(
Constants
.
SUFFIX_PAGE_FILE
))
{
ok
=
true
;
ok
=
true
;
}
else
if
(
f
.
endsWith
(
Constants
.
SUFFIX_MV_FILE
))
{
ok
=
true
;
}
else
if
(
all
)
{
}
else
if
(
all
)
{
if
(
f
.
endsWith
(
Constants
.
SUFFIX_LOCK_FILE
))
{
if
(
f
.
endsWith
(
Constants
.
SUFFIX_LOCK_FILE
))
{
ok
=
true
;
ok
=
true
;
...
...
h2/src/main/org/h2/table/RegularTable.java
浏览文件 @
a921dc87
...
@@ -111,11 +111,11 @@ public class RegularTable extends TableBase {
...
@@ -111,11 +111,11 @@ public class RegularTable extends TableBase {
}
}
public
void
addRow
(
Session
session
,
Row
row
)
{
public
void
addRow
(
Session
session
,
Row
row
)
{
int
i
=
0
;
lastModificationId
=
database
.
getNextModificationDataId
();
lastModificationId
=
database
.
getNextModificationDataId
();
if
(
database
.
isMultiVersion
())
{
if
(
database
.
isMultiVersion
())
{
row
.
setSessionId
(
session
.
getId
());
row
.
setSessionId
(
session
.
getId
());
}
}
int
i
=
0
;
try
{
try
{
for
(
int
size
=
indexes
.
size
();
i
<
size
;
i
++)
{
for
(
int
size
=
indexes
.
size
();
i
<
size
;
i
++)
{
Index
index
=
indexes
.
get
(
i
);
Index
index
=
indexes
.
get
(
i
);
...
...
h2/src/main/org/h2/tools/Recover.java
浏览文件 @
a921dc87
...
@@ -28,6 +28,7 @@ import org.h2.engine.DbObject;
...
@@ -28,6 +28,7 @@ import org.h2.engine.DbObject;
import
org.h2.engine.MetaRecord
;
import
org.h2.engine.MetaRecord
;
import
org.h2.jdbc.JdbcConnection
;
import
org.h2.jdbc.JdbcConnection
;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.mvstore.MVStoreTool
;
import
org.h2.result.Row
;
import
org.h2.result.Row
;
import
org.h2.result.SimpleRow
;
import
org.h2.result.SimpleRow
;
import
org.h2.security.SHA256
;
import
org.h2.security.SHA256
;
...
@@ -241,6 +242,10 @@ public class Recover extends Tool implements DataHandler {
...
@@ -241,6 +242,10 @@ public class Recover extends Tool implements DataHandler {
dumpPageStore
(
fileName
);
dumpPageStore
(
fileName
);
}
else
if
(
fileName
.
endsWith
(
Constants
.
SUFFIX_LOB_FILE
))
{
}
else
if
(
fileName
.
endsWith
(
Constants
.
SUFFIX_LOB_FILE
))
{
dumpLob
(
fileName
,
false
);
dumpLob
(
fileName
,
false
);
}
else
if
(
fileName
.
endsWith
(
Constants
.
SUFFIX_MV_FILE
))
{
PrintWriter
writer
=
getWriter
(
fileName
,
".mv.txt"
);
MVStoreTool
.
dump
(
fileName
,
writer
);
writer
.
close
();
}
}
}
}
}
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论