序
本文次要钻研一下 BitCaskLock
BitCaskLock
bitcask-java/src/main/java/com/trifork/bitcask/BitCaskLock.java
public class BitCaskLock {
public static enum Stale {OK, NOT_STALE}
public static enum Type {
WRITE, MERGE;
private String type_name() {if (this == MERGE) return "merge";
if (this == WRITE) return "write";
throw new RuntimeException();}
}
private RandomAccessFile file;
private boolean is_write_lock;
private File filename;
private BitCaskLock(RandomAccessFile file, File filename, boolean isWriteLock) {
this.file = file;
this.filename = filename;
this.is_write_lock = isWriteLock;
}
public static BitCaskLock acquire(Type type, File dirname) throws IOException {File lock_filename = lock_filename(type, dirname);
foo: do {
try {BitCaskLock lock = lock_acquire(lock_filename, true);
String lock_contents = Integer.toString(OS.getpid()) + "\n";
lock.write_data(ByteString.copyFromUtf8(lock_contents));
return lock;
} catch (FileAlreadyExistsException e) {delete_stale_lock(lock_filename);
continue foo;
}
} while (false);
return null;
}
public void release() throws IOException {if (file != null) {if (is_write_lock) {file.close();
filename.delete();}
}
file = null;
}
//......
}
- BitCaskLock 的 acquire 办法,先通过 lock_acquire 获取 BitCaskLock,如果呈现 FileAlreadyExistsException 则执行 delete_stale_lock;其 release 办法针对 is_write_lock 执行 file.close() 及 filename.delete()
lock_acquire
bitcask-java/src/main/java/com/trifork/bitcask/BitCaskLock.java
private static BitCaskLock lock_acquire(File lockFilename, boolean is_write_lock)
throws IOException {if (is_write_lock) {if (lockFilename.createNewFile() == false) {
// file already exists, so we fail!
throw new FileAlreadyExistsException(lockFilename);
}
}
RandomAccessFile f = new RandomAccessFile(lockFilename,
is_write_lock ? "rws" : "r");
return new BitCaskLock(f, lockFilename, is_write_lock);
}
- lock_acquire 办法针对 is_write_lock,执行 lockFilename.createNewFile(),若为 false 则抛出 FileAlreadyExistsException
delete_stale_lock
bitcask-java/src/main/java/com/trifork/bitcask/BitCaskLock.java
public static Stale delete_stale_lock(Type type, File dirname) throws IOException {return delete_stale_lock(lock_filename(type, dirname));
}
private static Stale delete_stale_lock(File lockFilename) throws IOException {
BitCaskLock l = null;
try {l = lock_acquire(lockFilename, false);
} catch (FileNotFoundException e) {return Stale.OK;} catch (IOException e) {return Stale.NOT_STALE;}
try {int pid = l.read_lock_data_pid();
if (OS.pid_exists(pid)) {return Stale.NOT_STALE;} else {lockFilename.delete();
return Stale.OK;
}
} catch (IOException e) {return Stale.NOT_STALE;} finally {l.release();
}
}
- delete_stale_lock 办法先执行 lock_acquire,若呈现 FileNotFoundException,则返回 Stale.OK,若呈现 IOException 则返回 Stale.NOT_STALE;否则通过 l.read_lock_data_pid() 获取 pid,若 OS.pid_exists(pid) 则返回 Stale.NOT_STALE,否则执行 lockFilename.delete(),返回 Stale.OK;最初执行 l.release()
小结
BitCaskLock 的 acquire 办法,先通过 lock_acquire 获取 BitCaskLock,如果呈现 FileAlreadyExistsException 则执行 delete_stale_lock;其 release 办法针对 is_write_lock 执行 file.close() 及 filename.delete()
doc
- BitCaskLock