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

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

上级 b3d3defd
......@@ -20,7 +20,8 @@ Change Log
<h1>Change Log</h1>
<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>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.
......
......@@ -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
*/
public Trace getTrace(String module) {
return traceSystem.getTrace(module);
public Trace getTrace(int moduleId) {
return traceSystem.getTrace(moduleId);
}
@Override
......
......@@ -40,12 +40,12 @@ public abstract class DbObjectBase implements DbObject {
* @param db the database
* @param objectId the object id
* @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,
String traceModule) {
int traceModuleId) {
this.database = db;
this.trace = db.getTrace(traceModule);
this.trace = db.getTrace(traceModuleId);
this.id = objectId;
this.objectName = name;
this.modificationId = db.getModificationMetaId();
......
......@@ -26,8 +26,8 @@ public abstract class RightOwner extends DbObjectBase {
private HashMap<DbObject, Right> grantedRights;
protected RightOwner(Database database, int id, String name,
String traceModule) {
initDbObjectBase(database, id, name, traceModule);
int traceModuleId) {
initDbObjectBase(database, id, name, traceModuleId);
}
/**
......
......@@ -855,11 +855,11 @@ public class Session extends SessionWithState {
if (trace != null && !closed) {
return trace;
}
String traceModuleName = Trace.JDBC + "[" + id + "]";
String traceModuleName = "jdbc[" + id + "]";
if (closed) {
return new TraceSystem(null).getTrace(traceModuleName);
}
trace = database.getTrace(traceModuleName);
trace = database.getTraceSystem().getTrace(traceModuleName);
return trace;
}
......
......@@ -34,7 +34,7 @@ public class JdbcDataSourceFactory implements ObjectFactory {
* The public constructor to create new factory objects.
*/
public JdbcDataSourceFactory() {
trace = getTraceSystem().getTrace("JDBCX");
trace = getTraceSystem().getTrace(Trace.JDBCX);
}
/**
......
......@@ -20,85 +20,116 @@ import org.h2.value.Value;
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 String module;
private final String lineSeparator;
private int traceLevel = TraceSystem.PARENT;
Trace(TraceWriter traceWriter, int moduleId) {
this(traceWriter, MODULE_NAMES[moduleId]);
}
Trace(TraceWriter traceWriter, String module) {
this.traceWriter = traceWriter;
this.module = module;
......
......@@ -10,14 +10,12 @@ import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicReferenceArray;
import org.h2.api.ErrorCode;
import org.h2.engine.Constants;
import org.h2.jdbc.JdbcSQLException;
import org.h2.store.fs.FileUtils;
import org.h2.util.IOUtils;
import org.h2.util.New;
/**
* The trace mechanism is the logging facility of this database. There is
......@@ -83,7 +81,8 @@ public class TraceSystem implements TraceWriter {
private int levelMax;
private int maxFileSize = DEFAULT_MAX_FILE_SIZE;
private String fileName;
private HashMap<String, Trace> traces;
private final AtomicReferenceArray<Trace> traces =
new AtomicReferenceArray<Trace>(Trace.MODULE_NAMES.length);
private SimpleDateFormat dateFormat;
private Writer fileWriter;
private PrintWriter printWriter;
......@@ -117,28 +116,34 @@ public class TraceSystem implements TraceWriter {
}
/**
* Get or create a trace object for this module. Trace modules with names
* such as "JDBC[1]" are not cached (modules where the name ends with "]").
* All others are cached.
* Get or create a trace object for this module id. Trace modules with id
* are cached.
*
* @param module the module name
* @param moduleId module id
* @return the trace object
*/
public synchronized Trace getTrace(String module) {
if (module.endsWith("]")) {
return new Trace(writer, module);
}
if (traces == null) {
traces = New.hashMap(16);
}
Trace t = traces.get(module);
public Trace getTrace(int moduleId) {
Trace t = traces.get(moduleId);
if (t == null) {
t = new Trace(writer, module);
traces.put(module, t);
t = new Trace(writer, moduleId);
if (!traces.compareAndSet(moduleId, null, t)) {
t = traces.get(moduleId);
}
}
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
public boolean isEnabled(int level) {
return level <= this.levelMax;
......@@ -214,6 +219,11 @@ public class TraceSystem implements TraceWriter {
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
public void write(int level, String module, String s, Throwable t) {
if (level <= levelSystemOut || level > this.levelMax) {
......
......@@ -30,6 +30,17 @@ interface TraceWriter {
*/
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.
*
......
......@@ -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
public void write(int level, String module, String s, Throwable t) {
if (isEnabled(level)) {
......
......@@ -21,11 +21,11 @@ public abstract class SchemaObjectBase extends DbObjectBase implements
* @param newSchema the schema
* @param id the object id
* @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,
String traceModule) {
initDbObjectBase(newSchema.getDatabase(), id, name, traceModule);
int traceModuleId) {
initDbObjectBase(newSchema.getDatabase(), id, name, traceModuleId);
this.schema = newSchema;
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论