All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jsimpledb.kv.array.ArrayKVStore Maven / Gradle / Ivy

There is a newer version: 3.6.1
Show newest version

/*
 * Copyright (C) 2015 Archie L. Cobbs. All rights reserved.
 */

package org.jsimpledb.kv.array;

import com.google.common.base.Preconditions;
import com.google.common.collect.UnmodifiableIterator;

import java.nio.ByteBuffer;
import java.util.Iterator;
import java.util.NoSuchElementException;

import org.jsimpledb.kv.AbstractKVStore;
import org.jsimpledb.kv.KVPair;

/**
 * A simple read-only {@link org.jsimpledb.kv.KVStore} based on a sorted array of key/value pairs.
 *
 * 

* Instances query three {@link ByteBuffer}s, one for the array index, one for the key data, and one for the value data. * Data for these {@link ByteBuffer}s is created using {@link ArrayKVWriter}. * *

* Instances are optimized for minimal memory overhead and queries using keys sharing a prefix with the previously * queried key. Key data is prefix-compressed. * *

* Key and value data must not exceed 2GB (each separately). */ public class ArrayKVStore extends AbstractKVStore { private final ByteBuffer indx; private final ByteBuffer keys; private final ByteBuffer vals; private final int size; private final ThreadLocal finderThreadLocal = new ThreadLocal() { @Override protected ArrayKVFinder initialValue() { return new ArrayKVFinder(ArrayKVStore.this.indx, ArrayKVStore.this.keys, ArrayKVStore.this.vals); } }; /** * Constructor. * * @param indx buffer containing index data written by a {@link ArrayKVWriter} * @param keys buffer containing key data written by a {@link ArrayKVWriter} * @param vals buffer containing value data written by a {@link ArrayKVWriter} * @throws IllegalArgumentException if any parameter is null * @throws IllegalArgumentException if {@code indx} size is not a correct multiple */ public ArrayKVStore(ByteBuffer indx, ByteBuffer keys, ByteBuffer vals) { Preconditions.checkArgument(indx != null, "null indx"); Preconditions.checkArgument(keys != null, "null keys"); Preconditions.checkArgument(vals != null, "null vals"); Preconditions.checkArgument(indx.capacity() % 8 == 0, "index size is not a multiple of 8"); this.indx = indx; this.keys = keys; this.vals = vals; this.size = this.indx.capacity() / 8; } @Override public byte[] get(byte[] key) { final ArrayKVFinder finder = this.finderThreadLocal.get(); final int index = finder.find(key); if (index < 0) return null; return finder.readValue(index); } @Override public KVPair getAtLeast(byte[] minKey) { final ArrayKVFinder finder = this.finderThreadLocal.get(); int index = finder.find(minKey); if (index < 0) { index = ~index; if (index == this.size) return null; } return finder.readKV(index); } @Override public KVPair getAtMost(byte[] maxKey) { final ArrayKVFinder finder = this.finderThreadLocal.get(); int index = finder.find(maxKey); if (index < 0) index = ~index; if (index == 0) return null; return finder.readKV(index - 1); } @Override public Iterator getRange(byte[] minKey, byte[] maxKey, final boolean reverse) { // Find min index final ArrayKVFinder finder = this.finderThreadLocal.get(); int index; if (minKey == null || minKey.length == 0) index = 0; else { index = finder.find(minKey); if (index < 0) index = ~index; } final int minIndex = index; // Find max index if (maxKey == null) index = this.size; else { index = finder.find(maxKey); if (index < 0) index = ~index; } final int maxIndex = index; // Return iterator over array indexes return new UnmodifiableIterator() { private int index = reverse ? maxIndex : minIndex; @Override public boolean hasNext() { return reverse ? this.index > minIndex : this.index < maxIndex; } @Override public KVPair next() { if (!this.hasNext()) throw new NoSuchElementException(); if (reverse) this.index--; final KVPair kv = ArrayKVStore.this.finderThreadLocal.get().readKV(this.index); if (!reverse) this.index++; return kv; } }; } @Override public void put(byte[] key, byte[] value) { throw new UnsupportedOperationException(); } @Override public void remove(byte[] key) { throw new UnsupportedOperationException(); } @Override public void removeRange(byte[] minKey, byte[] maxKey) { throw new UnsupportedOperationException(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy