1

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


codecraft
11.9k 声望2k 粉丝

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