聊聊BitCaskLock

/ java / 没有评论 / 10浏览

本文主要研究一下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;
	}
	//......

}	

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);
	}

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();
		}

	}

小结

BitCaskLock的acquire方法,先通过lock_acquire获取BitCaskLock,如果出现FileAlreadyExistsException则执行delete_stale_lock;其release方法针对is_write_lock执行file.close()及filename.delete()

doc