提交 36f3c9ef authored 作者: Thomas Mueller's avatar Thomas Mueller

Formatting, javadocs

上级 c4af37cd
...@@ -32,21 +32,24 @@ import org.h2.value.ValueLob; ...@@ -32,21 +32,24 @@ import org.h2.value.ValueLob;
import org.h2.value.ValueLobDb; import org.h2.value.ValueLobDb;
/** /**
* This class stores LOB objects in the database. * This class stores LOB objects in the database. This is the back-end i.e. the
* This is the back-end i.e. the server side of the LOB storage. * server side of the LOB storage.
* <p> * <p>
* Using the system session * Using the system session
* <p> * <p>
* Why do we use the system session to store the data? Some LOB operations can take a very long time. * Why do we use the system session to store the data? Some LOB operations can
* If we did them on a normal session, we would be locking the LOB tables for long periods of time, * take a very long time. If we did them on a normal session, we would be
* which is extremely detrimental to the rest of the system. * locking the LOB tables for long periods of time, which is extremely
* Perhaps when we shift to the MVStore engine, we can revisit this design decision. * detrimental to the rest of the system. Perhaps when we shift to the MVStore
* engine, we can revisit this design decision.
* <p> * <p>
* Locking Discussion * Locking Discussion
* <p> * <p>
* Normally, the locking order in H2 is: first lock the Session object, then lock the Database object. * Normally, the locking order in H2 is: first lock the Session object, then
* However, in the case of the LOB data, we are using the system session to store the data. * lock the Database object. However, in the case of the LOB data, we are using
* If we locked the normal way, we see deadlocks caused by the following pattern: * the system session to store the data. If we locked the normal way, we see
* deadlocks caused by the following pattern:
*
* <pre> * <pre>
* Thread 1: * Thread 1:
* locks normal session * locks normal session
...@@ -56,9 +59,11 @@ import org.h2.value.ValueLobDb; ...@@ -56,9 +59,11 @@ import org.h2.value.ValueLobDb;
* locks system session * locks system session
* waiting to lock database. * waiting to lock database.
* </pre> * </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. * So, in this class alone, we do two things: we have our very own dedicated
* Since we own the LOB session, no-one else can lock on it, and we are safe. * 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 { public class LobStorageBackend implements LobStorageInterface {
...@@ -389,12 +394,14 @@ public class LobStorageBackend implements LobStorageInterface { ...@@ -389,12 +394,14 @@ public class LobStorageBackend implements LobStorageInterface {
small = new byte[0]; small = new byte[0];
} }
if (small != null) { 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(); long precision = countingReaderForClob == null ? small.length : countingReaderForClob.getLength();
ValueLobDb v = ValueLobDb.createSmallLob(type, small, precision); ValueLobDb v = ValueLobDb.createSmallLob(type, small, precision);
return v; 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(); long precision = countingReaderForClob == null ? length : countingReaderForClob.getLength();
return registerLob(type, lobId, LobStorageFrontend.TABLE_TEMP, length, precision); return registerLob(type, lobId, LobStorageFrontend.TABLE_TEMP, length, precision);
} catch (IOException e) { } catch (IOException e) {
...@@ -592,6 +599,11 @@ public class LobStorageBackend implements LobStorageInterface { ...@@ -592,6 +599,11 @@ public class LobStorageBackend implements LobStorageInterface {
} }
} }
/**
* Check whether this thread has synchronized on this object.
*
* @param lock the object
*/
static void assertHoldsLock(Object lock) { static void assertHoldsLock(Object lock) {
if (!Thread.holdsLock(lock)) { if (!Thread.holdsLock(lock)) {
throw DbException.throwInternalError(); throw DbException.throwInternalError();
......
...@@ -44,6 +44,9 @@ import javax.tools.ToolProvider; ...@@ -44,6 +44,9 @@ import javax.tools.ToolProvider;
*/ */
public class SourceCompiler { public class SourceCompiler {
/**
* The "com.sun.tools.javac.Main" (if available).
*/
static final JavaCompiler JAVA_COMPILER; static final JavaCompiler JAVA_COMPILER;
private static final Class<?> JAVAC_SUN; private static final Class<?> JAVAC_SUN;
...@@ -60,6 +63,9 @@ public class SourceCompiler { ...@@ -60,6 +63,9 @@ public class SourceCompiler {
*/ */
final HashMap<String, Class<?>> compiled = New.hashMap(); final HashMap<String, Class<?>> compiled = New.hashMap();
/**
* Whether to use the ToolProvider.getSystemJavaCompiler().
*/
boolean useJavaSystemCompiler = SysProperties.JAVA_SYSTEM_COMPILER; boolean useJavaSystemCompiler = SysProperties.JAVA_SYSTEM_COMPILER;
static { static {
...@@ -222,6 +228,15 @@ public class SourceCompiler { ...@@ -222,6 +228,15 @@ public class SourceCompiler {
} }
} }
/**
* 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) { static String getCompleteSourceCode(String packageName, String className, String source) {
if (source.startsWith("package ")) { if (source.startsWith("package ")) {
return source; return source;
...@@ -247,6 +262,14 @@ public class SourceCompiler { ...@@ -247,6 +262,14 @@ public class SourceCompiler {
return buff.toString(); 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) { Class<?> javaxToolsJavac(String packageName, String className, String source) {
String fullClassName = packageName + "." + className; String fullClassName = packageName + "." + className;
StringWriter writer = new StringWriter(); StringWriter writer = new StringWriter();
...@@ -427,7 +450,7 @@ public class SourceCompiler { ...@@ -427,7 +450,7 @@ public class SourceCompiler {
*/ */
static class JavaClassObject extends SimpleJavaFileObject { static class JavaClassObject extends SimpleJavaFileObject {
protected final ByteArrayOutputStream out = new ByteArrayOutputStream(); private final ByteArrayOutputStream out = new ByteArrayOutputStream();
public JavaClassObject(String name, Kind kind) { public JavaClassObject(String name, Kind kind) {
super(URI.create("string:///" + name.replace('.', '/') super(URI.create("string:///" + name.replace('.', '/')
...@@ -449,6 +472,9 @@ public class SourceCompiler { ...@@ -449,6 +472,9 @@ public class SourceCompiler {
*/ */
static class ClassFileManager extends ForwardingJavaFileManager<StandardJavaFileManager> { static class ClassFileManager extends ForwardingJavaFileManager<StandardJavaFileManager> {
/**
* The class (only one class is kept).
*/
JavaClassObject classObject; JavaClassObject classObject;
public ClassFileManager(StandardJavaFileManager standardManager) { public ClassFileManager(StandardJavaFileManager standardManager) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论