2

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


codecraft
11.9k 声望2k 粉丝

当一个代码的工匠回首往事时,不因虚度年华而悔恨,也不因碌碌无为而羞愧,这样,当他老的时候,可以很自豪告诉世人,我曾经将代码注入生命去打造互联网的浪潮之巅,那是个很疯狂的时代,我在一波波的浪潮上留下...