提交 771c08fe authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 8c20d4bd
......@@ -40,7 +40,15 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<h3>Version 1.0 (Current)</h3>
<h3>Version 1.0.x (2007-09-x)</h3><ul>
<li>Using spaces in column and table aliases was not supported when used inside a view or temporary view.
<li>After deleting data, empty space in the database files was not efficiently reused
(but it was reused when opening the database). This has been fixed.
</li><li>About 230 bytes per database was leaked. This is a problem for applications
opening and closing many thousand databases. The main problem: a shutdown hook
was added but never removed. Fixed. In JDK 1.4, there is an additionally problem,
see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4197876.
A workaround has been implemented.
</li><li>Optimization for COLUMN IN(.., NULL) if the column does not allow NULL values.
</li><li>Using spaces in column and table aliases was not supported when used inside a view or temporary view.
</li><li>The version (build) number is now included in the manifest file.
</li><li>In some systems, SecureRandom.generateSeed is very slow (taking one minute or more).
For those cases, an alternative method is used that takes less than one second.
......@@ -730,6 +738,12 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
</li><li>Support indexes for views (probably requires materialized views)
</li><li>Linked tables that point to the same database should share the connection
</li><li>Use log for rollback
</li><li>Document SET SEARCH_PATH, BEGIN, EXECUTE, $ parameters
</li><li>Complete Javadocs for ErrorCode messages and add to docs
</li><li>Browser: use Desktop.isDesktopSupported and browse when using JDK 1.6
</li><li>Document org.h2.samples.MixedMode
</li><li>Server: use one listener (detect if the request comes from an PG or TCP client)
</li><li>Store dates as 'local'. Existing files use GMT. Use escape syntax for backward compatiblity)
</li></ul>
<h3>Not Planned</h3>
......
......@@ -137,6 +137,7 @@ public class Database implements DataHandler {
private String accessModeLog, accessModeData;
private boolean referentialIntegrity = true;
private boolean multiVersion;
private DatabaseCloser closeOnExit;
public Database(String name, ConnectionInfo ci, String cipher) throws SQLException {
this.compareMode = new CompareMode(null, null);
......@@ -180,7 +181,7 @@ public class Database implements DataHandler {
open(traceLevelFile, traceLevelSystemOut);
}
if (closeAtVmShutdown) {
DatabaseCloser closeOnExit = new DatabaseCloser(this, 0, true);
closeOnExit = new DatabaseCloser(this, 0, true);
try {
Runtime.getRuntime().addShutdownHook(closeOnExit);
} catch (IllegalStateException e) {
......@@ -841,6 +842,15 @@ public class Database implements DataHandler {
}
traceSystem.getTrace(Trace.DATABASE).info("closed");
traceSystem.close();
if (closeOnExit != null) {
closeOnExit.reset();
try {
Runtime.getRuntime().removeShutdownHook(closeOnExit);
} catch (IllegalStateException e) {
// ignore
}
closeOnExit = null;
}
Engine.getInstance().close(databaseName);
if (deleteFilesOnDisconnect && persistent) {
deleteFilesOnDisconnect = false;
......
......@@ -11,6 +11,7 @@ public class DatabaseCloser extends Thread {
private final boolean shutdownHook;
private volatile WeakReference databaseRef;
private int delayInMillis;
private boolean stopImmediately;
DatabaseCloser(Database db, int delayInMillis, boolean shutdownHook) {
this.databaseRef = new WeakReference(db);
......@@ -22,9 +23,19 @@ public class DatabaseCloser extends Thread {
synchronized (this) {
databaseRef = null;
}
if (getThreadGroup().activeCount() > 100) {
// in JDK 1.4 and below, all Thread objects are added to the ThreadGroup,
// and cause a memory leak if never started.
// Need to start it, otherwise it leaks memory in JDK 1.4 and below
stopImmediately = true;
start();
}
}
public void run() {
if (stopImmediately) {
return;
}
while (delayInMillis > 0) {
try {
int step = 100;
......
......@@ -56,9 +56,6 @@ merge into pg_catalog.pg_type values(
0
);
create view pg_catalog.pg_class -- (oid, relname, relnamespace, relkind, relam, reltuples, relpages, relhasrules, relhasoids)
as
select
......
......@@ -185,7 +185,7 @@ public class DiskFile implements CacheWriter {
}
}
private boolean isPageFree(int page) {
boolean isPageFree(int page) {
for (int i = page * BLOCKS_PER_PAGE; i < (page + 1) * BLOCKS_PER_PAGE; i++) {
if (used.get(i)) {
return false;
......@@ -500,8 +500,7 @@ public class DiskFile implements CacheWriter {
for (int i = pos; i < pos + blockCount; i++) {
used.clear(i);
if ((i % BLOCKS_PER_PAGE == 0) && (pos + blockCount >= i + BLOCKS_PER_PAGE)) {
// if this is the first page of a block and if the whole page is
// free
// if this is the first page of a block and if the whole page is free
setPageOwner(getPage(i), -1);
}
}
......
......@@ -37,6 +37,7 @@ public class Storage {
private int id;
private Database database;
private DataPage dummy;
private int pageCheckIndex;
public Storage(Database database, DiskFile file, RecordReader reader, int id) {
this.database = database;
......@@ -133,6 +134,7 @@ public class Storage {
}
public void removeRecord(Session session, int pos) throws SQLException {
checkOnePage();
Record record = getRecord(session, pos);
if (SysProperties.CHECK && record.getDeleted()) {
throw Message.getInternalError("duplicate delete " + pos);
......@@ -144,10 +146,6 @@ public class Storage {
file.removeRecord(session, pos, record, blockCount);
}
public void removeRecord(Session session, int pos, int blockCount) throws SQLException {
}
private boolean isFreeAndMine(int pos, int blocks) {
BitField used = file.getUsed();
for (int i = blocks + pos - 1; i >= pos; i--) {
......@@ -255,4 +253,23 @@ public class Storage {
pages.removeValue(i);
}
private int test;
//private static long totalCheck;
private void checkOnePage() throws SQLException {
// if(true) return;
//long time = System.currentTimeMillis();
pageCheckIndex = (pageCheckIndex + 1) % pages.size();
int page = pages.get(pageCheckIndex);
if (file.isPageFree(page)) {
//System.out.println("found one! " + page);
file.setPageOwner(page, -1);
}
//time = System.currentTimeMillis() - time;
//totalCheck+= time;
//if(totalCheck > 1000) {
// System.out.println("##took one second");
// totalCheck--;
//}
}
}
......@@ -251,7 +251,9 @@ public class TableFilter implements ColumnResolver {
if (alwaysFalse) {
state = AFTER_LAST;
} else {
scanCount++;
if ((++scanCount & 4095) == 0) {
logScanCount();
}
if (cursor.next()) {
currentSearchRow = cursor.getSearchRow();
current = null;
......@@ -301,6 +303,10 @@ public class TableFilter implements ColumnResolver {
return false;
}
private void logScanCount() {
// System.out.println(this.alias+ " " + table.getName() + ": " + scanCount);
}
private boolean isOk(Expression condition) throws SQLException {
if (condition == null) {
return true;
......
......@@ -43,9 +43,7 @@ public class Csv implements SimpleRowSource {
private char fieldDelimiter = '\"';
private char escapeCharacter = '\"';
private String fileName;
private InputStream in;
private Reader reader;
private OutputStream out;
private PrintWriter writer;
private int back;
private boolean endOfLine, endOfFile;
......@@ -226,9 +224,9 @@ public class Csv implements SimpleRowSource {
private void initWrite() throws IOException {
if (writer == null) {
try {
out = new FileOutputStream(fileName);
BufferedOutputStream o = new BufferedOutputStream(out, bufferSize);
writer = new PrintWriter(new OutputStreamWriter(o, charset));
OutputStream out = new FileOutputStream(fileName);
out = new BufferedOutputStream(out, bufferSize);
writer = new PrintWriter(new OutputStreamWriter(out, charset));
// TODO performance: what is faster? one, two, or both?
// writer = new PrintWriter(new BufferedWriter(new
// OutputStreamWriter(out, encoding), bufferSize));
......@@ -287,12 +285,11 @@ public class Csv implements SimpleRowSource {
private void initRead() throws IOException {
if (reader == null) {
try {
in = FileUtils.openFileInputStream(fileName);
BufferedInputStream i = new BufferedInputStream(in, bufferSize);
reader = new InputStreamReader(i, charset);
InputStream in = FileUtils.openFileInputStream(fileName);
in = new BufferedInputStream(in, bufferSize);
reader = new InputStreamReader(in, charset);
// TODO what is faster, 1, 2, 1+2
// reader = new BufferedReader(new InputStreamReader(in,
// encoding), bufferSize);
// reader = new BufferedReader(new InputStreamReader(in, encoding), bufferSize);
} catch (IOException e) {
close();
throw e;
......@@ -500,12 +497,8 @@ public class Csv implements SimpleRowSource {
public void close() {
IOUtils.closeSilently(reader);
reader = null;
IOUtils.closeSilently(in);
in = null;
IOUtils.closeSilently(writer);
writer = null;
IOUtils.closeSilently(out);
out = null;
}
/**
......
......@@ -22,6 +22,7 @@ import org.h2.engine.Constants;
import org.h2.message.Message;
import org.h2.util.ClassUtils;
import org.h2.util.FileUtils;
import org.h2.util.IOUtils;
import org.h2.util.ObjectUtils;
import org.h2.util.JdbcUtils;
import org.h2.util.ScriptReader;
......@@ -159,11 +160,11 @@ public class RunScript {
InputStream in = FileUtils.openFileInputStream(fileName);
String path = FileUtils.getParent(fileName);
try {
BufferedInputStream bin = new BufferedInputStream(in, Constants.IO_BUFFER_SIZE);
InputStreamReader reader = new InputStreamReader(bin, charsetName);
in = new BufferedInputStream(in, Constants.IO_BUFFER_SIZE);
InputStreamReader reader = new InputStreamReader(in, charsetName);
execute(conn, threadMap, continueOnError, path, reader, charsetName);
} finally {
in.close();
IOUtils.closeSilently(in);
}
}
......
......@@ -148,49 +148,9 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript
/*
SYSDATE sollte CURRENT_TIMESTAMP
support Trunc(Sysdate),...
public static String chr(int code) {
return String.valueOf((char) code);
}
public static Object nvl(Object value, Object ifNull) {
return (value != null) ? value : ifNull;
}
public static Object nvl2(Object value, Object notNull, Object ifNull) {
return (value != null) ? notNull : ifNull;
}
public static Timestamp sysdate() {
return new Timestamp(System.currentTimeMillis());
}
public static String to_char(Object what, String format) {
throw new Error("not yet"); // @todo check format
}
public static Date to_date(Object what, String format) {
throw new Error("not yet"); // @todo check format
}
public static Number to_number(String str) {
return new Double(str);
}
public static java.sql.Date trunc(Timestamp tsp) {
return new java.sql.Date(tsp.getTime());
}
public static Object trunc(Object what, String format) {
System.out.println("*** trunc ***");
if (what == null)
return null;
else if (what instanceof Date) {
System.out.println("*** date-format = " + format);
return Timestamp.valueOf("1963-03-27 12:34:56.0");
} else if (what instanceof Number) {
System.out.println("*** number-format = " + format);
return new Double(123.456D);
} else
throw new ClassCastException("number or date expected");
}
database files grow when updating data
slow:
select ta.attname, ia.attnum, ic.relname
from pg_catalog.pg_attribute ta, pg_catalog.pg_attribute ia, pg_catalog.pg_class ic, pg_catalog.pg_index i, pg_catalog.pg_namespace n
where ic.relname = 'dummy_pkey'
......@@ -204,51 +164,10 @@ AND (NOT ta.attisdropped)
AND (NOT ia.attisdropped)
order by ia.attnum;
database files grow when updating data
change default for in-memory undo
japanese topics in the javascript search
feature request: optimization for
where link_id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
with NULL and LINK_ID doesn't allow nulls
slow power off test: slow memFS?
DROP TABLE ONE;
DROP TABLE TWO;
CREATE TABLE ONE(A INT PRIMARY KEY, B INT);
INSERT INTO ONE VALUES(0, NULL);
INSERT INTO ONE VALUES(1, 0);
INSERT INTO ONE VALUES(2, 1);
INSERT INTO ONE VALUES(3, 4);
CREATE TABLE TWO(A INT PRIMARY KEY, B INT);
INSERT INTO TWO VALUES(0, NULL);
INSERT INTO TWO VALUES(1, 0);
INSERT INTO TWO VALUES(2, 2);
INSERT INTO TWO VALUES(3, 3);
INSERT INTO TWO VALUES(4, NULL);
SELECT * FROM ONE A LEFT JOIN ONE B ON NOT A.A=A.A;
SELECT T0.A FROM TWO T0 WHERE NOT ((T0.B=T0.A ) AND (T0.B=0 )) AND (T0.B IS NULL );
SELECT T0.A, T1.A, T2.A, T3.A FROM ONE T0 LEFT JOIN ONE T1 ON NOT T0.B=T0.B LEFT JOIN ONE T2 ON T1.A=T2.A LEFT JOIN ONE T3 ON (T3.B=0 ) OR (T2.A<-1 );
SELECT T0.A, T1.A, T2.A, T3.A FROM TWO T0 LEFT JOIN ONE T1 ON T0.B<T0.A LEFT JOIN ONE T2 ON T1.A=T2.A LEFT JOIN TWO T3 ON (T2.A=T3.A ) OR (T3.B=0 );
SELECT T0.A, T1.A, T2.A, T3.A FROM TWO T0 LEFT JOIN ONE T1 ON T0.B>2 LEFT JOIN ONE T2 ON T1.A=T2.A LEFT JOIN TWO T3 ON T2.A IS NULL;
SELECT T0.A, T1.A FROM TWO T0 INNER JOIN TWO T1 ON NOT (((T0.A=T0.B ) AND (T0.B=0 )) OR (T0.A=T1.A )) OR (T0.A=T0.B );
SELECT T0.A, T1.A FROM ONE T0 INNER JOIN ONE T1 ON NOT ((T0.A=T0.B ) AND (T0.B=1 )) OR (T0.B=2 );
document:
maximum file size increment is 16 MB
dont increase database size by more than 128 MB
DROP TABLE IF EXISTS TEST;
CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR);
@LOOP 1000000 INSERT INTO TEST VALUES(?, SPACE(100000));
......@@ -266,15 +185,11 @@ add MVCC
don't create @~ of not translated
improve documentation of 'mixed mode' usage.
test performance and document fulltext search
clustered tables: test, document
search for japanese: works, but is it ok?
pdf: first page looks empty (because the top part is empty) - title on the top?
pdf / openoffice: pictures don't work?
extend tests that simulate power off
......@@ -330,27 +245,16 @@ Test Eclipse DTP 1.5 (HSQLDB / H2 connection bug fixed)
Automate real power off tests
Negative dictionary:
Please note that
Merge more from diff.zip (Pavel Ganelin)
Integrate patches from Pavel Ganelin: www.dullesopen.com/software/h2-database-03-04-07-mod.src.zip
store dates as 'local'. Problem: existing files use GMT (use escape syntax)
drop table test;
CREATE TABLE TEST( ID BIGINT PRIMARY KEY, CREATED TIMESTAMP);
INSERT INTO TEST VALUES(1, '2007-01-01 00:00:00');
SELECT * FROM TEST;
Server: use one listener (detect if the request comes from an PG or TCP client).
http://fastutil.dsi.unimi.it/
http://javolution.org/
http://joda-time.sourceforge.net/
http://ibatis.apache.org/
Document org.h2.samples.MixedMode
http://www.igniterealtime.org/projects/openfire/index.jsp
translation:
......@@ -366,15 +270,47 @@ translated .pdf
docs: xml:lang="en" > correct language (and detect wrong language based on _ja)
docs: xhtml: use UTF-8 encoding (<?xml version="1.0"?>)
io: wrapped streams are closed: simplify code
document SET SEARCH_PATH, BEGIN, EXECUTE, $ parameters
Complete Javadocs for Messages and add to docs
write tests using the PostgreSQL JDBC driver
JDK 1.6: Desktop.isDesktopSupported, browse(URI uri)
SYSDATE sollte CURRENT_TIMESTAMP
support Trunc(Sysdate),...
public static String chr(int code) {
return String.valueOf((char) code);
}
public static Object nvl(Object value, Object ifNull) {
return (value != null) ? value : ifNull;
}
public static Object nvl2(Object value, Object notNull, Object ifNull) {
return (value != null) ? notNull : ifNull;
}
public static Timestamp sysdate() {
return new Timestamp(System.currentTimeMillis());
}
public static String to_char(Object what, String format) {
throw new Error("not yet"); // @todo check format
}
public static Date to_date(Object what, String format) {
throw new Error("not yet"); // @todo check format
}
public static Number to_number(String str) {
return new Double(str);
}
public static java.sql.Date trunc(Timestamp tsp) {
return new java.sql.Date(tsp.getTime());
}
public static Object trunc(Object what, String format) {
System.out.println("*** trunc ***");
if (what == null)
return null;
else if (what instanceof Date) {
System.out.println("*** date-format = " + format);
return Timestamp.valueOf("1963-03-27 12:34:56.0");
} else if (what instanceof Number) {
System.out.println("*** number-format = " + format);
return new Double(123.456D);
} else
throw new ClassCastException("number or date expected");
}
*/
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论