提交 a6fd251f authored 作者: Thomas Mueller's avatar Thomas Mueller

Pull request #116: Improved concurrency in the trace system.

上级 b3d3defd
...@@ -20,7 +20,8 @@ Change Log ...@@ -20,7 +20,8 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>Issue 609: the spatial index did not support NULL. <ul><li>Pull request #116: Improved concurrency in the trace system.
</li><li>Issue 609: the spatial index did not support NULL.
</li><li>Granting a schema is now supported. </li><li>Granting a schema is now supported.
</li><li>Linked tables did not work when a function-based index is present (Oracle). </li><li>Linked tables did not work when a function-based index is present (Oracle).
</li><li>Creating a user with a null password, salt, or hash threw a NullPointerException. </li><li>Creating a user with a null password, salt, or hash threw a NullPointerException.
......
...@@ -510,13 +510,13 @@ public class Database implements DataHandler { ...@@ -510,13 +510,13 @@ public class Database implements DataHandler {
} }
/** /**
* Get the trace object for the given module. * Get the trace object for the given module id.
* *
* @param module the module name * @param moduleId the module id
* @return the trace object * @return the trace object
*/ */
public Trace getTrace(String module) { public Trace getTrace(int moduleId) {
return traceSystem.getTrace(module); return traceSystem.getTrace(moduleId);
} }
@Override @Override
......
...@@ -40,12 +40,12 @@ public abstract class DbObjectBase implements DbObject { ...@@ -40,12 +40,12 @@ public abstract class DbObjectBase implements DbObject {
* @param db the database * @param db the database
* @param objectId the object id * @param objectId the object id
* @param name the name * @param name the name
* @param traceModule the trace module name * @param traceModuleId the trace module id
*/ */
protected void initDbObjectBase(Database db, int objectId, String name, protected void initDbObjectBase(Database db, int objectId, String name,
String traceModule) { int traceModuleId) {
this.database = db; this.database = db;
this.trace = db.getTrace(traceModule); this.trace = db.getTrace(traceModuleId);
this.id = objectId; this.id = objectId;
this.objectName = name; this.objectName = name;
this.modificationId = db.getModificationMetaId(); this.modificationId = db.getModificationMetaId();
......
...@@ -26,8 +26,8 @@ public abstract class RightOwner extends DbObjectBase { ...@@ -26,8 +26,8 @@ public abstract class RightOwner extends DbObjectBase {
private HashMap<DbObject, Right> grantedRights; private HashMap<DbObject, Right> grantedRights;
protected RightOwner(Database database, int id, String name, protected RightOwner(Database database, int id, String name,
String traceModule) { int traceModuleId) {
initDbObjectBase(database, id, name, traceModule); initDbObjectBase(database, id, name, traceModuleId);
} }
/** /**
......
...@@ -855,11 +855,11 @@ public class Session extends SessionWithState { ...@@ -855,11 +855,11 @@ public class Session extends SessionWithState {
if (trace != null && !closed) { if (trace != null && !closed) {
return trace; return trace;
} }
String traceModuleName = Trace.JDBC + "[" + id + "]"; String traceModuleName = "jdbc[" + id + "]";
if (closed) { if (closed) {
return new TraceSystem(null).getTrace(traceModuleName); return new TraceSystem(null).getTrace(traceModuleName);
} }
trace = database.getTrace(traceModuleName); trace = database.getTraceSystem().getTrace(traceModuleName);
return trace; return trace;
} }
......
...@@ -34,7 +34,7 @@ public class JdbcDataSourceFactory implements ObjectFactory { ...@@ -34,7 +34,7 @@ public class JdbcDataSourceFactory implements ObjectFactory {
* The public constructor to create new factory objects. * The public constructor to create new factory objects.
*/ */
public JdbcDataSourceFactory() { public JdbcDataSourceFactory() {
trace = getTraceSystem().getTrace("JDBCX"); trace = getTraceSystem().getTrace(Trace.JDBCX);
} }
/** /**
......
...@@ -20,85 +20,116 @@ import org.h2.value.Value; ...@@ -20,85 +20,116 @@ import org.h2.value.Value;
public class Trace { public class Trace {
/** /**
* The trace module name for commands. * The trace module id for commands.
*/ */
public static final String COMMAND = "command"; public static final int COMMAND = 0;
/** /**
* The trace module name for constraints. * The trace module id for constraints.
*/ */
public static final String CONSTRAINT = "constraint"; public static final int CONSTRAINT = 1;
/** /**
* The trace module name for databases. * The trace module id for databases.
*/ */
public static final String DATABASE = "database"; public static final int DATABASE = 2;
/** /**
* The trace module name for functions. * The trace module id for functions.
*/ */
public static final String FUNCTION = "function"; public static final int FUNCTION = 3;
/** /**
* The trace module name for file locks. * The trace module id for file locks.
*/ */
public static final String FILE_LOCK = "fileLock"; public static final int FILE_LOCK = 4;
/** /**
* The trace module name for indexes. * The trace module id for indexes.
*/ */
public static final String INDEX = "index"; public static final int INDEX = 5;
/** /**
* The trace module name for the JDBC API. * The trace module id for the JDBC API.
*/ */
public static final String JDBC = "jdbc"; public static final int JDBC = 6;
/** /**
* The trace module name for locks. * The trace module id for locks.
*/ */
public static final String LOCK = "lock"; public static final int LOCK = 7;
/** /**
* The trace module name for schemas. * The trace module id for schemas.
*/ */
public static final String SCHEMA = "schema"; public static final int SCHEMA = 8;
/** /**
* The trace module name for sequences. * The trace module id for sequences.
*/ */
public static final String SEQUENCE = "sequence"; public static final int SEQUENCE = 9;
/** /**
* The trace module name for settings. * The trace module id for settings.
*/ */
public static final String SETTING = "setting"; public static final int SETTING = 10;
/** /**
* The trace module name for tables. * The trace module id for tables.
*/ */
public static final String TABLE = "table"; public static final int TABLE = 11;
/** /**
* The trace module name for triggers. * The trace module id for triggers.
*/ */
public static final String TRIGGER = "trigger"; public static final int TRIGGER = 12;
/** /**
* The trace module name for users. * The trace module id for users.
*/ */
public static final String USER = "user"; public static final int USER = 13;
/** /**
* The trace module name for the page store. * The trace module id for the page store.
*/ */
public static final String PAGE_STORE = "pageStore"; public static final int PAGE_STORE = 14;
/**
* The trace module id for the JDBCX API
*/
public static final int JDBCX = 15;
/**
* Module names by their ids as array indexes.
*/
public static final String[] MODULE_NAMES = {
"command",
"constraint",
"database",
"function",
"fileLock",
"index",
"jdbc",
"lock",
"schema",
"sequence",
"setting",
"table",
"trigger",
"user",
"pageStore",
"JDBCX"
};
private final TraceWriter traceWriter; private final TraceWriter traceWriter;
private final String module; private final String module;
private final String lineSeparator; private final String lineSeparator;
private int traceLevel = TraceSystem.PARENT; private int traceLevel = TraceSystem.PARENT;
Trace(TraceWriter traceWriter, int moduleId) {
this(traceWriter, MODULE_NAMES[moduleId]);
}
Trace(TraceWriter traceWriter, String module) { Trace(TraceWriter traceWriter, String module) {
this.traceWriter = traceWriter; this.traceWriter = traceWriter;
this.module = module; this.module = module;
......
...@@ -10,14 +10,12 @@ import java.io.PrintStream; ...@@ -10,14 +10,12 @@ import java.io.PrintStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.Writer; import java.io.Writer;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.HashMap; import java.util.concurrent.atomic.AtomicReferenceArray;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.jdbc.JdbcSQLException; import org.h2.jdbc.JdbcSQLException;
import org.h2.store.fs.FileUtils; import org.h2.store.fs.FileUtils;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
import org.h2.util.New;
/** /**
* The trace mechanism is the logging facility of this database. There is * The trace mechanism is the logging facility of this database. There is
...@@ -83,7 +81,8 @@ public class TraceSystem implements TraceWriter { ...@@ -83,7 +81,8 @@ public class TraceSystem implements TraceWriter {
private int levelMax; private int levelMax;
private int maxFileSize = DEFAULT_MAX_FILE_SIZE; private int maxFileSize = DEFAULT_MAX_FILE_SIZE;
private String fileName; private String fileName;
private HashMap<String, Trace> traces; private final AtomicReferenceArray<Trace> traces =
new AtomicReferenceArray<Trace>(Trace.MODULE_NAMES.length);
private SimpleDateFormat dateFormat; private SimpleDateFormat dateFormat;
private Writer fileWriter; private Writer fileWriter;
private PrintWriter printWriter; private PrintWriter printWriter;
...@@ -117,28 +116,34 @@ public class TraceSystem implements TraceWriter { ...@@ -117,28 +116,34 @@ public class TraceSystem implements TraceWriter {
} }
/** /**
* Get or create a trace object for this module. Trace modules with names * Get or create a trace object for this module id. Trace modules with id
* such as "JDBC[1]" are not cached (modules where the name ends with "]"). * are cached.
* All others are cached.
* *
* @param module the module name * @param moduleId module id
* @return the trace object * @return the trace object
*/ */
public synchronized Trace getTrace(String module) { public Trace getTrace(int moduleId) {
if (module.endsWith("]")) { Trace t = traces.get(moduleId);
return new Trace(writer, module);
}
if (traces == null) {
traces = New.hashMap(16);
}
Trace t = traces.get(module);
if (t == null) { if (t == null) {
t = new Trace(writer, module); t = new Trace(writer, moduleId);
traces.put(module, t); if (!traces.compareAndSet(moduleId, null, t)) {
t = traces.get(moduleId);
}
} }
return t; return t;
} }
/**
* Create a trace object for this module. Trace modules with names are not
* cached.
*
* @param module the module name
* @return the trace object
*/
public Trace getTrace(String module) {
return new Trace(writer, module);
}
@Override @Override
public boolean isEnabled(int level) { public boolean isEnabled(int level) {
return level <= this.levelMax; return level <= this.levelMax;
...@@ -214,6 +219,11 @@ public class TraceSystem implements TraceWriter { ...@@ -214,6 +219,11 @@ public class TraceSystem implements TraceWriter {
return dateFormat.format(System.currentTimeMillis()) + module + ": " + s; return dateFormat.format(System.currentTimeMillis()) + module + ": " + s;
} }
@Override
public void write(int level, int moduleId, String s, Throwable t) {
write(level, Trace.MODULE_NAMES[moduleId], s, t);
}
@Override @Override
public void write(int level, String module, String s, Throwable t) { public void write(int level, String module, String s, Throwable t) {
if (level <= levelSystemOut || level > this.levelMax) { if (level <= levelSystemOut || level > this.levelMax) {
......
...@@ -30,6 +30,17 @@ interface TraceWriter { ...@@ -30,6 +30,17 @@ interface TraceWriter {
*/ */
void write(int level, String module, String s, Throwable t); void write(int level, String module, String s, Throwable t);
/**
* Write a message.
*
* @param level the trace level
* @param moduleId the id of the module
* @param s the message
* @param t the exception (may be null)
*/
void write(int level, int moduleId, String s, Throwable t);
/** /**
* Check the given trace / log level is enabled. * Check the given trace / log level is enabled.
* *
......
...@@ -45,6 +45,11 @@ public class TraceWriterAdapter implements TraceWriter { ...@@ -45,6 +45,11 @@ public class TraceWriterAdapter implements TraceWriter {
} }
} }
@Override
public void write(int level, int moduleId, String s, Throwable t) {
write(level, Trace.MODULE_NAMES[moduleId], s, t);
};
@Override @Override
public void write(int level, String module, String s, Throwable t) { public void write(int level, String module, String s, Throwable t) {
if (isEnabled(level)) { if (isEnabled(level)) {
......
...@@ -21,11 +21,11 @@ public abstract class SchemaObjectBase extends DbObjectBase implements ...@@ -21,11 +21,11 @@ public abstract class SchemaObjectBase extends DbObjectBase implements
* @param newSchema the schema * @param newSchema the schema
* @param id the object id * @param id the object id
* @param name the name * @param name the name
* @param traceModule the trace module name * @param traceModuleId the trace module id
*/ */
protected void initSchemaObjectBase(Schema newSchema, int id, String name, protected void initSchemaObjectBase(Schema newSchema, int id, String name,
String traceModule) { int traceModuleId) {
initDbObjectBase(newSchema.getDatabase(), id, name, traceModule); initDbObjectBase(newSchema.getDatabase(), id, name, traceModuleId);
this.schema = newSchema; this.schema = newSchema;
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论