提交 4b2f3723 authored 作者: Thomas Mueller's avatar Thomas Mueller

Improved database and in-memory file system.

上级 fb7999e1
...@@ -100,6 +100,7 @@ public class FileSystemDatabase extends FileSystem { ...@@ -100,6 +100,7 @@ public class FileSystemDatabase extends FileSystem {
*/ */
public void close() { public void close() {
JdbcUtils.closeSilently(conn); JdbcUtils.closeSilently(conn);
INSTANCES.remove(url);
} }
private void commit() { private void commit() {
...@@ -240,7 +241,6 @@ public class FileSystemDatabase extends FileSystem { ...@@ -240,7 +241,6 @@ public class FileSystemDatabase extends FileSystem {
} }
public String createTempFile(String name, String suffix, boolean deleteOnExit, boolean inTempDir) throws IOException { public String createTempFile(String name, String suffix, boolean deleteOnExit, boolean inTempDir) throws IOException {
name = translateFileName(name);
name += "."; name += ".";
for (int i = 0;; i++) { for (int i = 0;; i++) {
String n = name + i + suffix; String n = name + i + suffix;
......
...@@ -11,9 +11,11 @@ import java.io.InputStream; ...@@ -11,9 +11,11 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
import org.h2.util.ObjectArray;
import org.h2.util.RandomUtils; import org.h2.util.RandomUtils;
/** /**
...@@ -23,7 +25,7 @@ import org.h2.util.RandomUtils; ...@@ -23,7 +25,7 @@ import org.h2.util.RandomUtils;
public class FileSystemMemory extends FileSystem { public class FileSystemMemory extends FileSystem {
private static final FileSystemMemory INSTANCE = new FileSystemMemory(); private static final FileSystemMemory INSTANCE = new FileSystemMemory();
private static final HashMap MEMORY_FILES = new HashMap(); private final HashMap memoryFiles = new HashMap();
private FileSystemMemory() { private FileSystemMemory() {
// don't allow construction // don't allow construction
...@@ -40,71 +42,85 @@ public class FileSystemMemory extends FileSystem { ...@@ -40,71 +42,85 @@ public class FileSystemMemory extends FileSystem {
public void rename(String oldName, String newName) { public void rename(String oldName, String newName) {
oldName = normalize(oldName); oldName = normalize(oldName);
newName = normalize(newName); newName = normalize(newName);
FileObjectMemory f = getMemoryFile(oldName); synchronized (memoryFiles) {
f.setName(newName); FileObjectMemory f = getMemoryFile(oldName);
synchronized (MEMORY_FILES) { f.setName(newName);
MEMORY_FILES.remove(oldName); memoryFiles.remove(oldName);
MEMORY_FILES.put(newName, f); memoryFiles.put(newName, f);
} }
} }
public boolean createNewFile(String fileName) { public boolean createNewFile(String fileName) {
if (exists(fileName)) { synchronized (memoryFiles) {
return false; if (exists(fileName)) {
return false;
}
getMemoryFile(fileName);
} }
// creates the file (not thread safe)
getMemoryFile(fileName);
return true; return true;
} }
public boolean exists(String fileName) { public boolean exists(String fileName) {
fileName = normalize(fileName); fileName = normalize(fileName);
synchronized (MEMORY_FILES) { synchronized (memoryFiles) {
return MEMORY_FILES.get(fileName) != null; return memoryFiles.get(fileName) != null;
} }
} }
public void delete(String fileName) { public void delete(String fileName) {
fileName = normalize(fileName); fileName = normalize(fileName);
synchronized (MEMORY_FILES) { synchronized (memoryFiles) {
MEMORY_FILES.remove(fileName); memoryFiles.remove(fileName);
} }
} }
public boolean tryDelete(String fileName) { public boolean tryDelete(String fileName) {
fileName = normalize(fileName); fileName = normalize(fileName);
synchronized (MEMORY_FILES) { synchronized (memoryFiles) {
MEMORY_FILES.remove(fileName); memoryFiles.remove(fileName);
} }
return true; return true;
} }
public String createTempFile(String name, String suffix, boolean deleteOnExit, boolean inTempDir) { public String createTempFile(String name, String suffix, boolean deleteOnExit, boolean inTempDir) {
name += "."; name += ".";
for (int i = 0;; i++) { synchronized (memoryFiles) {
String n = name + (RandomUtils.getSecureLong() >>> 1) + suffix; for (int i = 0;; i++) {
if (!exists(n)) { String n = name + (RandomUtils.getSecureLong() >>> 1) + suffix;
// creates the file (not thread safe) if (!exists(n)) {
getMemoryFile(n); getMemoryFile(n);
return n; return n;
}
} }
} }
} }
public String[] listFiles(String path) { public String[] listFiles(String path) {
synchronized (MEMORY_FILES) { ObjectArray list = new ObjectArray();
String[] list = new String[MEMORY_FILES.size()]; synchronized (memoryFiles) {
FileObjectMemory[] l = new FileObjectMemory[MEMORY_FILES.size()]; for (Iterator it = memoryFiles.keySet().iterator(); it.hasNext();) {
MEMORY_FILES.values().toArray(l); String name = (String) it.next();
for (int i = 0; i < list.length; i++) { if (name.startsWith(path)) {
list[i] = l[i].getName(); list.add(name);
}
} }
return list; String[] array = new String[list.size()];
list.toArray(array);
return array;
} }
} }
public void deleteRecursive(String fileName) throws SQLException { public void deleteRecursive(String fileName) throws SQLException {
throw Message.getUnsupportedException(); fileName = normalize(fileName);
synchronized (memoryFiles) {
Iterator it = memoryFiles.keySet().iterator();
while (it.hasNext()) {
String name = (String) it.next();
if (name.startsWith(fileName)) {
it.remove();
}
}
}
} }
public boolean isReadOnly(String fileName) { public boolean isReadOnly(String fileName) {
...@@ -201,12 +217,12 @@ public class FileSystemMemory extends FileSystem { ...@@ -201,12 +217,12 @@ public class FileSystemMemory extends FileSystem {
private FileObjectMemory getMemoryFile(String fileName) { private FileObjectMemory getMemoryFile(String fileName) {
fileName = normalize(fileName); fileName = normalize(fileName);
synchronized (MEMORY_FILES) { synchronized (memoryFiles) {
FileObjectMemory m = (FileObjectMemory) MEMORY_FILES.get(fileName); FileObjectMemory m = (FileObjectMemory) memoryFiles.get(fileName);
if (m == null) { if (m == null) {
boolean compress = fileName.startsWith(FileSystem.PREFIX_MEMORY_LZF); boolean compress = fileName.startsWith(FileSystem.PREFIX_MEMORY_LZF);
m = new FileObjectMemory(fileName, compress); m = new FileObjectMemory(fileName, compress);
MEMORY_FILES.put(fileName, m); memoryFiles.put(fileName, m);
} }
return m; return m;
} }
......
...@@ -27,6 +27,15 @@ import org.h2.test.TestBase; ...@@ -27,6 +27,15 @@ import org.h2.test.TestBase;
*/ */
public class TestFileSystem extends TestBase { public class TestFileSystem extends TestBase {
/**
* Run just this test.
*
* @param a ignored
*/
public static void main(String[] a) throws Exception {
TestBase.createCaller().init().test();
}
public void test() throws Exception { public void test() throws Exception {
testDatabaseInMemFileSys(); testDatabaseInMemFileSys();
testDatabaseInJar(); testDatabaseInJar();
...@@ -40,6 +49,7 @@ public class TestFileSystem extends TestBase { ...@@ -40,6 +49,7 @@ public class TestFileSystem extends TestBase {
private void testDatabaseInMemFileSys() throws SQLException { private void testDatabaseInMemFileSys() throws SQLException {
org.h2.Driver.load(); org.h2.Driver.load();
deleteDb("fsMem");
String url = "jdbc:h2:" + baseDir + "/fsMem"; String url = "jdbc:h2:" + baseDir + "/fsMem";
Connection conn = DriverManager.getConnection(url, "sa", "sa"); Connection conn = DriverManager.getConnection(url, "sa", "sa");
conn.createStatement().execute("CREATE TABLE TEST AS SELECT * FROM DUAL"); conn.createStatement().execute("CREATE TABLE TEST AS SELECT * FROM DUAL");
...@@ -145,7 +155,7 @@ public class TestFileSystem extends TestBase { ...@@ -145,7 +155,7 @@ public class TestFileSystem extends TestBase {
fs.rename(fsBase + "/test3", fsBase + "/test2"); fs.rename(fsBase + "/test3", fsBase + "/test2");
assertTrue(!fs.exists(fsBase + "/test3")); assertTrue(!fs.exists(fsBase + "/test3"));
assertTrue(fs.exists(fsBase + "/test2")); assertTrue(fs.exists(fsBase + "/test2"));
assertEquals(fs.length(fsBase + "/test2"), 10000); assertEquals(10000, fs.length(fsBase + "/test2"));
byte[] buffer2 = new byte[10000]; byte[] buffer2 = new byte[10000];
InputStream in = fs.openFileInputStream(fsBase + "/test2"); InputStream in = fs.openFileInputStream(fsBase + "/test2");
int pos = 0; int pos = 0;
...@@ -157,8 +167,8 @@ public class TestFileSystem extends TestBase { ...@@ -157,8 +167,8 @@ public class TestFileSystem extends TestBase {
pos += l; pos += l;
} }
in.close(); in.close();
assertEquals(pos, 10000); assertEquals(10000, pos);
assertEquals(buffer2, buffer); assertEquals(buffer, buffer2);
assertTrue(fs.tryDelete(fsBase + "/test2")); assertTrue(fs.tryDelete(fsBase + "/test2"));
fs.delete(fsBase + "/test"); fs.delete(fsBase + "/test");
...@@ -171,6 +181,7 @@ public class TestFileSystem extends TestBase { ...@@ -171,6 +181,7 @@ public class TestFileSystem extends TestBase {
assertTrue(!fs.exists("/testDir")); assertTrue(!fs.exists("/testDir"));
} }
} }
fs.close();
} }
private void testRandomAccess(String fsBase) throws Exception { private void testRandomAccess(String fsBase) throws Exception {
...@@ -245,7 +256,7 @@ public class TestFileSystem extends TestBase { ...@@ -245,7 +256,7 @@ public class TestFileSystem extends TestBase {
ra.close(); ra.close();
ra = new RandomAccessFile(file, "rw"); ra = new RandomAccessFile(file, "rw");
f = fs.openFileObject(s, "rw"); f = fs.openFileObject(s, "rw");
assertEquals(f.length(), ra.length()); assertEquals(ra.length(), f.length());
break; break;
} }
default: default:
...@@ -253,6 +264,7 @@ public class TestFileSystem extends TestBase { ...@@ -253,6 +264,7 @@ public class TestFileSystem extends TestBase {
} }
f.close(); f.close();
ra.close(); ra.close();
fs.close();
} }
private void testTempFile(String fsBase) throws Exception { private void testTempFile(String fsBase) throws Exception {
...@@ -273,6 +285,7 @@ public class TestFileSystem extends TestBase { ...@@ -273,6 +285,7 @@ public class TestFileSystem extends TestBase {
assertEquals(in.read(), -1); assertEquals(in.read(), -1);
in.close(); in.close();
out.close(); out.close();
fs.close();
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论