Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
769193eb
提交
769193eb
authored
7月 10, 2013
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
MVStore: error codes; fix MVRTreeMap iterators
上级
aed6260d
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
10 个修改的文件
包含
452 行增加
和
121 行删除
+452
-121
Chunk.java
h2/src/main/org/h2/mvstore/Chunk.java
+1
-0
Cursor.java
h2/src/main/org/h2/mvstore/Cursor.java
+15
-15
DataUtils.java
h2/src/main/org/h2/mvstore/DataUtils.java
+93
-9
FreeSpaceList.java
h2/src/main/org/h2/mvstore/FreeSpaceList.java
+4
-0
MVMap.java
h2/src/main/org/h2/mvstore/MVMap.java
+4
-3
MVStore.java
h2/src/main/org/h2/mvstore/MVStore.java
+69
-24
Page.java
h2/src/main/org/h2/mvstore/Page.java
+8
-2
MVTableEngine.java
h2/src/main/org/h2/mvstore/db/MVTableEngine.java
+49
-9
TransactionStore.java
h2/src/main/org/h2/mvstore/db/TransactionStore.java
+9
-4
MVRTreeMap.java
h2/src/main/org/h2/mvstore/rtree/MVRTreeMap.java
+200
-55
没有找到文件。
h2/src/main/org/h2/mvstore/Chunk.java
浏览文件 @
769193eb
...
@@ -95,6 +95,7 @@ public class Chunk {
...
@@ -95,6 +95,7 @@ public class Chunk {
static
Chunk
fromHeader
(
ByteBuffer
buff
,
long
start
)
{
static
Chunk
fromHeader
(
ByteBuffer
buff
,
long
start
)
{
if
(
buff
.
get
()
!=
'c'
)
{
if
(
buff
.
get
()
!=
'c'
)
{
throw
DataUtils
.
newIllegalStateException
(
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_FILE_CORRUPT
,
"File corrupt reading chunk at position {0}"
,
start
);
"File corrupt reading chunk at position {0}"
,
start
);
}
}
int
length
=
buff
.
getInt
();
int
length
=
buff
.
getInt
();
...
...
h2/src/main/org/h2/mvstore/Cursor.java
浏览文件 @
769193eb
...
@@ -15,27 +15,19 @@ import java.util.Iterator;
...
@@ -15,27 +15,19 @@ import java.util.Iterator;
*/
*/
public
class
Cursor
<
K
>
implements
Iterator
<
K
>
{
public
class
Cursor
<
K
>
implements
Iterator
<
K
>
{
pr
otected
final
MVMap
<
K
,
?>
map
;
pr
ivate
final
MVMap
<
K
,
?>
map
;
pr
otected
final
K
from
;
pr
ivate
final
K
from
;
pr
otected
CursorPos
pos
;
pr
ivate
CursorPos
pos
;
pr
otected
K
current
;
pr
ivate
K
current
;
private
final
Page
root
;
private
final
Page
root
;
private
boolean
initialized
;
private
boolean
initialized
;
protected
Cursor
(
MVMap
<
K
,
?>
map
,
Page
root
,
K
from
)
{
Cursor
(
MVMap
<
K
,
?>
map
,
Page
root
,
K
from
)
{
this
.
map
=
map
;
this
.
map
=
map
;
this
.
root
=
root
;
this
.
root
=
root
;
this
.
from
=
from
;
this
.
from
=
from
;
}
}
@Override
public
K
next
()
{
hasNext
();
K
c
=
current
;
fetchNext
();
return
c
;
}
@Override
@Override
public
boolean
hasNext
()
{
public
boolean
hasNext
()
{
if
(!
initialized
)
{
if
(!
initialized
)
{
...
@@ -46,6 +38,14 @@ public class Cursor<K> implements Iterator<K> {
...
@@ -46,6 +38,14 @@ public class Cursor<K> implements Iterator<K> {
return
current
!=
null
;
return
current
!=
null
;
}
}
@Override
public
K
next
()
{
hasNext
();
K
c
=
current
;
fetchNext
();
return
c
;
}
/**
/**
* Skip over that many entries. This method is relatively fast (for this map
* Skip over that many entries. This method is relatively fast (for this map
* implementation) even if many entries need to be skipped.
* implementation) even if many entries need to be skipped.
...
@@ -82,7 +82,7 @@ public class Cursor<K> implements Iterator<K> {
...
@@ -82,7 +82,7 @@ public class Cursor<K> implements Iterator<K> {
* @param p the page to start
* @param p the page to start
* @param from the key to search
* @param from the key to search
*/
*/
pr
otected
void
min
(
Page
p
,
K
from
)
{
pr
ivate
void
min
(
Page
p
,
K
from
)
{
while
(
true
)
{
while
(
true
)
{
if
(
p
.
isLeaf
())
{
if
(
p
.
isLeaf
())
{
int
x
=
from
==
null
?
0
:
p
.
binarySearch
(
from
);
int
x
=
from
==
null
?
0
:
p
.
binarySearch
(
from
);
...
@@ -107,7 +107,7 @@ public class Cursor<K> implements Iterator<K> {
...
@@ -107,7 +107,7 @@ public class Cursor<K> implements Iterator<K> {
* Fetch the next entry if there is one.
* Fetch the next entry if there is one.
*/
*/
@SuppressWarnings
(
"unchecked"
)
@SuppressWarnings
(
"unchecked"
)
pr
otected
void
fetchNext
()
{
pr
ivate
void
fetchNext
()
{
while
(
pos
!=
null
)
{
while
(
pos
!=
null
)
{
if
(
pos
.
index
<
pos
.
page
.
getKeyCount
())
{
if
(
pos
.
index
<
pos
.
page
.
getKeyCount
())
{
current
=
(
K
)
pos
.
page
.
getKey
(
pos
.
index
++);
current
=
(
K
)
pos
.
page
.
getKey
(
pos
.
index
++);
...
...
h2/src/main/org/h2/mvstore/DataUtils.java
浏览文件 @
769193eb
...
@@ -24,6 +24,57 @@ import org.h2.util.New;
...
@@ -24,6 +24,57 @@ import org.h2.util.New;
*/
*/
public
class
DataUtils
{
public
class
DataUtils
{
/**
* An error occurred while reading from the file.
*/
public
static
final
int
ERROR_READING_FAILED
=
1
;
/**
* An error occurred when trying to write to the file.
*/
public
static
final
int
ERROR_WRITING_FAILED
=
2
;
/**
* An internal error occurred. This could be a bug, or a memory corruption
* (for example caused by out of memory).
*/
public
static
final
int
ERROR_INTERNAL
=
3
;
/**
* The object is already closed.
*/
public
static
final
int
ERROR_CLOSED
=
4
;
/**
* The file format is not supported.
*/
public
static
final
int
ERROR_UNSUPPORTED_FORMAT
=
5
;
/**
* The file is corrupt or (for encrypted files) the encryption key is wrong.
*/
public
static
final
int
ERROR_FILE_CORRUPT
=
6
;
/**
* The file is locked.
*/
public
static
final
int
ERROR_FILE_LOCKED
=
7
;
/**
* An error occurred when serializing or de-serializing.
*/
public
static
final
int
ERROR_SERIALIZATION
=
8
;
/**
* The transaction store is corrupt.
*/
public
static
final
int
ERROR_TRANSACTION_CORRUPT
=
100
;
/**
* A lock timeout occurred.
*/
public
static
final
int
ERROR_TRANSACTION_LOCK_TIMEOUT
=
101
;
/**
/**
* The type for leaf page.
* The type for leaf page.
*/
*/
...
@@ -332,6 +383,7 @@ public class DataUtils {
...
@@ -332,6 +383,7 @@ public class DataUtils {
dst
.
rewind
();
dst
.
rewind
();
}
catch
(
IOException
e
)
{
}
catch
(
IOException
e
)
{
throw
newIllegalStateException
(
throw
newIllegalStateException
(
ERROR_READING_FAILED
,
"Reading from {0} failed; length {1} at {2}"
,
"Reading from {0} failed; length {1} at {2}"
,
file
,
dst
.
remaining
(),
pos
,
e
);
file
,
dst
.
remaining
(),
pos
,
e
);
}
}
...
@@ -353,6 +405,7 @@ public class DataUtils {
...
@@ -353,6 +405,7 @@ public class DataUtils {
}
while
(
src
.
remaining
()
>
0
);
}
while
(
src
.
remaining
()
>
0
);
}
catch
(
IOException
e
)
{
}
catch
(
IOException
e
)
{
throw
newIllegalStateException
(
throw
newIllegalStateException
(
ERROR_WRITING_FAILED
,
"Writing to {0} failed; length {1} at {2}"
,
"Writing to {0} failed; length {1} at {2}"
,
file
,
src
.
remaining
(),
pos
,
e
);
file
,
src
.
remaining
(),
pos
,
e
);
}
}
...
@@ -518,13 +571,17 @@ public class DataUtils {
...
@@ -518,13 +571,17 @@ public class DataUtils {
*
*
* @param s the list
* @param s the list
* @return the map
* @return the map
* @throws IllegalStateException if parsing failed
*/
*/
public
static
HashMap
<
String
,
String
>
parseMap
(
String
s
)
{
public
static
HashMap
<
String
,
String
>
parseMap
(
String
s
)
{
HashMap
<
String
,
String
>
map
=
New
.
hashMap
();
HashMap
<
String
,
String
>
map
=
New
.
hashMap
();
for
(
int
i
=
0
,
size
=
s
.
length
();
i
<
size
;)
{
for
(
int
i
=
0
,
size
=
s
.
length
();
i
<
size
;)
{
int
startKey
=
i
;
int
startKey
=
i
;
i
=
s
.
indexOf
(
':'
,
i
);
i
=
s
.
indexOf
(
':'
,
i
);
checkArgument
(
i
>=
0
,
"Not a map"
);
if
(
i
<
0
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_FILE_CORRUPT
,
"Not a map: {0}"
,
s
);
}
String
key
=
s
.
substring
(
startKey
,
i
++);
String
key
=
s
.
substring
(
startKey
,
i
++);
StringBuilder
buff
=
new
StringBuilder
();
StringBuilder
buff
=
new
StringBuilder
();
while
(
i
<
size
)
{
while
(
i
<
size
)
{
...
@@ -596,7 +653,7 @@ public class DataUtils {
...
@@ -596,7 +653,7 @@ public class DataUtils {
public
static
IllegalArgumentException
newIllegalArgumentException
(
public
static
IllegalArgumentException
newIllegalArgumentException
(
String
message
,
Object
...
arguments
)
{
String
message
,
Object
...
arguments
)
{
return
initCause
(
new
IllegalArgumentException
(
return
initCause
(
new
IllegalArgumentException
(
MessageFormat
.
format
(
message
,
arguments
)
+
" "
+
getVersion
(
)),
formatMessage
(
0
,
message
,
arguments
)),
arguments
);
arguments
);
}
}
...
@@ -608,16 +665,18 @@ public class DataUtils {
...
@@ -608,16 +665,18 @@ public class DataUtils {
*/
*/
public
static
UnsupportedOperationException
newUnsupportedOperationException
(
public
static
UnsupportedOperationException
newUnsupportedOperationException
(
String
message
)
{
String
message
)
{
return
new
UnsupportedOperationException
(
message
+
" "
+
getVersion
(
));
return
new
UnsupportedOperationException
(
formatMessage
(
0
,
message
));
}
}
/**
/**
* Create a new ConcurrentModificationException.
* Create a new ConcurrentModificationException.
*
*
* @param message the message
* @return the exception
* @return the exception
*/
*/
public
static
ConcurrentModificationException
newConcurrentModificationException
()
{
public
static
ConcurrentModificationException
newConcurrentModificationException
(
return
new
ConcurrentModificationException
(
getVersion
());
String
message
)
{
return
new
ConcurrentModificationException
(
formatMessage
(
0
,
message
));
}
}
/**
/**
...
@@ -628,9 +687,9 @@ public class DataUtils {
...
@@ -628,9 +687,9 @@ public class DataUtils {
* @return the exception
* @return the exception
*/
*/
public
static
IllegalStateException
newIllegalStateException
(
public
static
IllegalStateException
newIllegalStateException
(
String
message
,
Object
...
arguments
)
{
int
errorCode
,
String
message
,
Object
...
arguments
)
{
return
initCause
(
new
IllegalStateException
(
return
initCause
(
new
IllegalStateException
(
MessageFormat
.
format
(
message
,
arguments
)
+
" "
+
getVersion
(
)),
formatMessage
(
errorCode
,
message
,
arguments
)),
arguments
);
arguments
);
}
}
...
@@ -644,10 +703,35 @@ public class DataUtils {
...
@@ -644,10 +703,35 @@ public class DataUtils {
}
}
return
e
;
return
e
;
}
}
private
static
String
formatMessage
(
int
errorCode
,
String
message
,
Object
...
arguments
)
{
return
MessageFormat
.
format
(
message
,
arguments
)
+
" "
+
getVersionAndCode
(
errorCode
);
}
private
static
String
getVersion
(
)
{
private
static
String
getVersion
AndCode
(
int
errorCode
)
{
return
"["
+
Constants
.
VERSION_MAJOR
+
"."
+
return
"["
+
Constants
.
VERSION_MAJOR
+
"."
+
Constants
.
VERSION_MINOR
+
"."
+
Constants
.
BUILD_ID
+
"]"
;
Constants
.
VERSION_MINOR
+
"."
+
Constants
.
BUILD_ID
+
"/"
+
errorCode
+
"]"
;
}
/**
* Get the error code from an exception message.
*
* @param m the message
* @return the error code, or 0 if none
*/
public
static
int
getErrorCode
(
String
m
)
{
if
(
m
.
endsWith
(
"]"
))
{
int
dash
=
m
.
lastIndexOf
(
'/'
);
if
(
dash
>=
0
)
{
String
s
=
m
.
substring
(
dash
+
1
,
m
.
length
()
-
1
);
try
{
return
Integer
.
parseInt
(
s
);
}
catch
(
NumberFormatException
e
)
{
// no error code
}
}
}
return
0
;
}
}
/**
/**
...
...
h2/src/main/org/h2/mvstore/FreeSpaceList.java
浏览文件 @
769193eb
...
@@ -53,6 +53,7 @@ public class FreeSpaceList {
...
@@ -53,6 +53,7 @@ public class FreeSpaceList {
}
}
}
}
throw
DataUtils
.
newIllegalStateException
(
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_INTERNAL
,
"Could not find a free page to allocate"
);
"Could not find a free page to allocate"
);
}
}
...
@@ -75,10 +76,12 @@ public class FreeSpaceList {
...
@@ -75,10 +76,12 @@ public class FreeSpaceList {
}
}
if
(
found
==
null
)
{
if
(
found
==
null
)
{
throw
DataUtils
.
newIllegalStateException
(
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_INTERNAL
,
"Cannot find spot to mark chunk as used in free list: {0}"
,
c
);
"Cannot find spot to mark chunk as used in free list: {0}"
,
c
);
}
}
if
(
chunkStart
+
required
>
found
.
start
+
found
.
length
)
{
if
(
chunkStart
+
required
>
found
.
start
+
found
.
length
)
{
throw
DataUtils
.
newIllegalStateException
(
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_INTERNAL
,
"Chunk runs over edge of free space: {0}"
,
c
);
"Chunk runs over edge of free space: {0}"
,
c
);
}
}
if
(
found
.
start
==
chunkStart
)
{
if
(
found
.
start
==
chunkStart
)
{
...
@@ -127,6 +130,7 @@ public class FreeSpaceList {
...
@@ -127,6 +130,7 @@ public class FreeSpaceList {
}
}
if
(
found
==
null
)
{
if
(
found
==
null
)
{
throw
DataUtils
.
newIllegalStateException
(
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_INTERNAL
,
"Cannot find spot to mark chunk as unused in free list: {0}"
,
c
);
"Cannot find spot to mark chunk as unused in free list: {0}"
,
c
);
}
}
if
(
chunkStart
+
required
+
1
==
found
.
start
)
{
if
(
chunkStart
+
required
+
1
==
found
.
start
)
{
...
...
h2/src/main/org/h2/mvstore/MVMap.java
浏览文件 @
769193eb
...
@@ -907,7 +907,8 @@ public class MVMap<K, V> extends AbstractMap<K, V>
...
@@ -907,7 +907,8 @@ public class MVMap<K, V> extends AbstractMap<K, V>
*/
*/
protected
void
checkOpen
()
{
protected
void
checkOpen
()
{
if
(
closed
)
{
if
(
closed
)
{
throw
DataUtils
.
newIllegalStateException
(
"This map is closed"
);
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_CLOSED
,
"This map is closed"
);
}
}
}
}
...
@@ -937,7 +938,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
...
@@ -937,7 +938,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
if
(
writing
)
{
if
(
writing
)
{
// try to detect concurrent modification
// try to detect concurrent modification
// on a best-effort basis
// on a best-effort basis
throw
DataUtils
.
newConcurrentModificationException
();
throw
DataUtils
.
newConcurrentModificationException
(
getName
()
);
}
}
}
}
...
@@ -1004,7 +1005,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
...
@@ -1004,7 +1005,7 @@ public class MVMap<K, V> extends AbstractMap<K, V>
public
MVMap
<
K
,
V
>
openVersion
(
long
version
)
{
public
MVMap
<
K
,
V
>
openVersion
(
long
version
)
{
if
(
readOnly
)
{
if
(
readOnly
)
{
throw
DataUtils
.
newUnsupportedOperationException
(
throw
DataUtils
.
newUnsupportedOperationException
(
"This map is read-only
-
need to call the method on the writable map"
);
"This map is read-only
;
need to call the method on the writable map"
);
}
}
DataUtils
.
checkArgument
(
version
>=
createVersion
,
DataUtils
.
checkArgument
(
version
>=
createVersion
,
"Unknown version {0}; this map was created in version is {1}"
,
"Unknown version {0}; this map was created in version is {1}"
,
...
...
h2/src/main/org/h2/mvstore/MVStore.java
浏览文件 @
769193eb
...
@@ -10,6 +10,7 @@ import java.io.IOException;
...
@@ -10,6 +10,7 @@ import java.io.IOException;
import
java.nio.ByteBuffer
;
import
java.nio.ByteBuffer
;
import
java.nio.channels.FileChannel
;
import
java.nio.channels.FileChannel
;
import
java.nio.channels.FileLock
;
import
java.nio.channels.FileLock
;
import
java.nio.channels.OverlappingFileLockException
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.Collections
;
...
@@ -436,6 +437,10 @@ public class MVStore {
...
@@ -436,6 +437,10 @@ public class MVStore {
/**
/**
* Open the store.
* Open the store.
*
* @throws IllegalStateException if the file is corrupt, or an exception
* occurred while opening
* @throws IllegalArgumentException if the directory does not exist
*/
*/
void
open
()
{
void
open
()
{
meta
=
new
MVMapConcurrent
<
String
,
String
>(
StringDataType
.
INSTANCE
,
StringDataType
.
INSTANCE
);
meta
=
new
MVMapConcurrent
<
String
,
String
>(
StringDataType
.
INSTANCE
,
StringDataType
.
INSTANCE
);
...
@@ -476,11 +481,13 @@ public class MVStore {
...
@@ -476,11 +481,13 @@ public class MVStore {
* Try to open the file in read or write mode.
* Try to open the file in read or write mode.
*
*
* @return if opening the file was successful, and false if the file could
* @return if opening the file was successful, and false if the file could
* not be opened in write mode because the write file format it too
* not be opened in write mode because the write file format it too
* high (in which case the file can be opened in read-only mode)
* high (in which case the file can be opened in read-only mode)
* @throw IllegalStateException if the file could not be opened at all
* @throw IllegalStateException if the file could not be opened
* because of an IOException or file format error
*/
*/
private
boolean
openFile
()
{
private
boolean
openFile
()
{
IllegalStateException
exception
;
try
{
try
{
log
(
"file open"
);
log
(
"file open"
);
FilePath
f
=
FilePath
.
get
(
fileName
);
FilePath
f
=
FilePath
.
get
(
fileName
);
...
@@ -493,16 +500,19 @@ public class MVStore {
...
@@ -493,16 +500,19 @@ public class MVStore {
file
=
new
FilePathCrypt
.
FileCrypt
(
fileName
,
password
,
file
);
file
=
new
FilePathCrypt
.
FileCrypt
(
fileName
,
password
,
file
);
}
}
file
=
FilePathCache
.
wrap
(
file
);
file
=
FilePathCache
.
wrap
(
file
);
if
(
readOnly
)
{
try
{
fileLock
=
file
.
tryLock
(
0
,
Long
.
MAX_VALUE
,
true
);
if
(
readOnly
)
{
if
(
fileLock
==
null
)
{
fileLock
=
file
.
tryLock
(
0
,
Long
.
MAX_VALUE
,
true
);
throw
new
IOException
(
"The file is locked: "
+
fileName
);
}
else
{
}
fileLock
=
file
.
tryLock
();
}
else
{
fileLock
=
file
.
tryLock
();
if
(
fileLock
==
null
)
{
throw
new
IOException
(
"The file is locked: "
+
fileName
);
}
}
}
catch
(
OverlappingFileLockException
e
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_FILE_LOCKED
,
"The file is locked: {0}"
,
fileName
,
e
);
}
if
(
fileLock
==
null
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_FILE_LOCKED
,
"The file is locked: {0}"
,
fileName
);
}
}
fileSize
=
file
.
size
();
fileSize
=
file
.
size
();
if
(
fileSize
==
0
)
{
if
(
fileSize
==
0
)
{
...
@@ -521,8 +531,9 @@ public class MVStore {
...
@@ -521,8 +531,9 @@ public class MVStore {
int
formatRead
=
x
==
null
?
formatWrite
:
Integer
.
parseInt
(
x
);
int
formatRead
=
x
==
null
?
formatWrite
:
Integer
.
parseInt
(
x
);
if
(
formatRead
>
FORMAT_READ
)
{
if
(
formatRead
>
FORMAT_READ
)
{
throw
DataUtils
.
newIllegalStateException
(
throw
DataUtils
.
newIllegalStateException
(
"The file format {0} is larger than the supported format {1}"
,
DataUtils
.
ERROR_UNSUPPORTED_FORMAT
,
formatRead
,
FORMAT_READ
);
"The file format {0} is larger than the supported format {1}"
,
formatRead
,
FORMAT_READ
);
}
}
if
(
formatWrite
>
FORMAT_WRITE
)
{
if
(
formatWrite
>
FORMAT_WRITE
)
{
readOnly
=
true
;
readOnly
=
true
;
...
@@ -533,14 +544,21 @@ public class MVStore {
...
@@ -533,14 +544,21 @@ public class MVStore {
readMeta
();
readMeta
();
}
}
}
}
}
catch
(
Exception
e
)
{
exception
=
null
;
}
catch
(
IOException
e
)
{
exception
=
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_READING_FAILED
,
"Could not open file {0}"
,
fileName
,
e
);
}
catch
(
IllegalStateException
e
)
{
exception
=
e
;
}
if
(
exception
!=
null
)
{
try
{
try
{
closeFile
(
false
);
closeFile
(
false
);
}
catch
(
Exception
e2
)
{
}
catch
(
Exception
e2
)
{
// ignore
// ignore
}
}
throw
DataUtils
.
newIllegalStateException
(
throw
exception
;
"Could not open file {0}"
,
fileName
,
e
);
}
}
return
true
;
return
true
;
}
}
...
@@ -603,7 +621,12 @@ public class MVStore {
...
@@ -603,7 +621,12 @@ public class MVStore {
for
(
int
i
=
0
;
i
<
3
*
BLOCK_SIZE
;
i
+=
BLOCK_SIZE
)
{
for
(
int
i
=
0
;
i
<
3
*
BLOCK_SIZE
;
i
+=
BLOCK_SIZE
)
{
String
s
=
new
String
(
buff
.
array
(),
i
,
BLOCK_SIZE
,
Constants
.
UTF8
)
String
s
=
new
String
(
buff
.
array
(),
i
,
BLOCK_SIZE
,
Constants
.
UTF8
)
.
trim
();
.
trim
();
HashMap
<
String
,
String
>
m
=
DataUtils
.
parseMap
(
s
);
HashMap
<
String
,
String
>
m
;
try
{
m
=
DataUtils
.
parseMap
(
s
);
}
catch
(
IllegalArgumentException
e
)
{
continue
;
}
String
f
=
m
.
remove
(
"fletcher"
);
String
f
=
m
.
remove
(
"fletcher"
);
if
(
f
==
null
)
{
if
(
f
==
null
)
{
continue
;
continue
;
...
@@ -630,7 +653,8 @@ public class MVStore {
...
@@ -630,7 +653,8 @@ public class MVStore {
}
}
}
}
if
(
currentVersion
<
0
)
{
if
(
currentVersion
<
0
)
{
throw
DataUtils
.
newIllegalStateException
(
"File header is corrupt"
);
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_FILE_CORRUPT
,
"File header is corrupt: {0}"
,
fileName
);
}
}
lastStoredVersion
=
-
1
;
lastStoredVersion
=
-
1
;
}
}
...
@@ -645,8 +669,11 @@ public class MVStore {
...
@@ -645,8 +669,11 @@ public class MVStore {
int
checksum
=
DataUtils
.
getFletcher32
(
bytes
,
bytes
.
length
/
2
*
2
);
int
checksum
=
DataUtils
.
getFletcher32
(
bytes
,
bytes
.
length
/
2
*
2
);
DataUtils
.
appendMap
(
buff
,
"fletcher"
,
Integer
.
toHexString
(
checksum
));
DataUtils
.
appendMap
(
buff
,
"fletcher"
,
Integer
.
toHexString
(
checksum
));
bytes
=
buff
.
toString
().
getBytes
(
Constants
.
UTF8
);
bytes
=
buff
.
toString
().
getBytes
(
Constants
.
UTF8
);
DataUtils
.
checkArgument
(
bytes
.
length
<=
BLOCK_SIZE
,
if
(
bytes
.
length
>
BLOCK_SIZE
)
{
"File header too large: {0}"
,
buff
);
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_UNSUPPORTED_FORMAT
,
"File header too large: {0}"
,
buff
);
}
return
bytes
;
return
bytes
;
}
}
...
@@ -720,6 +747,7 @@ public class MVStore {
...
@@ -720,6 +747,7 @@ public class MVStore {
maps
.
clear
();
maps
.
clear
();
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
throw
DataUtils
.
newIllegalStateException
(
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_WRITING_FAILED
,
"Closing failed for file {0}"
,
fileName
,
e
);
"Closing failed for file {0}"
,
fileName
,
e
);
}
finally
{
}
finally
{
file
=
null
;
file
=
null
;
...
@@ -799,7 +827,8 @@ public class MVStore {
...
@@ -799,7 +827,8 @@ public class MVStore {
return
currentVersion
;
return
currentVersion
;
}
}
if
(
readOnly
)
{
if
(
readOnly
)
{
throw
DataUtils
.
newIllegalStateException
(
"This store is read-only"
);
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_WRITING_FAILED
,
"This store is read-only"
);
}
}
int
currentUnsavedPageCount
=
unsavedPageCount
;
int
currentUnsavedPageCount
=
unsavedPageCount
;
long
storeVersion
=
currentStoreVersion
=
currentVersion
;
long
storeVersion
=
currentStoreVersion
=
currentVersion
;
...
@@ -893,7 +922,8 @@ public class MVStore {
...
@@ -893,7 +922,8 @@ public class MVStore {
if
(
ASSERT
)
{
if
(
ASSERT
)
{
if
(
freedPages
.
size
()
>
0
)
{
if
(
freedPages
.
size
()
>
0
)
{
throw
DataUtils
.
newIllegalStateException
(
"Temporary freed chunks"
);
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_INTERNAL
,
"Temporary freed chunks"
);
}
}
}
}
...
@@ -1002,14 +1032,17 @@ public class MVStore {
...
@@ -1002,14 +1032,17 @@ public class MVStore {
c
.
pageCountLive
+=
f
.
pageCountLive
;
c
.
pageCountLive
+=
f
.
pageCountLive
;
if
(
c
.
pageCountLive
<
0
)
{
if
(
c
.
pageCountLive
<
0
)
{
throw
DataUtils
.
newIllegalStateException
(
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_INTERNAL
,
"Corrupt page count {0}"
,
c
.
pageCountLive
);
"Corrupt page count {0}"
,
c
.
pageCountLive
);
}
}
if
(
c
.
maxLengthLive
<
0
)
{
if
(
c
.
maxLengthLive
<
0
)
{
throw
DataUtils
.
newIllegalStateException
(
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_INTERNAL
,
"Corrupt max length {0}"
,
c
.
maxLengthLive
);
"Corrupt max length {0}"
,
c
.
maxLengthLive
);
}
}
if
(
c
.
pageCount
==
0
&&
c
.
maxLengthLive
>
0
)
{
if
(
c
.
pageCount
==
0
&&
c
.
maxLengthLive
>
0
)
{
throw
DataUtils
.
newIllegalStateException
(
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_INTERNAL
,
"Corrupt max length {0}"
,
c
.
maxLengthLive
);
"Corrupt max length {0}"
,
c
.
maxLengthLive
);
}
}
modified
.
add
(
c
);
modified
.
add
(
c
);
...
@@ -1060,6 +1093,7 @@ public class MVStore {
...
@@ -1060,6 +1093,7 @@ public class MVStore {
file
.
truncate
(
used
);
file
.
truncate
(
used
);
}
catch
(
IOException
e
)
{
}
catch
(
IOException
e
)
{
throw
DataUtils
.
newIllegalStateException
(
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_WRITING_FAILED
,
"Could not truncate file {0} to size {1}"
,
"Could not truncate file {0} to size {1}"
,
fileName
,
used
,
e
);
fileName
,
used
,
e
);
}
}
...
@@ -1259,6 +1293,7 @@ public class MVStore {
...
@@ -1259,6 +1293,7 @@ public class MVStore {
Chunk
c
=
getChunk
(
pos
);
Chunk
c
=
getChunk
(
pos
);
if
(
c
==
null
)
{
if
(
c
==
null
)
{
throw
DataUtils
.
newIllegalStateException
(
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_FILE_CORRUPT
,
"Chunk {0} not found"
,
"Chunk {0} not found"
,
DataUtils
.
getPageChunkId
(
pos
));
DataUtils
.
getPageChunkId
(
pos
));
}
}
...
@@ -1682,7 +1717,8 @@ public class MVStore {
...
@@ -1682,7 +1717,8 @@ public class MVStore {
private
void
checkOpen
()
{
private
void
checkOpen
()
{
if
(
closed
)
{
if
(
closed
)
{
throw
DataUtils
.
newIllegalStateException
(
"This store is closed"
);
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_CLOSED
,
"This store is closed"
);
}
}
}
}
...
@@ -1741,6 +1777,15 @@ public class MVStore {
...
@@ -1741,6 +1777,15 @@ public class MVStore {
store
(
true
);
store
(
true
);
}
}
/**
* Set the read cache size in MB.
*
* @param mb the cache size in MB.
*/
public
void
setCacheSize
(
long
mb
)
{
cache
.
setMaxMemory
(
mb
*
1024
*
1024
);
}
public
boolean
isReadOnly
()
{
public
boolean
isReadOnly
()
{
return
readOnly
;
return
readOnly
;
}
}
...
...
h2/src/main/org/h2/mvstore/Page.java
浏览文件 @
769193eb
...
@@ -429,6 +429,7 @@ public class Page {
...
@@ -429,6 +429,7 @@ public class Page {
}
}
if
(
check
!=
totalCount
)
{
if
(
check
!=
totalCount
)
{
throw
DataUtils
.
newIllegalStateException
(
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_INTERNAL
,
"Expected: {0} got: {1}"
,
check
,
totalCount
);
"Expected: {0} got: {1}"
,
check
,
totalCount
);
}
}
}
}
...
@@ -694,6 +695,7 @@ public class Page {
...
@@ -694,6 +695,7 @@ public class Page {
int
pageLength
=
buff
.
getInt
();
int
pageLength
=
buff
.
getInt
();
if
(
pageLength
>
maxLength
)
{
if
(
pageLength
>
maxLength
)
{
throw
DataUtils
.
newIllegalStateException
(
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_FILE_CORRUPT
,
"File corrupted, expected length =< {0}, got {1}"
,
"File corrupted, expected length =< {0}, got {1}"
,
maxLength
,
pageLength
);
maxLength
,
pageLength
);
}
}
...
@@ -701,6 +703,7 @@ public class Page {
...
@@ -701,6 +703,7 @@ public class Page {
int
mapId
=
DataUtils
.
readVarInt
(
buff
);
int
mapId
=
DataUtils
.
readVarInt
(
buff
);
if
(
mapId
!=
map
.
getId
())
{
if
(
mapId
!=
map
.
getId
())
{
throw
DataUtils
.
newIllegalStateException
(
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_FILE_CORRUPT
,
"File corrupted, expected map id {0}, got {1}"
,
"File corrupted, expected map id {0}, got {1}"
,
map
.
getId
(),
mapId
);
map
.
getId
(),
mapId
);
}
}
...
@@ -709,6 +712,7 @@ public class Page {
...
@@ -709,6 +712,7 @@ public class Page {
^
DataUtils
.
getCheckValue
(
pageLength
);
^
DataUtils
.
getCheckValue
(
pageLength
);
if
(
check
!=
(
short
)
checkTest
)
{
if
(
check
!=
(
short
)
checkTest
)
{
throw
DataUtils
.
newIllegalStateException
(
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_FILE_CORRUPT
,
"File corrupted, expected check value {0}, got {1}"
,
"File corrupted, expected check value {0}, got {1}"
,
checkTest
,
check
);
checkTest
,
check
);
}
}
...
@@ -818,7 +822,8 @@ public class Page {
...
@@ -818,7 +822,8 @@ public class Page {
^
DataUtils
.
getCheckValue
(
pageLength
);
^
DataUtils
.
getCheckValue
(
pageLength
);
buff
.
putShort
(
start
+
4
,
(
short
)
check
);
buff
.
putShort
(
start
+
4
,
(
short
)
check
);
if
(
pos
!=
0
)
{
if
(
pos
!=
0
)
{
throw
DataUtils
.
newIllegalStateException
(
"Page already stored"
);
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_INTERNAL
,
"Page already stored"
);
}
}
pos
=
DataUtils
.
getPagePos
(
chunkId
,
start
,
pageLength
,
type
);
pos
=
DataUtils
.
getPagePos
(
chunkId
,
start
,
pageLength
,
type
);
long
max
=
DataUtils
.
getPageMaxLength
(
pos
);
long
max
=
DataUtils
.
getPageMaxLength
(
pos
);
...
@@ -901,7 +906,8 @@ public class Page {
...
@@ -901,7 +906,8 @@ public class Page {
public
int
getMemory
()
{
public
int
getMemory
()
{
if
(
MVStore
.
ASSERT
)
{
if
(
MVStore
.
ASSERT
)
{
if
(
memory
!=
calculateMemory
())
{
if
(
memory
!=
calculateMemory
())
{
throw
DataUtils
.
newIllegalStateException
(
"Memory calculation error"
);
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_INTERNAL
,
"Memory calculation error"
);
}
}
}
}
return
memory
;
return
memory
;
...
...
h2/src/main/org/h2/mvstore/db/MVTableEngine.java
浏览文件 @
769193eb
...
@@ -11,13 +11,16 @@ import java.util.List;
...
@@ -11,13 +11,16 @@ import java.util.List;
import
org.h2.api.TableEngine
;
import
org.h2.api.TableEngine
;
import
org.h2.command.ddl.CreateTableData
;
import
org.h2.command.ddl.CreateTableData
;
import
org.h2.constant.ErrorCode
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Constants
;
import
org.h2.engine.Database
;
import
org.h2.engine.Database
;
import
org.h2.engine.Session
;
import
org.h2.engine.Session
;
import
org.h2.message.DbException
;
import
org.h2.message.DbException
;
import
org.h2.mvstore.DataUtils
;
import
org.h2.mvstore.MVStore
;
import
org.h2.mvstore.MVStore
;
import
org.h2.mvstore.db.TransactionStore.Transaction
;
import
org.h2.mvstore.db.TransactionStore.Transaction
;
import
org.h2.store.InDoubtTransaction
;
import
org.h2.store.InDoubtTransaction
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.table.RegularTable
;
import
org.h2.table.RegularTable
;
import
org.h2.table.TableBase
;
import
org.h2.table.TableBase
;
import
org.h2.util.New
;
import
org.h2.util.New
;
...
@@ -26,13 +29,14 @@ import org.h2.util.New;
...
@@ -26,13 +29,14 @@ import org.h2.util.New;
* A table engine that internally uses the MVStore.
* A table engine that internally uses the MVStore.
*/
*/
public
class
MVTableEngine
implements
TableEngine
{
public
class
MVTableEngine
implements
TableEngine
{
@Override
/**
public
TableBase
createTable
(
CreateTableData
data
)
{
* Initialize the MVStore.
Database
db
=
data
.
session
.
getDatabase
();
*
if
(!
data
.
persistData
||
(
data
.
temporary
&&
!
data
.
persistIndexes
))
{
* @param db the database
return
new
RegularTable
(
data
);
* @return the store
}
*/
public
static
Store
init
(
Database
db
)
{
Store
store
=
db
.
getMvStore
();
Store
store
=
db
.
getMvStore
();
if
(
store
==
null
)
{
if
(
store
==
null
)
{
byte
[]
key
=
db
.
getFilePasswordHash
();
byte
[]
key
=
db
.
getFilePasswordHash
();
...
@@ -41,9 +45,19 @@ public class MVTableEngine implements TableEngine {
...
@@ -41,9 +45,19 @@ public class MVTableEngine implements TableEngine {
if
(
dbPath
==
null
)
{
if
(
dbPath
==
null
)
{
store
=
new
Store
(
db
,
builder
.
open
());
store
=
new
Store
(
db
,
builder
.
open
());
}
else
{
}
else
{
builder
.
fileName
(
dbPath
+
Constants
.
SUFFIX_MV_FILE
);
String
fileName
=
dbPath
+
Constants
.
SUFFIX_MV_FILE
;
builder
.
fileName
(
fileName
);
if
(
db
.
isReadOnly
())
{
if
(
db
.
isReadOnly
())
{
builder
.
readOnly
();
builder
.
readOnly
();
}
else
{
// possibly create the directory
boolean
exists
=
FileUtils
.
exists
(
fileName
);
if
(
exists
&&
!
FileUtils
.
canWrite
(
fileName
))
{
// read only
}
else
{
String
dir
=
FileUtils
.
getParent
(
fileName
);
FileUtils
.
createDirectories
(
dir
);
}
}
}
if
(
key
!=
null
)
{
if
(
key
!=
null
)
{
char
[]
password
=
new
char
[
key
.
length
];
char
[]
password
=
new
char
[
key
.
length
];
...
@@ -52,10 +66,32 @@ public class MVTableEngine implements TableEngine {
...
@@ -52,10 +66,32 @@ public class MVTableEngine implements TableEngine {
}
}
builder
.
encryptionKey
(
password
);
builder
.
encryptionKey
(
password
);
}
}
store
=
new
Store
(
db
,
builder
.
open
());
try
{
store
=
new
Store
(
db
,
builder
.
open
());
}
catch
(
IllegalStateException
e
)
{
int
errorCode
=
DataUtils
.
getErrorCode
(
e
.
getMessage
());
if
(
errorCode
==
DataUtils
.
ERROR_FILE_CORRUPT
)
{
if
(
key
!=
null
)
{
throw
DbException
.
get
(
ErrorCode
.
FILE_ENCRYPTION_ERROR_1
,
fileName
);
}
}
else
if
(
errorCode
==
DataUtils
.
ERROR_FILE_LOCKED
)
{
throw
DbException
.
get
(
ErrorCode
.
DATABASE_ALREADY_OPEN_1
,
fileName
);
}
throw
DbException
.
get
(
ErrorCode
.
FILE_CORRUPTED_1
,
fileName
);
}
}
}
db
.
setMvStore
(
store
);
db
.
setMvStore
(
store
);
}
}
return
store
;
}
@Override
public
TableBase
createTable
(
CreateTableData
data
)
{
Database
db
=
data
.
session
.
getDatabase
();
if
(!
data
.
persistData
||
(
data
.
temporary
&&
!
data
.
persistIndexes
))
{
return
new
RegularTable
(
data
);
}
Store
store
=
init
(
db
);
MVTable
table
=
new
MVTable
(
data
,
store
);
MVTable
table
=
new
MVTable
(
data
,
store
);
store
.
openTables
.
add
(
table
);
store
.
openTables
.
add
(
table
);
table
.
init
(
data
.
session
);
table
.
init
(
data
.
session
);
...
@@ -188,6 +224,10 @@ public class MVTableEngine implements TableEngine {
...
@@ -188,6 +224,10 @@ public class MVTableEngine implements TableEngine {
return
result
;
return
result
;
}
}
public
void
setCacheSize
(
int
kb
)
{
store
.
setCacheSize
(
kb
*
1024
);
}
}
}
/**
/**
...
...
h2/src/main/org/h2/mvstore/db/TransactionStore.java
浏览文件 @
769193eb
...
@@ -111,7 +111,9 @@ public class TransactionStore {
...
@@ -111,7 +111,9 @@ public class TransactionStore {
}
}
Long
lastKey
=
preparedTransactions
.
lastKey
();
Long
lastKey
=
preparedTransactions
.
lastKey
();
if
(
lastKey
!=
null
&&
lastKey
.
longValue
()
>
lastTransactionId
)
{
if
(
lastKey
!=
null
&&
lastKey
.
longValue
()
>
lastTransactionId
)
{
throw
DataUtils
.
newIllegalStateException
(
"Last transaction not stored"
);
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_TRANSACTION_CORRUPT
,
"Last transaction not stored"
);
}
}
if
(
undoLog
.
size
()
>
0
)
{
if
(
undoLog
.
size
()
>
0
)
{
long
[]
key
=
undoLog
.
firstKey
();
long
[]
key
=
undoLog
.
firstKey
();
...
@@ -616,7 +618,8 @@ public class TransactionStore {
...
@@ -616,7 +618,8 @@ public class TransactionStore {
*/
*/
void
checkNotClosed
()
{
void
checkNotClosed
()
{
if
(
status
==
STATUS_CLOSED
)
{
if
(
status
==
STATUS_CLOSED
)
{
throw
DataUtils
.
newIllegalStateException
(
"Transaction is closed"
);
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_CLOSED
,
"Transaction is closed"
);
}
}
}
}
...
@@ -749,14 +752,16 @@ public class TransactionStore {
...
@@ -749,14 +752,16 @@ public class TransactionStore {
// wait until it is committed, or until the lock timeout
// wait until it is committed, or until the lock timeout
long
timeout
=
transaction
.
store
.
lockTimeout
;
long
timeout
=
transaction
.
store
.
lockTimeout
;
if
(
timeout
==
0
)
{
if
(
timeout
==
0
)
{
throw
DataUtils
.
newIllegalStateException
(
"Lock timeout"
);
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_TRANSACTION_LOCK_TIMEOUT
,
"Lock timeout"
);
}
}
if
(
start
==
0
)
{
if
(
start
==
0
)
{
start
=
System
.
currentTimeMillis
();
start
=
System
.
currentTimeMillis
();
}
else
{
}
else
{
long
t
=
System
.
currentTimeMillis
()
-
start
;
long
t
=
System
.
currentTimeMillis
()
-
start
;
if
(
t
>
timeout
)
{
if
(
t
>
timeout
)
{
throw
DataUtils
.
newIllegalStateException
(
"Lock timeout"
);
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_TRANSACTION_LOCK_TIMEOUT
,
"Lock timeout"
);
}
}
// TODO use wait/notify instead, or remove the feature
// TODO use wait/notify instead, or remove the feature
try
{
try
{
...
...
h2/src/main/org/h2/mvstore/rtree/MVRTreeMap.java
浏览文件 @
769193eb
差异被折叠。
点击展开。
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论