Permalink
Browse files

Added option to DBMaker to disable file-system locking entirely.

  • Loading branch information...
1 parent 25369ed commit 68fbaf54f97527eb1969a57a48acbc649f1907c6 @hamishmorgan hamishmorgan committed Apr 18, 2012
View
4 src/main/java/net/kotek/jdbm/DBCache.java
@@ -40,11 +40,11 @@
*/
public DBCache(String filename, boolean readonly, boolean transactionDisabled,
Cipher cipherIn, Cipher cipherOut, boolean useRandomAccessFile,
- boolean deleteFilesAfterClose){
+ boolean deleteFilesAfterClose,boolean lockingDisabled){
super(filename, readonly, transactionDisabled,
cipherIn, cipherOut, useRandomAccessFile,
- deleteFilesAfterClose);
+ deleteFilesAfterClose,lockingDisabled);
}
View
4 src/main/java/net/kotek/jdbm/DBCacheMRU.java
@@ -69,10 +69,10 @@
*/
public DBCacheMRU(String filename, boolean readonly, boolean transactionDisabled,
Cipher cipherIn, Cipher cipherOut, boolean useRandomAccessFile,
- boolean deleteFilesAfterClose, int cacheMaxRecords) {
+ boolean deleteFilesAfterClose, int cacheMaxRecords, boolean lockingDisabled) {
super(filename, readonly, transactionDisabled,
cipherIn, cipherOut, useRandomAccessFile,
- deleteFilesAfterClose);
+ deleteFilesAfterClose,lockingDisabled);
_hash = new LongHashMap<CacheEntry>(cacheMaxRecords);
_max = cacheMaxRecords;
View
4 src/main/java/net/kotek/jdbm/DBCacheRef.java
@@ -79,11 +79,11 @@
public DBCacheRef(String filename, boolean readonly, boolean transactionDisabled,
Cipher cipherIn, Cipher cipherOut, boolean useRandomAccessFile,
boolean deleteFilesAfterClose,
- byte cacheType, boolean cacheAutoClearOnLowMem) {
+ byte cacheType, boolean cacheAutoClearOnLowMem, boolean lockingDisabled) {
super(filename, readonly, transactionDisabled,
cipherIn, cipherOut, useRandomAccessFile,
- deleteFilesAfterClose);
+ deleteFilesAfterClose, lockingDisabled);
this._cacheType = cacheType;
View
26 src/main/java/net/kotek/jdbm/DBMaker.java
@@ -36,6 +36,7 @@
private String location = null;
private boolean disableTransactions = false;
+ private boolean lockingDisabled = false;
private boolean readonly = false;
private String password = null;
private boolean useAES256Bit = true;
@@ -231,7 +232,24 @@ public DBMaker disableTransactions() {
this.disableTransactions = true;
return this;
}
-
+
+ /**
+ * Disable file system based locking (for file systems that do not support it).
+ *
+ * Locking is not supported by many remote or distributed file systems; such
+ * as Lustre and NFS. Attempts to perform locks will result in an
+ * IOException with the message "Function not implemented".
+ *
+ * Disabling locking will avoid this issue, though of course it comes with
+ * all the issues of uncontrolled file access.
+ *
+ * @return this builder
+ */
+ public DBMaker disableLocking(){
+ this.lockingDisabled = true;
+ return this;
+ }
+
/**
* By default JDBM uses mapped memory buffers to read from files.
* But this may behave strangely on some platforms.
@@ -314,11 +332,11 @@ public DB make() {
if (cacheType == DBCacheRef.MRU){
- db = new DBCacheMRU(location, readonly, disableTransactions, cipherIn, cipherOut,useRandomAccessFile,deleteFilesAfterCloseFlag, mruCacheSize);
+ db = new DBCacheMRU(location, readonly, disableTransactions, cipherIn, cipherOut,useRandomAccessFile,deleteFilesAfterCloseFlag, mruCacheSize,lockingDisabled);
}else if( cacheType == DBCacheRef.SOFT || cacheType == DBCacheRef.HARD || cacheType == DBCacheRef.WEAK) {
- db = new DBCacheRef(location, readonly, disableTransactions, cipherIn, cipherOut,useRandomAccessFile,deleteFilesAfterCloseFlag, cacheType,autoClearRefCacheOnLowMem);
+ db = new DBCacheRef(location, readonly, disableTransactions, cipherIn, cipherOut,useRandomAccessFile,deleteFilesAfterCloseFlag, cacheType,autoClearRefCacheOnLowMem,lockingDisabled);
} else if (cacheType == DBCacheRef.NONE) {
- db = new DBStore(location, readonly, disableTransactions, cipherIn, cipherOut,useRandomAccessFile,deleteFilesAfterCloseFlag);
+ db = new DBStore(location, readonly, disableTransactions, cipherIn, cipherOut,useRandomAccessFile,deleteFilesAfterCloseFlag,lockingDisabled);
} else {
throw new IllegalArgumentException("Unknown cache type: " + cacheType);
}
View
13 src/main/java/net/kotek/jdbm/DBStore.java
@@ -93,7 +93,7 @@
*/
private Cipher cipherIn;
private boolean useRandomAccessFile;
-
+ private boolean lockingDisabled;
void checkCanWrite() {
if (readonly)
@@ -129,8 +129,8 @@ void checkCanWrite() {
private final String _filename;
- public DBStore(String filename, boolean readonly, boolean transactionDisabled) throws IOException {
- this(filename, readonly, transactionDisabled, null, null, false,false);
+ public DBStore(String filename, boolean readonly, boolean transactionDisabled, boolean lockingDisabled) throws IOException {
+ this(filename, readonly, transactionDisabled, null, null, false,false,false);
}
@@ -142,21 +142,22 @@ public DBStore(String filename, boolean readonly, boolean transactionDisabled) t
*/
public DBStore(String filename, boolean readonly, boolean transactionDisabled,
Cipher cipherIn, Cipher cipherOut, boolean useRandomAccessFile,
- boolean deleteFilesAfterClose){
+ boolean deleteFilesAfterClose, boolean lockingDisabled){
_filename = filename;
this.readonly = readonly;
this.transactionsDisabled = transactionDisabled;
this.cipherIn = cipherIn;
this.cipherOut = cipherOut;
this.useRandomAccessFile = useRandomAccessFile;
this.deleteFilesAfterClose = deleteFilesAfterClose;
+ this.lockingDisabled = lockingDisabled;
reopen();
}
private void reopen() {
try{
- _file = new PageFile(_filename, readonly, transactionsDisabled, cipherIn, cipherOut,useRandomAccessFile);
+ _file = new PageFile(_filename, readonly, transactionsDisabled, cipherIn, cipherOut,useRandomAccessFile,lockingDisabled);
_pageman = new PageManager(_file);
_physMgr = new PhysicalRowIdManager(_file, _pageman);
@@ -669,7 +670,7 @@ public synchronized void defrag(boolean sortCollections) {
commit();
final String filename2 = _filename + "_defrag" + System.currentTimeMillis();
final String filename1 = _filename;
- DBStore db2 = new DBStore(filename2, false, true, cipherIn, cipherOut, false,false);
+ DBStore db2 = new DBStore(filename2, false, true, cipherIn, cipherOut, false,false,false);
//recreate logical file with original page layout
{
View
8 src/main/java/net/kotek/jdbm/PageFile.java
@@ -81,7 +81,7 @@
* @throws IOException whenever the creation of the underlying
* RandomAccessFile throws it.
*/
- PageFile(String fileName, boolean readonly, boolean transactionsDisabled, Cipher cipherIn, Cipher cipherOut, boolean useRandomAccessFile) throws IOException {
+ PageFile(String fileName, boolean readonly, boolean transactionsDisabled, Cipher cipherIn, Cipher cipherOut, boolean useRandomAccessFile, boolean lockingDisabled) throws IOException {
this.cipherIn = cipherIn;
this.cipherOut = cipherOut;
this.transactionsDisabled = transactionsDisabled;
@@ -92,9 +92,9 @@
// }else if (fileName.contains("!/"))
// this.storage = new StorageZip(fileName);
else if(useRandomAccessFile)
- this.storage = new StorageDisk(fileName,readonly);
+ this.storage = new StorageDisk(fileName,readonly,lockingDisabled);
else
- this.storage = new StorageDiskMapped(fileName,readonly,transactionsDisabled);
+ this.storage = new StorageDiskMapped(fileName,readonly,transactionsDisabled,lockingDisabled);
if (this.storage.isReadonly() && !readonly)
throw new IllegalArgumentException("This type of storage is readonly, you should call readonly() on DBMaker");
@@ -106,7 +106,7 @@ else if(useRandomAccessFile)
}
public PageFile(String filename) throws IOException {
- this(filename, false, false, null, null,false);
+ this(filename, false, false, null, null,false,false);
}
View
6 src/main/java/net/kotek/jdbm/StorageDisk.java
@@ -21,14 +21,16 @@
private long lastPageNumber = Long.MIN_VALUE;
private boolean readonly;
+ private boolean lockingDisabled;
- public StorageDisk(String fileName,boolean readonly) throws IOException {
+ public StorageDisk(String fileName,boolean readonly, boolean lockingDisabled) throws IOException {
this.fileName = fileName;
this.readonly = readonly;
+ this.lockingDisabled = lockingDisabled;
//make sure first file can be opened
//lock it
try {
- if(!readonly)
+ if(!readonly && !lockingDisabled)
getRaf(0).getChannel().tryLock();
} catch (IOException e) {
throw new IOException("Could not lock DB file: " + fileName, e);
View
7 src/main/java/net/kotek/jdbm/StorageDiskMapped.java
@@ -37,16 +37,19 @@
private String fileName;
private boolean transactionsDisabled;
private boolean readonly;
+ private boolean lockingDisabled;
- public StorageDiskMapped(String fileName, boolean readonly, boolean transactionsDisabled) throws IOException {
+ public StorageDiskMapped(String fileName, boolean readonly, boolean transactionsDisabled, boolean lockingDisabled) throws IOException {
this.fileName = fileName;
this.transactionsDisabled = transactionsDisabled;
this.readonly = readonly;
+ this.lockingDisabled = lockingDisabled;
//make sure first file can be opened
//lock it
try {
- getChannel(0).lock();
+ if(!lockingDisabled)
+ getChannel(0).lock();
} catch (IOException e) {
throw new IOException("Could not lock DB file: " + fileName, e);
} catch (OverlappingFileLockException e) {
View
6 src/test/java/net/kotek/jdbm/BTreeKeyCompressionTest.java
@@ -13,7 +13,7 @@
public void testExpand() throws IOException {
long init = Long.MAX_VALUE - size * 2;
String file = newTestFile();
- DB db = new DBStore(file, false, false);
+ DB db = new DBStore(file, false, false,false);
SortedMap<Long, String> map = db.createTreeMap("aa");
for (long i = init; i < init + size; i++) {
map.put(i, "");
@@ -104,15 +104,15 @@ public void testCornersLimitsInt() throws IOException {
public void testStrings() throws IOException {
long init = Long.MAX_VALUE - size * 2;
String file = newTestFile();
- DB db = new DBStore(file, false, false);
+ DB db = new DBStore(file, false, false,false);
SortedMap<String, String> map = db.createTreeMap("aa");
for (long i = init; i < init + size / 10; i++) {
map.put("aaaaa" + i, "");
}
db.commit();
db.defrag(true);
db.close();
- db = new DBStore(file, false, false);
+ db = new DBStore(file, false, false,false);
map = db.getTreeMap("aa");
for (long i = init; i < init + size / 10; i++) {
assertTrue(map.containsKey("aaaaa" + i));
View
16 src/test/java/net/kotek/jdbm/DefragTest.java
@@ -8,18 +8,18 @@
public void testDefrag1() throws IOException {
String file = newTestFile();
- DBStore m = new DBStore(file, false, false);
+ DBStore m = new DBStore(file, false, false,false);
long loc = m.insert("123");
m.defrag(true);
m.close();
- m = new DBStore(file, false, false);
+ m = new DBStore(file, false, false,false);
assertEquals(m.fetch(loc), "123");
}
public void testDefrag2() throws IOException {
String file = newTestFile();
- DBStore m = new DBStore(file, false, false);
+ DBStore m = new DBStore(file, false, false,false);
TreeMap<Long, String> map = new TreeMap<Long, String>();
for (int i = 0; i < 10000; i++) {
long loc = m.insert("" + i);
@@ -28,7 +28,7 @@ public void testDefrag2() throws IOException {
m.defrag(true);
m.close();
- m = new DBStore(file, false, false);
+ m = new DBStore(file, false, false,false);
for (Long l : map.keySet()) {
String val = map.get(l);
assertEquals(val, m.fetch(l));
@@ -38,7 +38,7 @@ public void testDefrag2() throws IOException {
public void testDefragBtree() throws IOException {
String file = newTestFile();
- DBStore m = new DBStore(file, false, false);
+ DBStore m = new DBStore(file, false, false,false);
Map t = m.createTreeMap("aa");
TreeMap t2 = new TreeMap();
for (int i = 0; i < 10000; i++) {
@@ -48,14 +48,14 @@ public void testDefragBtree() throws IOException {
m.defrag(true);
m.close();
- m = new DBStore(file, false, false);
+ m = new DBStore(file, false, false,false);
t = m.getTreeMap("aa");
assertEquals(t, t2);
}
public void testDefragLinkedList() throws Exception {
String file = newTestFile();
- DBStore r = new DBStore(file, false, false);
+ DBStore r = new DBStore(file, false, false,false);
List l = r.createLinkedList("test");
Map<Long, Double> junk = new LinkedHashMap<Long, Double>();
@@ -72,7 +72,7 @@ public void testDefragLinkedList() throws Exception {
r.defrag(true);
r.close();
- r = new DBStore(file, false, false);
+ r = new DBStore(file, false, false,false);
assertEquals(oldRecCount, r.countRecords());
//compare that list was unchanged
View
2 src/test/java/net/kotek/jdbm/StorageZipTest.java
@@ -15,7 +15,7 @@ public void test_archive_creation() throws IOException {
tmp.deleteOnExit();
//first create archie and put it in zip file
- DBStore r = new DBStore(newTestFile(), false, true);
+ DBStore r = new DBStore(newTestFile(), false, true,false);
Set<Long> h = r.createHashSet("hash");
for (Long l = 0L; l < 1e3; l++) {
h.add(l);
View
2 src/test/java/net/kotek/jdbm/TestLargeData.java
@@ -7,7 +7,7 @@
public void testLargeData() throws IOException {
- DBAbstract db = new DBStore(newTestFile(), false, false);
+ DBAbstract db = new DBStore(newTestFile(), false, false,false);
byte[] data = UtilTT.makeRecord(1000000, (byte) 12);
final long id = db.insert(data);
View
4 src/test/java/net/kotek/jdbm/TestStress.java
@@ -79,7 +79,7 @@ private int getRandomAllocatedRoot() {
public void testBasics() throws Exception {
String file = newTestFile();
- DBStore db = new DBStore(file, false, false);
+ DBStore db = new DBStore(file, false, false,false);
// as this code is meant to test data structure calculcations
// and stuff like that, we may want to disable transactions
@@ -105,7 +105,7 @@ public void testBasics() throws Exception {
System.out.print(" (reopened at round "
+ i / RPPROMILLE + ")");
db.close();
- db = new DBStore(file, false, false);
+ db = new DBStore(file, false, false,false);
// db.disableTransactions();
}

0 comments on commit 68fbaf5

Please sign in to comment.