乐趣区

关于java:聊聊BitCaskKeyDir

本文次要钻研一下 BitCaskKeyDir

BitCaskKeyDir

bitcask-java/src/main/java/com/trifork/bitcask/BitCaskKeyDir.java

public class BitCaskKeyDir {Map<ByteString, BitCaskEntry> map = new HashMap<ByteString, BitCaskEntry>();
    ReadWriteLock rwl = new ReentrantReadWriteLock();
    private boolean is_ready;

    public boolean put(ByteString key, BitCaskEntry ent) {Lock writeLock = rwl.writeLock();
        writeLock.lock();
        try {BitCaskEntry old = map.get(key);
            if (old == null) {map.put(key, ent);
                return true;
            } else if (ent.is_newer_than(old)) {map.put(key, ent);
                return true;
            } else {return false;}

        } finally {writeLock.unlock();
        }

    }
    
    public BitCaskEntry get(ByteString key) {Lock readLock = rwl.readLock();
        readLock.lock();
        try {return map.get(key);
            
        } finally {readLock.unlock();
        }
        
    }

    //......

}
  • BitCaskKeyDir 提供了 map 来寄存 BitCaskEntry;其 put 办法应用 writeLock.lock(),对于 old 值为 null 的或者新值大于 old 值的才 put 进去,否则返回 false,最初 writeLock.unlock();其 get 办法应用 readLock.lock() 从 map 读取指定 key 的值,最初 readLock.unlock()

key_dirs

bitcask-java/src/main/java/com/trifork/bitcask/BitCaskKeyDir.java

public class BitCaskKeyDir {public static Map<File,BitCaskKeyDir> key_dirs = new HashMap<File, BitCaskKeyDir>();
    public static Lock keydir_lock = new ReentrantLock();
    
    public static BitCaskKeyDir keydir_new(File dirname, int openTimeoutSecs) throws IOException {File abs_name = dirname.getAbsoluteFile();
        BitCaskKeyDir dir;
        keydir_lock.lock();
        try {dir = key_dirs.get(abs_name);
            if (dir == null) {dir = new BitCaskKeyDir();
                key_dirs.put(abs_name, dir);
                return dir;
            }
            
            
        } finally {keydir_lock.unlock();
        }

        if (dir.wait_for_ready(openTimeoutSecs)) {return dir;} else {throw new IOException("timeout while waiting for keydir");
        }
    }

    public synchronized boolean is_ready() {return is_ready;}
    
    public synchronized void mark_ready() {
        is_ready = true;
        this.notifyAll();}
    
    public synchronized boolean wait_for_ready(int timeout_secs) {long now = System.currentTimeMillis();
        long abs_timeout = now + (timeout_secs * 1000);
        
        while (!is_ready && now < abs_timeout) {
            try {wait();
            } catch (InterruptedException e) {// ignore}
        
            now = System.currentTimeMillis();}
        
        return is_ready;
    }
}
  • BitCaskKeyDir 定义了 static 的 key_dirs,用于寄存指定 File 的 BitCaskKeyDir;其 keydir_new 会针对不存在的 BitCaskKeyDir 进行创立,最初通过 dir.wait_for_ready(openTimeoutSecs) 期待 ready

小结

BitCaskKeyDir 提供了 map 来寄存 BitCaskEntry;其 put 办法应用 writeLock.lock(),对于 old 值为 null 的或者新值大于 old 值的才 put 进去,否则返回 false,最初 writeLock.unlock();其 get 办法应用 readLock.lock() 从 map 读取指定 key 的值,最初 readLock.unlock()

doc

  • BitCaskKeyDir
退出移动版