提交 6acd8d14 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 7b88d790
......@@ -395,6 +395,8 @@ private int test;
* INTERNAL
*/
public static int getLogFileDeleteDelay() {
return getIntSetting(H2_LOG_DELETE_DELAY, 2000);
int test;
return getIntSetting(H2_LOG_DELETE_DELAY, 0);
// return getIntSetting(H2_LOG_DELETE_DELAY, 2000);
}
}
......@@ -51,6 +51,7 @@ import org.h2.util.BitField;
import org.h2.util.ByteUtils;
import org.h2.util.CacheLRU;
import org.h2.util.ClassUtils;
import org.h2.util.DelayedFileDeleter;
import org.h2.util.FileUtils;
import org.h2.util.IOUtils;
import org.h2.util.IntHashMap;
......@@ -1344,11 +1345,7 @@ public class Database implements DataHandler {
}
public void deleteLogFileLater(String fileName) throws SQLException {
if (writer == null) {
FileUtils.delete(fileName);
} else {
writer.deleteLater(fileName);
}
DelayedFileDeleter.getInstance().deleteLater(fileName);
}
public Class loadUserClass(String className) throws SQLException {
......
......@@ -34,7 +34,6 @@ import org.h2.message.TraceObject;
import org.h2.result.ResultInterface;
import org.h2.util.ClassUtils;
import org.h2.util.JdbcConnectionListener;
import org.h2.util.TempFileDeleter;
import org.h2.value.Value;
import org.h2.value.ValueInt;
import org.h2.value.ValueLob;
......@@ -214,7 +213,6 @@ public class JdbcConnection extends TraceObject implements Connection {
* rolled back.
*/
public void close() throws SQLException {
TempFileDeleter.deleteUnused();
synchronized (this) {
if (listener == null) {
closeConnection();
......
......@@ -312,6 +312,8 @@ public class LogFile {
}
public void redoAllGoEnd() throws SQLException {
int test;
//System.out.println("redo log " + fileName);
boolean readOnly = logSystem.getDatabase().getReadOnly();
long length = file.length();
if (length <= FileStore.HEADER_LENGTH) {
......
......@@ -213,6 +213,10 @@ public class DiskFile implements CacheWriter {
}
public void initFromSummary(byte[] summary) {
int test;
//System.out.println("init from summary: " + this);
synchronized (database) {
if (summary == null || summary.length == 0) {
ObjectArray list = database.getAllStorages();
......
......@@ -16,7 +16,7 @@ import org.h2.security.SecureFileStore;
import org.h2.store.fs.FileObject;
import org.h2.store.fs.FileSystem;
import org.h2.util.ByteUtils;
import org.h2.util.TempFileDeleter;
import org.h2.util.DelayedFileDeleter;
/**
* This class is an abstraction of a random access file.
......@@ -163,7 +163,7 @@ public class FileStore {
public void closeAndDeleteSilently() {
if (file != null) {
closeSilently();
TempFileDeleter.deleteFile(autoDeleteReference, name);
DelayedFileDeleter.getInstance().autoDeleteFile(autoDeleteReference, name);
name = null;
}
}
......@@ -324,11 +324,11 @@ public class FileStore {
}
public void autoDelete() {
autoDeleteReference = TempFileDeleter.addFile(name, this);
autoDeleteReference = DelayedFileDeleter.getInstance().addTempFile(name, this);
}
public void stopAutoDelete() {
TempFileDeleter.stopAutoDelete(autoDeleteReference, name);
DelayedFileDeleter.getInstance().stopAutoDelete(autoDeleteReference, name);
autoDeleteReference = null;
}
......
......@@ -201,7 +201,9 @@ public class Storage {
public void delete(Session session) throws SQLException {
truncate(session);
database.removeStorage(id, file);
int test;
// database.removeStorage(id, file);
}
// private int allocateBest(int start, int blocks) {
......
......@@ -6,9 +6,6 @@ package org.h2.store;
import java.lang.ref.WeakReference;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
......@@ -19,10 +16,7 @@ import org.h2.log.LogSystem;
import org.h2.message.Trace;
import org.h2.message.TraceSystem;
import org.h2.table.Table;
import org.h2.util.FileUtils;
import org.h2.util.ObjectArray;
import org.h2.util.ObjectUtils;
import org.h2.util.TempFileDeleter;
/**
* The writer thread is responsible to flush the transaction log file from time to time.
......@@ -44,55 +38,6 @@ public class WriterThread extends Thread {
private int writeDelay;
private long lastIndexFlush;
private volatile boolean stop;
private HashMap deleteLater = new HashMap();
private volatile long deleteNext;
public void deleteLater(String fileName) {
long at = System.currentTimeMillis() + SysProperties.getLogFileDeleteDelay();
if (at < deleteNext || deleteNext == 0) {
deleteNext = at;
}
synchronized (deleteLater) {
deleteLater.put(fileName, ObjectUtils.getLong(at));
}
}
private void delete(boolean now) {
if (!now && (deleteNext == 0 || System.currentTimeMillis() < deleteNext)) {
return;
}
long time = System.currentTimeMillis();
ObjectArray delete = new ObjectArray();
synchronized (deleteLater) {
deleteNext = 0;
for (Iterator it = deleteLater.entrySet().iterator(); it.hasNext();) {
Entry entry = (Entry) it.next();
long at = ((Long) entry.getValue()).longValue();
if (now || time >= at) {
String fileName = (String) entry.getKey();
delete.add(fileName);
} else {
if (at < deleteNext || deleteNext == 0) {
deleteNext = at;
}
}
}
}
for (int i = 0; i < delete.size(); i++) {
String fileName = (String) delete.get(i);
try {
FileUtils.delete(fileName);
synchronized (deleteLater) {
deleteLater.remove(fileName);
}
} catch (SQLException e) {
Database database = (Database) databaseRef.get();
if (database != null) {
database.getTrace(Trace.DATABASE).error("delete " + fileName, e);
}
}
}
}
private WriterThread(Database database, int writeDelay) {
this.databaseRef = new WeakReference(database);
......@@ -161,8 +106,6 @@ public class WriterThread extends Thread {
public void run() {
while (!stop) {
delete(false);
TempFileDeleter.deleteUnused();
Database database = (Database) databaseRef.get();
if (database == null) {
break;
......@@ -196,9 +139,6 @@ public class WriterThread extends Thread {
}
public void stopThread() {
int testing;
delete(false);
stop = true;
}
......
/*
* Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.util;
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import org.h2.constant.SysProperties;
import org.h2.message.Message;
/**
* Deletes files later on or if they are not used.
* This class deletes temporary files when they are not used any longer.
*/
public class DelayedFileDeleter extends Thread {
private static DelayedFileDeleter instance;
private final ReferenceQueue queue = new ReferenceQueue();
private final HashMap refMap = new HashMap();
private final HashMap deleteLater = new HashMap();
private long deleteNext;
public synchronized void deleteLater(String fileName) throws SQLException {
int delay = SysProperties.getLogFileDeleteDelay();
if (delay == 0 && deleteLater.size() == 0) {
// shortcut if delay is 0
FileUtils.delete(fileName);
return;
}
long at = System.currentTimeMillis() + delay;
if (deleteNext != 0 && at <= deleteNext) {
// make sure files are deleted in the correct order
at = deleteNext + 1;
}
deleteNext = at;
deleteLater.put(fileName, ObjectUtils.getLong(at));
}
/**
* Delete at most one old file (after the delay)
*/
private void deleteOld() {
long now = System.currentTimeMillis();
if (deleteNext == 0 || now < deleteNext) {
return;
}
String delete = null;
long oldest = 0;
for (Iterator it = deleteLater.entrySet().iterator(); it.hasNext();) {
Entry entry = (Entry) it.next();
long at = ((Long) entry.getValue()).longValue();
if (at < now && (delete == null || at < oldest)) {
delete = (String) entry.getKey();
oldest = at;
}
}
if (delete == null) {
return;
}
try {
FileUtils.delete(delete);
} catch (SQLException e) {
// ignore
}
deleteLater.remove(delete);
}
public static synchronized DelayedFileDeleter getInstance() {
if (instance == null) {
int test;
//System.out.println("DelayerFileDeleter.getInstance()");
instance = new DelayedFileDeleter();
instance.setDaemon(true);
instance.setPriority(Thread.MIN_PRIORITY);
instance.start();
}
return instance;
}
private DelayedFileDeleter() {
setName("H2 FileDeleter");
}
public void run() {
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// ignore
}
synchronized (this) {
if (refMap.size() != 0) {
deleteUnused();
} else if (deleteLater.size() != 0) {
deleteOld();
} else {
break;
}
}
}
int test;
//System.out.println("DelayerFileDeleter.stop()");
}
/**
* Add a temp file to the queue and delete it if it is no longer referenced.
*
* @param fileName the file name
* @param file the object to track
* @return the reference
*/
public synchronized Reference addTempFile(String fileName, Object file) {
FileUtils.trace("FileDeleter.addFile", fileName, file);
PhantomReference ref = new PhantomReference(file, queue);
refMap.put(ref, fileName);
return ref;
}
/**
* Delete a file now and remove it from the queue.
*
* @param the reference in the queue
* @param fileName the file name
*/
public synchronized void autoDeleteFile(Reference ref, String fileName) {
if (ref != null) {
String f2 = (String) refMap.remove(ref);
if (SysProperties.CHECK && f2 != null && fileName != null && !f2.equals(fileName)) {
throw Message.getInternalError("f2:" + f2 + " f:" + fileName);
}
}
if (fileName != null && FileUtils.exists(fileName)) {
try {
FileUtils.trace("FileDeleter.deleteFile", fileName, null);
FileUtils.delete(fileName);
} catch (Exception e) {
// TODO log such errors?
}
deleteUnused();
}
}
/**
* Delete all unreferenced files that have been garbage collected now.
* This method is called from time to time by the application.
*/
private void deleteUnused() {
while (true) {
Reference ref = queue.poll();
if (ref == null) {
break;
}
autoDeleteFile(ref, null);
}
}
/**
* Remove a file from the list of files to be deleted.
*
* @param ref the reference
* @param fileName the file name
*/
public synchronized void stopAutoDelete(Reference ref, String fileName) {
FileUtils.trace("FileDeleter.stopAutoDelete", fileName, ref);
if (ref != null) {
String f2 = (String) refMap.remove(ref);
if (SysProperties.CHECK && (f2 == null || !f2.equals(fileName))) {
throw Message.getInternalError("f2:" + f2 + " f:" + fileName);
}
}
}
}
/*
* Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.util;
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.util.HashMap;
import org.h2.constant.SysProperties;
import org.h2.message.Message;
/**
* This class deletes temporary files when they are not used any longer.
*/
public class TempFileDeleter {
private static final ReferenceQueue QUEUE = new ReferenceQueue();
private static final HashMap REF_MAP = new HashMap();
public static synchronized Reference addFile(String fileName, Object file) {
FileUtils.trace("TempFileDeleter.addFile", fileName, file);
PhantomReference ref = new PhantomReference(file, QUEUE);
REF_MAP.put(ref, fileName);
deleteUnused();
return ref;
}
public static synchronized void deleteFile(Reference ref, String fileName) {
if (ref != null) {
String f2 = (String) REF_MAP.remove(ref);
if (SysProperties.CHECK && f2 != null && fileName != null && !f2.equals(fileName)) {
throw Message.getInternalError("f2:" + f2 + " f:" + fileName);
}
}
if (fileName != null && FileUtils.exists(fileName)) {
try {
FileUtils.trace("TempFileDeleter.deleteFile", fileName, null);
FileUtils.delete(fileName);
} catch (Exception e) {
// TODO log such errors?
}
deleteUnused();
}
}
public static void deleteUnused() {
// Mystery: I don't know how QUEUE could get null, but two independent
// people reported NullPointerException here - if somebody understands
// how it could happen please report it!
// Environment: web application under Tomcat, exception occurs during undeploy
while (QUEUE != null) {
Reference ref = QUEUE.poll();
if (ref == null) {
break;
}
deleteFile(ref, null);
}
}
public static void stopAutoDelete(Reference ref, String fileName) {
FileUtils.trace("TempFileDeleter.stopAutoDelete", fileName, ref);
if (ref != null) {
String f2 = (String) REF_MAP.remove(ref);
if (SysProperties.CHECK && (f2 == null || !f2.equals(fileName))) {
throw Message.getInternalError("f2:" + f2 + " f:" + fileName);
}
}
deleteUnused();
}
}
......@@ -179,6 +179,8 @@ conn3:
4) insert into bla
5) commit
after init, scan all storages and return those that don't belong to a live database object!!
Automate real power off tests
Extend tests that simulate power off
timer test
......
......@@ -146,6 +146,10 @@ public abstract class TestBase {
}
private Connection getConnectionInternal(String url, String user, String password) throws Exception {
int test;
//System.out.println();
//System.out.println("connect to " + url);
Class.forName("org.h2.Driver");
// url += ";DEFAULT_TABLE_TYPE=1";
// Class.forName("org.hsqldb.jdbcDriver");
......
......@@ -32,46 +32,58 @@ public class TestIndex extends TestBase {
}
public void test() throws Exception {
testDescIndex();
int teting;
// testDescIndex();
//
if (config.networked && config.big) {
return;
}
random.setSeed(100);
deleteDb("index");
testWideIndex(147);
testWideIndex(313);
testWideIndex(979);
testWideIndex(1200);
testWideIndex(2400);
if (config.big && config.logMode == 2) {
for (int i = 0; i < 2000; i++) {
if ((i % 100) == 0) {
System.out.println("width: " + i);
}
testWideIndex(i);
}
}
int teting2;
//
// random.setSeed(100);
//
// deleteDb("index");
// testWideIndex(147);
// testWideIndex(313);
// testWideIndex(979);
// testWideIndex(1200);
// testWideIndex(2400);
// if (config.big && config.logMode == 2) {
// for (int i = 0; i < 2000; i++) {
// if ((i % 100) == 0) {
// System.out.println("width: " + i);
// }
// testWideIndex(i);
// }
// }
//
// testLike();
// reconnect();
// testConstraint();
// testLargeIndex();
// testMultiColumnIndex();
// // long time;
// // time = System.currentTimeMillis();
// testHashIndex(true, false);
System.setProperty("h2.logDeleteDelay", "999999999");
int testx;
if(config.logMode != 2) {
return;
}
testLike();
reconnect();
testConstraint();
testLargeIndex();
testMultiColumnIndex();
// long time;
// time = System.currentTimeMillis();
testHashIndex(true, false);
testHashIndex(false, false);
// System.out.println("btree="+(System.currentTimeMillis()-time));
// time = System.currentTimeMillis();
// // System.out.println("btree="+(System.currentTimeMillis()-time));
// // time = System.currentTimeMillis();
testHashIndex(true, true);
testHashIndex(false, true);
// System.out.println("hash="+(System.currentTimeMillis()-time));
testMultiColumnHashIndex();
conn.close();
int te3;
// testMultiColumnHashIndex();
//
// conn.close();
}
void testDescIndex() throws Exception {
......@@ -217,6 +229,8 @@ public class TestIndex extends TestBase {
check(1, prep.executeUpdate());
}
check(0, getValue(stat, "SELECT COUNT(*) FROM TEST"));
conn.close();
conn = null;
}
void testMultiColumnIndex() throws Exception {
......
......@@ -34,9 +34,10 @@ public class TestLob extends TestBase {
if (config.memory) {
return;
}
testLobVariable();
testLobDrop();
testLobNoClose();
int test;
// testLobVariable();
// testLobDrop();
// testLobNoClose();
testLobTransactions(10);
testLobTransactions(10000);
testLobRollbackStop();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论