Newer
Older
cactus / src / main / java / com / cube / storage / MemTable.java
@agalyaramadoss agalyaramadoss on 16 Feb 2 KB version update with 21
package com.cube.storage;

import java.util.*;
import java.util.concurrent.ConcurrentSkipListMap;

/**
 * In-memory sorted table for recent writes.
 */
public class MemTable {
    
    private final ConcurrentSkipListMap<String, byte[]> data;
    private volatile long size;
    
    public MemTable() {
        this.data = new ConcurrentSkipListMap<>();
        this.size = 0;
    }
    
    public void put(String key, byte[] value) {
        byte[] oldValue = data.put(key, value);
        
        if (oldValue != null) {
            size -= estimateEntrySize(key, oldValue);
        }
        size += estimateEntrySize(key, value);
    }
    
    public byte[] get(String key) {
        return data.get(key);
    }
    
    public boolean contains(String key) {
        return data.containsKey(key);
    }
    
    public Collection<String> scan(String prefix) {
        if (prefix == null || prefix.isEmpty()) {
            return new ArrayList<>(data.keySet());
        }
        
        List<String> result = new ArrayList<>();
        String startKey = prefix;
        String endKey = prefix + Character.MAX_VALUE;
        
        for (String key : data.subMap(startKey, endKey).keySet()) {
            result.add(key);
        }
        
        return result;
    }
    
    public Map<String, byte[]> scanEntries(String prefix) {
        if (prefix == null || prefix.isEmpty()) {
            return new TreeMap<>(data);
        }
        
        Map<String, byte[]> result = new TreeMap<>();
        String startKey = prefix;
        String endKey = prefix + Character.MAX_VALUE;
        
        for (Map.Entry<String, byte[]> entry : data.subMap(startKey, endKey).entrySet()) {
            result.put(entry.getKey(), entry.getValue());
        }
        
        return result;
    }
    
    public Map<String, byte[]> getEntries() {
        return new TreeMap<>(data);
    }
    
    public long size() {
        return size;
    }
    
    public int getKeyCount() {
        return data.size();
    }
    
    public boolean isEmpty() {
        return data.isEmpty();
    }
    
    public void clear() {
        data.clear();
        size = 0;
    }
    
    private long estimateEntrySize(String key, byte[] value) {
        return (key.length() * 2L) + value.length + 32;
    }
    
    @Override
    public String toString() {
        return "MemTable{keys=" + data.size() + ", size=" + size + " bytes}";
    }
}