Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
36f3c9ef
提交
36f3c9ef
authored
9月 23, 2013
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Formatting, javadocs
上级
c4af37cd
隐藏空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
87 行增加
和
49 行删除
+87
-49
LobStorageBackend.java
h2/src/main/org/h2/store/LobStorageBackend.java
+29
-17
FilePathCrypt.java
h2/src/main/org/h2/store/fs/FilePathCrypt.java
+1
-1
Table.java
h2/src/main/org/h2/table/Table.java
+1
-1
MultiDimension.java
h2/src/main/org/h2/tools/MultiDimension.java
+1
-1
SourceCompiler.java
h2/src/main/org/h2/util/SourceCompiler.java
+50
-24
ValueLob.java
h2/src/main/org/h2/value/ValueLob.java
+1
-1
ValueLobDb.java
h2/src/main/org/h2/value/ValueLobDb.java
+4
-4
没有找到文件。
h2/src/main/org/h2/store/LobStorageBackend.java
浏览文件 @
36f3c9ef
...
...
@@ -32,21 +32,24 @@ import org.h2.value.ValueLob;
import
org.h2.value.ValueLobDb
;
/**
* This class stores LOB objects in the database.
*
This is the back-end i.e. the
server side of the LOB storage.
* This class stores LOB objects in the database.
This is the back-end i.e. the
* server side of the LOB storage.
* <p>
* Using the system session
* <p>
* Why do we use the system session to store the data? Some LOB operations can take a very long time.
* If we did them on a normal session, we would be locking the LOB tables for long periods of time,
* which is extremely detrimental to the rest of the system.
* Perhaps when we shift to the MVStore engine, we can revisit this design decision.
* Why do we use the system session to store the data? Some LOB operations can
* take a very long time. If we did them on a normal session, we would be
* locking the LOB tables for long periods of time, which is extremely
* detrimental to the rest of the system. Perhaps when we shift to the MVStore
* engine, we can revisit this design decision.
* <p>
* Locking Discussion
* <p>
* Normally, the locking order in H2 is: first lock the Session object, then lock the Database object.
* However, in the case of the LOB data, we are using the system session to store the data.
* If we locked the normal way, we see deadlocks caused by the following pattern:
* Normally, the locking order in H2 is: first lock the Session object, then
* lock the Database object. However, in the case of the LOB data, we are using
* the system session to store the data. If we locked the normal way, we see
* deadlocks caused by the following pattern:
*
* <pre>
* Thread 1:
* locks normal session
...
...
@@ -56,9 +59,11 @@ import org.h2.value.ValueLobDb;
* locks system session
* waiting to lock database.
* </pre>
* So, in this class alone, we do two things: we have our very own dedicated session, the LOB session,
* and we take the locks in this order: first the Database object, and then the LOB session.
* Since we own the LOB session, no-one else can lock on it, and we are safe.
*
* So, in this class alone, we do two things: we have our very own dedicated
* session, the LOB session, and we take the locks in this order: first the
* Database object, and then the LOB session. Since we own the LOB session,
* no-one else can lock on it, and we are safe.
*/
public
class
LobStorageBackend
implements
LobStorageInterface
{
...
...
@@ -389,12 +394,14 @@ public class LobStorageBackend implements LobStorageInterface {
small
=
new
byte
[
0
];
}
if
(
small
!=
null
)
{
// For a BLOB, precision is length in bytes. For a CLOB, precision is length in chars
// For a BLOB, precision is length in bytes.
// For a CLOB, precision is length in chars
long
precision
=
countingReaderForClob
==
null
?
small
.
length
:
countingReaderForClob
.
getLength
();
ValueLobDb
v
=
ValueLobDb
.
createSmallLob
(
type
,
small
,
precision
);
return
v
;
}
// For a BLOB, precision is length in bytes. For a CLOB, precision is length in chars
// For a BLOB, precision is length in bytes.
// For a CLOB, precision is length in chars
long
precision
=
countingReaderForClob
==
null
?
length
:
countingReaderForClob
.
getLength
();
return
registerLob
(
type
,
lobId
,
LobStorageFrontend
.
TABLE_TEMP
,
length
,
precision
);
}
catch
(
IOException
e
)
{
...
...
@@ -585,19 +592,24 @@ public class LobStorageBackend implements LobStorageInterface {
}
}
}
private
static
void
assertNotHolds
(
Object
lock
)
{
if
(
Thread
.
holdsLock
(
lock
))
{
throw
DbException
.
throwInternalError
();
}
}
/**
* Check whether this thread has synchronized on this object.
*
* @param lock the object
*/
static
void
assertHoldsLock
(
Object
lock
)
{
if
(!
Thread
.
holdsLock
(
lock
))
{
throw
DbException
.
throwInternalError
();
}
}
/**
* An input stream that reads from a LOB.
*/
...
...
@@ -636,7 +648,7 @@ public class LobStorageBackend implements LobStorageInterface {
// before the lock on the database to prevent ABBA deadlocks
assertHoldsLock
(
conn
.
getSession
());
assertHoldsLock
(
database
);
if
(
byteCount
==
-
1
)
{
String
sql
=
"SELECT BYTE_COUNT FROM "
+
LOBS
+
" WHERE ID = ?"
;
PreparedStatement
prep
=
prepare
(
sql
);
...
...
h2/src/main/org/h2/store/fs/FilePathCrypt.java
浏览文件 @
36f3c9ef
...
...
@@ -104,7 +104,7 @@ public class FilePathCrypt extends FilePathWrapper {
/**
* Convert a char array to a byte array, in UTF-16 format. The char array is
* not cleared after use (this must be done by the caller).
*
*
* @param passwordChars the password characters
* @return the byte array
*/
...
...
h2/src/main/org/h2/table/Table.java
浏览文件 @
36f3c9ef
...
...
@@ -165,7 +165,7 @@ public abstract class Table extends SchemaObjectBase {
*/
public
abstract
Index
addIndex
(
Session
session
,
String
indexName
,
int
indexId
,
IndexColumn
[]
cols
,
IndexType
indexType
,
boolean
create
,
String
indexComment
);
/**
* Get the given row.
*
...
...
h2/src/main/org/h2/tools/MultiDimension.java
浏览文件 @
36f3c9ef
...
...
@@ -236,7 +236,7 @@ public class MultiDimension implements Comparator<long[]> {
/**
* Combine entries if the size of the list is too large.
*
* @param list list of pairs(low, high)
* @param list list of pairs(low, high)
* @param total product of the gap lengths
*/
private
void
combineEntries
(
ArrayList
<
long
[]>
list
,
int
total
)
{
...
...
h2/src/main/org/h2/util/SourceCompiler.java
浏览文件 @
36f3c9ef
...
...
@@ -44,12 +44,15 @@ import javax.tools.ToolProvider;
*/
public
class
SourceCompiler
{
/**
* The "com.sun.tools.javac.Main" (if available).
*/
static
final
JavaCompiler
JAVA_COMPILER
;
private
static
final
Class
<?>
JAVAC_SUN
;
private
static
final
String
COMPILE_DIR
=
Utils
.
getProperty
(
"java.io.tmpdir"
,
"."
);
/**
* The class name to source code map.
*/
...
...
@@ -59,7 +62,10 @@ public class SourceCompiler {
* The class name to byte code map.
*/
final
HashMap
<
String
,
Class
<?>>
compiled
=
New
.
hashMap
();
/**
* Whether to use the ToolProvider.getSystemJavaCompiler().
*/
boolean
useJavaSystemCompiler
=
SysProperties
.
JAVA_SYSTEM_COMPILER
;
static
{
...
...
@@ -91,10 +97,10 @@ public class SourceCompiler {
sources
.
put
(
className
,
source
);
compiled
.
clear
();
}
/**
* Enable or disable the usage of the Java system compiler.
*
*
* @param enabled true to enable
*/
public
void
setJavaSystemCompiler
(
boolean
enabled
)
{
...
...
@@ -221,7 +227,16 @@ public class SourceCompiler {
classFile
.
delete
();
}
}
/**
* Get the complete source code (including package name, imports, and so
* on).
*
* @param packageName the package name
* @param className the class name
* @param source the (possibly shortened) source code
* @return the full source code
*/
static
String
getCompleteSourceCode
(
String
packageName
,
String
className
,
String
source
)
{
if
(
source
.
startsWith
(
"package "
))
{
return
source
;
...
...
@@ -231,7 +246,7 @@ public class SourceCompiler {
buff
.
append
(
"package "
).
append
(
packageName
).
append
(
";\n"
);
}
int
endImport
=
source
.
indexOf
(
"@CODE"
);
String
importCode
=
String
importCode
=
"import java.util.*;\n"
+
"import java.math.*;\n"
+
"import java.sql.*;\n"
;
...
...
@@ -246,13 +261,21 @@ public class SourceCompiler {
"}\n"
);
return
buff
.
toString
();
}
/**
* Compile using the standard java compiler.
*
* @param packageName the package name
* @param className the class name
* @param source the source code
* @return the class
*/
Class
<?>
javaxToolsJavac
(
String
packageName
,
String
className
,
String
source
)
{
String
fullClassName
=
packageName
+
"."
+
className
;
StringWriter
writer
=
new
StringWriter
();
JavaFileManager
fileManager
=
new
ClassFileManager
(
JAVA_COMPILER
.
getStandardFileManager
(
null
,
null
,
null
));
.
getStandardFileManager
(
null
,
null
,
null
));
ArrayList
<
JavaFileObject
>
compilationUnits
=
new
ArrayList
<
JavaFileObject
>();
compilationUnits
.
add
(
new
StringJavaFileObject
(
fullClassName
,
source
));
JAVA_COMPILER
.
getTask
(
writer
,
fileManager
,
null
,
null
,
...
...
@@ -344,7 +367,7 @@ public class SourceCompiler {
* compile-time dependency unnecessarily.
*/
private
static
final
class
GroovyCompiler
{
private
static
final
Object
LOADER
;
private
static
final
Throwable
INIT_FAIL_EXCEPTION
;
...
...
@@ -358,12 +381,12 @@ public class SourceCompiler {
Object
importCustomizer
=
Utils
.
newInstance
(
"org.codehaus.groovy.control.customizers.ImportCustomizer"
);
// Call the method ImportCustomizer.addImports(String[])
String
[]
importsArray
=
new
String
[]
{
"java.sql.Connection"
,
"java.sql.Types"
,
String
[]
importsArray
=
new
String
[]
{
"java.sql.Connection"
,
"java.sql.Types"
,
"java.sql.ResultSet"
,
"groovy.sql.Sql"
,
"org.h2.tools.SimpleResultSet"
"groovy.sql.Sql"
,
"org.h2.tools.SimpleResultSet"
};
Utils
.
callMethod
(
importCustomizer
,
"addImports"
,
new
Object
[]
{
importsArray
});
...
...
@@ -373,7 +396,7 @@ public class SourceCompiler {
Array
.
set
(
importCustomizerArray
,
0
,
importCustomizer
);
Object
configuration
=
Utils
.
newInstance
(
"org.codehaus.groovy.control.CompilerConfiguration"
);
Utils
.
callMethod
(
configuration
,
Utils
.
callMethod
(
configuration
,
"addCompilationCustomizers"
,
new
Object
[]
{
importCustomizerArray
});
ClassLoader
parent
=
GroovyCompiler
.
class
.
getClassLoader
();
...
...
@@ -391,7 +414,7 @@ public class SourceCompiler {
throw
new
RuntimeException
(
"Compile fail: no Groovy jar in the classpath"
,
INIT_FAIL_EXCEPTION
);
}
try
{
Object
codeSource
=
Utils
.
newInstance
(
"groovy.lang.GroovyCodeSource"
,
Object
codeSource
=
Utils
.
newInstance
(
"groovy.lang.GroovyCodeSource"
,
source
,
packageAndClassName
+
".groovy"
,
"UTF-8"
);
Utils
.
callMethod
(
codeSource
,
"setCachable"
,
false
);
Class
<?>
clazz
=
(
Class
<?>)
Utils
.
callMethod
(
LOADER
,
"parseClass"
,
codeSource
);
...
...
@@ -401,7 +424,7 @@ public class SourceCompiler {
}
}
}
/**
* An in-memory java source file object.
*/
...
...
@@ -419,15 +442,15 @@ public class SourceCompiler {
public
CharSequence
getCharContent
(
boolean
ignoreEncodingErrors
)
{
return
sourceCode
;
}
}
/**
/**
* An in-memory java class object.
*/
static
class
JavaClassObject
extends
SimpleJavaFileObject
{
pr
otected
final
ByteArrayOutputStream
out
=
new
ByteArrayOutputStream
();
pr
ivate
final
ByteArrayOutputStream
out
=
new
ByteArrayOutputStream
();
public
JavaClassObject
(
String
name
,
Kind
kind
)
{
super
(
URI
.
create
(
"string:///"
+
name
.
replace
(
'.'
,
'/'
)
...
...
@@ -443,12 +466,15 @@ public class SourceCompiler {
return
out
;
}
}
/**
* An in-memory class file manager.
*/
static
class
ClassFileManager
extends
ForwardingJavaFileManager
<
StandardJavaFileManager
>
{
/**
* The class (only one class is kept).
*/
JavaClassObject
classObject
;
public
ClassFileManager
(
StandardJavaFileManager
standardManager
)
{
...
...
h2/src/main/org/h2/value/ValueLob.java
浏览文件 @
36f3c9ef
...
...
@@ -200,7 +200,7 @@ public class ValueLob extends Value {
long
m
=
compress
?
Constants
.
IO_BUFFER_SIZE_COMPRESS
:
Constants
.
IO_BUFFER_SIZE
;
if
(
m
<
remaining
&&
m
<=
inplace
)
{
// using "1L" to force long arithmetic
m
=
Math
.
min
(
remaining
,
inplace
+
1L
);
m
=
Math
.
min
(
remaining
,
inplace
+
1L
);
// the buffer size must be bigger than the inplace lob, otherwise we can't
// know if it must be stored in-place or not
m
=
MathUtils
.
roundUpLong
(
m
,
Constants
.
IO_BUFFER_SIZE
);
...
...
h2/src/main/org/h2/value/ValueLobDb.java
浏览文件 @
36f3c9ef
...
...
@@ -41,13 +41,13 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo
private
final
byte
[]
hmac
;
private
final
byte
[]
small
;
private
final
DataHandler
handler
;
/**
* For a BLOB, precision is length in bytes.
* For a CLOB, precision is length in chars.
*/
private
final
long
precision
;
private
final
String
fileName
;
private
final
FileStore
tempFile
;
private
int
tableId
;
...
...
@@ -121,7 +121,7 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo
}
this
.
precision
=
tmpPrecision
;
}
/**
* Create temporary BLOB from InputStream.
*/
...
...
@@ -157,7 +157,7 @@ public class ValueLobDb extends Value implements Value.ValueClob, Value.ValueBlo
}
this
.
precision
=
tmpPrecision
;
}
private
static
String
createTempLobFileName
(
DataHandler
handler
)
throws
IOException
{
String
path
=
handler
.
getDatabasePath
();
if
(
path
.
length
()
==
0
)
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论