Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
769193eb
提交
769193eb
authored
11 年前
作者:
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 {
static
Chunk
fromHeader
(
ByteBuffer
buff
,
long
start
)
{
if
(
buff
.
get
()
!=
'c'
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_FILE_CORRUPT
,
"File corrupt reading chunk at position {0}"
,
start
);
}
int
length
=
buff
.
getInt
();
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/Cursor.java
浏览文件 @
769193eb
...
...
@@ -15,27 +15,19 @@ import java.util.Iterator;
*/
public
class
Cursor
<
K
>
implements
Iterator
<
K
>
{
pr
otected
final
MVMap
<
K
,
?>
map
;
pr
otected
final
K
from
;
pr
otected
CursorPos
pos
;
pr
otected
K
current
;
pr
ivate
final
MVMap
<
K
,
?>
map
;
pr
ivate
final
K
from
;
pr
ivate
CursorPos
pos
;
pr
ivate
K
current
;
private
final
Page
root
;
private
boolean
initialized
;
protected
Cursor
(
MVMap
<
K
,
?>
map
,
Page
root
,
K
from
)
{
Cursor
(
MVMap
<
K
,
?>
map
,
Page
root
,
K
from
)
{
this
.
map
=
map
;
this
.
root
=
root
;
this
.
from
=
from
;
}
@Override
public
K
next
()
{
hasNext
();
K
c
=
current
;
fetchNext
();
return
c
;
}
@Override
public
boolean
hasNext
()
{
if
(!
initialized
)
{
...
...
@@ -46,6 +38,14 @@ public class Cursor<K> implements Iterator<K> {
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
* implementation) even if many entries need to be skipped.
...
...
@@ -82,7 +82,7 @@ public class Cursor<K> implements Iterator<K> {
* @param p the page to start
* @param from the key to search
*/
pr
otected
void
min
(
Page
p
,
K
from
)
{
pr
ivate
void
min
(
Page
p
,
K
from
)
{
while
(
true
)
{
if
(
p
.
isLeaf
())
{
int
x
=
from
==
null
?
0
:
p
.
binarySearch
(
from
);
...
...
@@ -107,7 +107,7 @@ public class Cursor<K> implements Iterator<K> {
* Fetch the next entry if there is one.
*/
@SuppressWarnings
(
"unchecked"
)
pr
otected
void
fetchNext
()
{
pr
ivate
void
fetchNext
()
{
while
(
pos
!=
null
)
{
if
(
pos
.
index
<
pos
.
page
.
getKeyCount
())
{
current
=
(
K
)
pos
.
page
.
getKey
(
pos
.
index
++);
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/DataUtils.java
浏览文件 @
769193eb
...
...
@@ -24,6 +24,57 @@ import org.h2.util.New;
*/
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.
*/
...
...
@@ -332,6 +383,7 @@ public class DataUtils {
dst
.
rewind
();
}
catch
(
IOException
e
)
{
throw
newIllegalStateException
(
ERROR_READING_FAILED
,
"Reading from {0} failed; length {1} at {2}"
,
file
,
dst
.
remaining
(),
pos
,
e
);
}
...
...
@@ -353,6 +405,7 @@ public class DataUtils {
}
while
(
src
.
remaining
()
>
0
);
}
catch
(
IOException
e
)
{
throw
newIllegalStateException
(
ERROR_WRITING_FAILED
,
"Writing to {0} failed; length {1} at {2}"
,
file
,
src
.
remaining
(),
pos
,
e
);
}
...
...
@@ -518,13 +571,17 @@ public class DataUtils {
*
* @param s the list
* @return the map
* @throws IllegalStateException if parsing failed
*/
public
static
HashMap
<
String
,
String
>
parseMap
(
String
s
)
{
HashMap
<
String
,
String
>
map
=
New
.
hashMap
();
for
(
int
i
=
0
,
size
=
s
.
length
();
i
<
size
;)
{
int
startKey
=
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
++);
StringBuilder
buff
=
new
StringBuilder
();
while
(
i
<
size
)
{
...
...
@@ -596,7 +653,7 @@ public class DataUtils {
public
static
IllegalArgumentException
newIllegalArgumentException
(
String
message
,
Object
...
arguments
)
{
return
initCause
(
new
IllegalArgumentException
(
MessageFormat
.
format
(
message
,
arguments
)
+
" "
+
getVersion
(
)),
formatMessage
(
0
,
message
,
arguments
)),
arguments
);
}
...
...
@@ -608,16 +665,18 @@ public class DataUtils {
*/
public
static
UnsupportedOperationException
newUnsupportedOperationException
(
String
message
)
{
return
new
UnsupportedOperationException
(
message
+
" "
+
getVersion
(
));
return
new
UnsupportedOperationException
(
formatMessage
(
0
,
message
));
}
/**
* Create a new ConcurrentModificationException.
*
* @param message the message
* @return the exception
*/
public
static
ConcurrentModificationException
newConcurrentModificationException
()
{
return
new
ConcurrentModificationException
(
getVersion
());
public
static
ConcurrentModificationException
newConcurrentModificationException
(
String
message
)
{
return
new
ConcurrentModificationException
(
formatMessage
(
0
,
message
));
}
/**
...
...
@@ -628,9 +687,9 @@ public class DataUtils {
* @return the exception
*/
public
static
IllegalStateException
newIllegalStateException
(
String
message
,
Object
...
arguments
)
{
int
errorCode
,
String
message
,
Object
...
arguments
)
{
return
initCause
(
new
IllegalStateException
(
MessageFormat
.
format
(
message
,
arguments
)
+
" "
+
getVersion
(
)),
formatMessage
(
errorCode
,
message
,
arguments
)),
arguments
);
}
...
...
@@ -644,10 +703,35 @@ public class DataUtils {
}
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
+
"."
+
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
;
}
/**
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/FreeSpaceList.java
浏览文件 @
769193eb
...
...
@@ -53,6 +53,7 @@ public class FreeSpaceList {
}
}
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_INTERNAL
,
"Could not find a free page to allocate"
);
}
...
...
@@ -75,10 +76,12 @@ public class FreeSpaceList {
}
if
(
found
==
null
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_INTERNAL
,
"Cannot find spot to mark chunk as used in free list: {0}"
,
c
);
}
if
(
chunkStart
+
required
>
found
.
start
+
found
.
length
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_INTERNAL
,
"Chunk runs over edge of free space: {0}"
,
c
);
}
if
(
found
.
start
==
chunkStart
)
{
...
...
@@ -127,6 +130,7 @@ public class FreeSpaceList {
}
if
(
found
==
null
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_INTERNAL
,
"Cannot find spot to mark chunk as unused in free list: {0}"
,
c
);
}
if
(
chunkStart
+
required
+
1
==
found
.
start
)
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/MVMap.java
浏览文件 @
769193eb
...
...
@@ -907,7 +907,8 @@ public class MVMap<K, V> extends AbstractMap<K, V>
*/
protected
void
checkOpen
()
{
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>
if
(
writing
)
{
// try to detect concurrent modification
// 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>
public
MVMap
<
K
,
V
>
openVersion
(
long
version
)
{
if
(
readOnly
)
{
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
,
"Unknown version {0}; this map was created in version is {1}"
,
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/MVStore.java
浏览文件 @
769193eb
...
...
@@ -10,6 +10,7 @@ import java.io.IOException;
import
java.nio.ByteBuffer
;
import
java.nio.channels.FileChannel
;
import
java.nio.channels.FileLock
;
import
java.nio.channels.OverlappingFileLockException
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
...
...
@@ -436,6 +437,10 @@ public class MVStore {
/**
* 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
()
{
meta
=
new
MVMapConcurrent
<
String
,
String
>(
StringDataType
.
INSTANCE
,
StringDataType
.
INSTANCE
);
...
...
@@ -476,11 +481,13 @@ public class MVStore {
* Try to open the file in read or write mode.
*
* @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
* high (in which case the file can be opened in read-only mode)
* @throw IllegalStateException if the file could not be opened at all
* 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)
* @throw IllegalStateException if the file could not be opened
* because of an IOException or file format error
*/
private
boolean
openFile
()
{
IllegalStateException
exception
;
try
{
log
(
"file open"
);
FilePath
f
=
FilePath
.
get
(
fileName
);
...
...
@@ -493,16 +500,19 @@ public class MVStore {
file
=
new
FilePathCrypt
.
FileCrypt
(
fileName
,
password
,
file
);
}
file
=
FilePathCache
.
wrap
(
file
);
if
(
readOnly
)
{
fileLock
=
file
.
tryLock
(
0
,
Long
.
MAX_VALUE
,
true
);
if
(
fileLock
==
null
)
{
throw
new
IOException
(
"The file is locked: "
+
fileName
);
}
}
else
{
fileLock
=
file
.
tryLock
();
if
(
fileLock
==
null
)
{
throw
new
IOException
(
"The file is locked: "
+
fileName
);
try
{
if
(
readOnly
)
{
fileLock
=
file
.
tryLock
(
0
,
Long
.
MAX_VALUE
,
true
);
}
else
{
fileLock
=
file
.
tryLock
();
}
}
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
();
if
(
fileSize
==
0
)
{
...
...
@@ -521,8 +531,9 @@ public class MVStore {
int
formatRead
=
x
==
null
?
formatWrite
:
Integer
.
parseInt
(
x
);
if
(
formatRead
>
FORMAT_READ
)
{
throw
DataUtils
.
newIllegalStateException
(
"The file format {0} is larger than the supported format {1}"
,
formatRead
,
FORMAT_READ
);
DataUtils
.
ERROR_UNSUPPORTED_FORMAT
,
"The file format {0} is larger than the supported format {1}"
,
formatRead
,
FORMAT_READ
);
}
if
(
formatWrite
>
FORMAT_WRITE
)
{
readOnly
=
true
;
...
...
@@ -533,14 +544,21 @@ public class MVStore {
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
{
closeFile
(
false
);
}
catch
(
Exception
e2
)
{
// ignore
}
throw
DataUtils
.
newIllegalStateException
(
"Could not open file {0}"
,
fileName
,
e
);
throw
exception
;
}
return
true
;
}
...
...
@@ -603,7 +621,12 @@ public class MVStore {
for
(
int
i
=
0
;
i
<
3
*
BLOCK_SIZE
;
i
+=
BLOCK_SIZE
)
{
String
s
=
new
String
(
buff
.
array
(),
i
,
BLOCK_SIZE
,
Constants
.
UTF8
)
.
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"
);
if
(
f
==
null
)
{
continue
;
...
...
@@ -630,7 +653,8 @@ public class MVStore {
}
}
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
;
}
...
...
@@ -645,8 +669,11 @@ public class MVStore {
int
checksum
=
DataUtils
.
getFletcher32
(
bytes
,
bytes
.
length
/
2
*
2
);
DataUtils
.
appendMap
(
buff
,
"fletcher"
,
Integer
.
toHexString
(
checksum
));
bytes
=
buff
.
toString
().
getBytes
(
Constants
.
UTF8
);
DataUtils
.
checkArgument
(
bytes
.
length
<=
BLOCK_SIZE
,
"File header too large: {0}"
,
buff
);
if
(
bytes
.
length
>
BLOCK_SIZE
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_UNSUPPORTED_FORMAT
,
"File header too large: {0}"
,
buff
);
}
return
bytes
;
}
...
...
@@ -720,6 +747,7 @@ public class MVStore {
maps
.
clear
();
}
catch
(
Exception
e
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_WRITING_FAILED
,
"Closing failed for file {0}"
,
fileName
,
e
);
}
finally
{
file
=
null
;
...
...
@@ -799,7 +827,8 @@ public class MVStore {
return
currentVersion
;
}
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
;
long
storeVersion
=
currentStoreVersion
=
currentVersion
;
...
...
@@ -893,7 +922,8 @@ public class MVStore {
if
(
ASSERT
)
{
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 {
c
.
pageCountLive
+=
f
.
pageCountLive
;
if
(
c
.
pageCountLive
<
0
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_INTERNAL
,
"Corrupt page count {0}"
,
c
.
pageCountLive
);
}
if
(
c
.
maxLengthLive
<
0
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_INTERNAL
,
"Corrupt max length {0}"
,
c
.
maxLengthLive
);
}
if
(
c
.
pageCount
==
0
&&
c
.
maxLengthLive
>
0
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_INTERNAL
,
"Corrupt max length {0}"
,
c
.
maxLengthLive
);
}
modified
.
add
(
c
);
...
...
@@ -1060,6 +1093,7 @@ public class MVStore {
file
.
truncate
(
used
);
}
catch
(
IOException
e
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_WRITING_FAILED
,
"Could not truncate file {0} to size {1}"
,
fileName
,
used
,
e
);
}
...
...
@@ -1259,6 +1293,7 @@ public class MVStore {
Chunk
c
=
getChunk
(
pos
);
if
(
c
==
null
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_FILE_CORRUPT
,
"Chunk {0} not found"
,
DataUtils
.
getPageChunkId
(
pos
));
}
...
...
@@ -1682,7 +1717,8 @@ public class MVStore {
private
void
checkOpen
()
{
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 {
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
()
{
return
readOnly
;
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/Page.java
浏览文件 @
769193eb
...
...
@@ -429,6 +429,7 @@ public class Page {
}
if
(
check
!=
totalCount
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_INTERNAL
,
"Expected: {0} got: {1}"
,
check
,
totalCount
);
}
}
...
...
@@ -694,6 +695,7 @@ public class Page {
int
pageLength
=
buff
.
getInt
();
if
(
pageLength
>
maxLength
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_FILE_CORRUPT
,
"File corrupted, expected length =< {0}, got {1}"
,
maxLength
,
pageLength
);
}
...
...
@@ -701,6 +703,7 @@ public class Page {
int
mapId
=
DataUtils
.
readVarInt
(
buff
);
if
(
mapId
!=
map
.
getId
())
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_FILE_CORRUPT
,
"File corrupted, expected map id {0}, got {1}"
,
map
.
getId
(),
mapId
);
}
...
...
@@ -709,6 +712,7 @@ public class Page {
^
DataUtils
.
getCheckValue
(
pageLength
);
if
(
check
!=
(
short
)
checkTest
)
{
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_FILE_CORRUPT
,
"File corrupted, expected check value {0}, got {1}"
,
checkTest
,
check
);
}
...
...
@@ -818,7 +822,8 @@ public class Page {
^
DataUtils
.
getCheckValue
(
pageLength
);
buff
.
putShort
(
start
+
4
,
(
short
)
check
);
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
);
long
max
=
DataUtils
.
getPageMaxLength
(
pos
);
...
...
@@ -901,7 +906,8 @@ public class Page {
public
int
getMemory
()
{
if
(
MVStore
.
ASSERT
)
{
if
(
memory
!=
calculateMemory
())
{
throw
DataUtils
.
newIllegalStateException
(
"Memory calculation error"
);
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_INTERNAL
,
"Memory calculation error"
);
}
}
return
memory
;
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/db/MVTableEngine.java
浏览文件 @
769193eb
...
...
@@ -11,13 +11,16 @@ import java.util.List;
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.engine.Session
;
import
org.h2.message.DbException
;
import
org.h2.mvstore.DataUtils
;
import
org.h2.mvstore.MVStore
;
import
org.h2.mvstore.db.TransactionStore.Transaction
;
import
org.h2.store.InDoubtTransaction
;
import
org.h2.store.fs.FileUtils
;
import
org.h2.table.RegularTable
;
import
org.h2.table.TableBase
;
import
org.h2.util.New
;
...
...
@@ -26,13 +29,14 @@ import org.h2.util.New;
* A table engine that internally uses the MVStore.
*/
public
class
MVTableEngine
implements
TableEngine
{
@Override
public
TableBase
createTable
(
CreateTableData
data
)
{
Database
db
=
data
.
session
.
getDatabase
();
if
(!
data
.
persistData
||
(
data
.
temporary
&&
!
data
.
persistIndexes
))
{
return
new
RegularTable
(
data
);
}
/**
* Initialize the MVStore.
*
* @param db the database
* @return the store
*/
public
static
Store
init
(
Database
db
)
{
Store
store
=
db
.
getMvStore
();
if
(
store
==
null
)
{
byte
[]
key
=
db
.
getFilePasswordHash
();
...
...
@@ -41,9 +45,19 @@ public class MVTableEngine implements TableEngine {
if
(
dbPath
==
null
)
{
store
=
new
Store
(
db
,
builder
.
open
());
}
else
{
builder
.
fileName
(
dbPath
+
Constants
.
SUFFIX_MV_FILE
);
String
fileName
=
dbPath
+
Constants
.
SUFFIX_MV_FILE
;
builder
.
fileName
(
fileName
);
if
(
db
.
isReadOnly
())
{
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
)
{
char
[]
password
=
new
char
[
key
.
length
];
...
...
@@ -52,10 +66,32 @@ public class MVTableEngine implements TableEngine {
}
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
);
}
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
);
store
.
openTables
.
add
(
table
);
table
.
init
(
data
.
session
);
...
...
@@ -188,6 +224,10 @@ public class MVTableEngine implements TableEngine {
return
result
;
}
public
void
setCacheSize
(
int
kb
)
{
store
.
setCacheSize
(
kb
*
1024
);
}
}
/**
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/db/TransactionStore.java
浏览文件 @
769193eb
...
...
@@ -111,7 +111,9 @@ public class TransactionStore {
}
Long
lastKey
=
preparedTransactions
.
lastKey
();
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
)
{
long
[]
key
=
undoLog
.
firstKey
();
...
...
@@ -616,7 +618,8 @@ public class TransactionStore {
*/
void
checkNotClosed
()
{
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 {
// wait until it is committed, or until the lock timeout
long
timeout
=
transaction
.
store
.
lockTimeout
;
if
(
timeout
==
0
)
{
throw
DataUtils
.
newIllegalStateException
(
"Lock timeout"
);
throw
DataUtils
.
newIllegalStateException
(
DataUtils
.
ERROR_TRANSACTION_LOCK_TIMEOUT
,
"Lock timeout"
);
}
if
(
start
==
0
)
{
start
=
System
.
currentTimeMillis
();
}
else
{
long
t
=
System
.
currentTimeMillis
()
-
start
;
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
try
{
...
...
This diff is collapsed.
Click to expand it.
h2/src/main/org/h2/mvstore/rtree/MVRTreeMap.java
浏览文件 @
769193eb
差异被折叠。
点击展开。
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论