leveldb-impl:WriteBatchImpl.java

实现leveldb-api中的WriteBatch接口:WriteBatch的实现类为WriteBatchImpl

public class WriteBatchImpl
        implements WriteBatch

可以看到WriteBatch中有一个变量为batch用来保存每一次的操作,还有一个变量为approximateSize,用来保存key和value的大小

 private final List<Entry<Slice, Slice>> batch = new ArrayList<>();
    private int approximateSize;

WriteBatch的第一个put方法:

@Override
    public WriteBatchImpl put(byte[] key, byte[] value)
    {
        requireNonNull(key, "key is null");
        requireNonNull(value, "value is null");
        batch.add(Maps.immutableEntry(Slices.wrappedBuffer(key), Slices.wrappedBuffer(value)));
        approximateSize += 12 + key.length + value.length;
        return this;
    }

这里batch add了immutable的Entry,同时将key和value进行了一层Slice的包装,在approximateSize值增加了key和value的length,同时增加了12。在存储当前字符串时,需要有一个8字节的序列号和4字节的记录数作为头,因此在申请空间存放的时候要多加上12个字节的大小。插入的记录由kTypeValue+key长度+key+value长度+value组成。

wrappedBuffer源码如下:

Slice源码如下:

Slice包装byte数组后,同时增加一个offset记载偏移量与增加length记录数组长度,并增加hash记录hash值,但是此处在WriteBatch保存kv时与这些应该是无关的.

WriteBatch的第二个put方法:

public WriteBatchImpl put(Slice key, Slice value)
    {
        requireNonNull(key, "key is null");
        requireNonNull(value, "value is null");
        batch.add(Maps.immutableEntry(key, value));
        approximateSize += 12 + key.length() + value.length();
        return this;
    }

此put方法传入slice key和slice value,batch add一个immutbaleEntry,将Key和value传入Maps

WriteBatch的第一个delete方法:

@Override
    public WriteBatchImpl delete(byte[] key)
    {
        requireNonNull(key, "key is null");
        batch.add(Maps.immutableEntry(Slices.wrappedBuffer(key), (Slice) null));
        approximateSize += 6 + key.length;
        return this;
    }

batch add一个slice封装的key  approximateSize大小=6+key长度

foreach方法:

public void forEach(Handler handler)
    {
        for (Entry<Slice, Slice> entry : batch) {
            Slice key = entry.getKey();
            Slice value = entry.getValue();
            if (value != null) {
                handler.put(key, value);
            }
            else {
                handler.delete(key);
            }
        }
    }

for循环依次处理add进来的key和value

handler接口:

public interface Handler
    {
        void put(Slice key, Slice value);

        void delete(Slice key);
    }

对之前的数据进行批量的操作,持久化存储或者删除等操作

参考地址:LevelDB 源码剖析(二)整体架构与基本组件:Comparator、Slice、Status、Iterator、Option_凌桓丶的博客-CSDN博客

        LevelDb(二):LevelDb整体架构_蓬莱道人的博客-CSDN博客_leveldb

posted @ 2022-07-19 14:56  只能说运气有点好  阅读(33)  评论(0)    收藏  举报