com.bigdata.btree.raba.IRaba Maven / Gradle / Ivy
/*
Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved.
Contact:
SYSTAP, LLC DBA Blazegraph
2501 Calvert ST NW #106
Washington, DC 20008
[email protected]
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Created on Aug 7, 2009
*/
package com.bigdata.btree.raba;
import java.io.DataInput;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import com.bigdata.btree.ResultSet;
import com.bigdata.btree.proc.IIndexProcedure;
import com.bigdata.io.ByteArrayBuffer;
/**
* Interface for random access to a logical byte[][]s. This is primarily used
* for B+Tree keys and values, but is also used when serializing keys and values
* for {@link IIndexProcedure}s. The interface defines optional operations for
* mutation. If mutation is supported, then {@link #isReadOnly()} will return
* false
. An {@link IRaba} instance either stores B+Tree keys and
* supports {@link #search(byte[])} -or- stores B+Tree values and allows
* null
s but does not support search. for storing null
* s and search are mutually exclusive. Some {@link IRaba} implementations may
* be used for either purpose, but the {@link IRaba} instance is always either
* B+Tree keys or B+Tree values. In both cases, the {@link IRaba} stores
* variable length byte[]s. However, when an {@link IRaba} stores B+Tree keys,
* the byte[]s interpreted as unsigned byte[]
s for the purpose of
* {@link #search(byte[])}.
*
* B+Tree keys
*
* When used for B+Tree keys, the interface provides operations on an ordered
* set of variable length unsigned byte[]
keys and
* null
s ARE NOT permitted.
*
* B+Tree values
*
* When used for B+Tree values, the interface provides operations on an
* unordered collection of variable length byte[]
s, does NOT
* support {@link #search(byte[])} and null
s are allowed.
*
* @author Bryan Thompson
*
* @todo consider discarding all of the {@link #add(byte[])} methods. It is
* typically easier and more convenient to directly manage the existing
* {@link MutableKeyBuffer} and {@link MutableValueBuffer}. However, there
* are also {@link MutableKeysRaba} and {@link MutableValueRaba}
* implementations which are, I believe, only used by the
* {@link ResultSet}.
*/
public interface IRaba extends Iterable {
/**
* Return true
if this implementation is read-only.
*/
boolean isReadOnly();
/**
* When true
the {@link IRaba} supports search and elements are
* interpreted as unsigned byte[]
s (B+Tree keys). For this case
* the application MUST ensure that the elements are maintained in
* unsigned byte[]
order and that duplicates byte[]s are not
* stored.
*
* When false
, the {@link IRaba} allows null
s and
* the elements are interpreted as signed byte[]
(B+Tree
* values).
*
* @return true
if the {@link IRaba} represents B+Tree keys and
* false
if it represents B+Tree values.
*/
boolean isKeys();
/*
* TODO This could be added to differentiate between IRaba implementations
* that do / do not support duplicate keys. The ones used with the HTree do.
* The rest do not.
*/
// /**
// * When true
, then {@link IRaba} supports duplicate keys.
// *
// * @see
// * Stochastic Results With Analytic Query Mode
// */
// boolean isDuplicateKeys();
/**
* The capacity of the logical byte[][].
*
* @todo Coded rabas generally impose capacity == size
while
* only mutable rabas have a sense of capacity GTE size. Some of the
* unit tests assume that all rabas are dimensions based on the
* branching factor, which is no longer true. By moving this method
* onto the mutable IRaba implementations we would uncover those
* assumptions and clean things up a bit more.
*/
public int capacity();
/**
* The #of entries in the logical byte[][].
*/
public int size();
/**
* True iff the logical byte[][] is empty.
*/
public boolean isEmpty();
/**
* True iff the logical byte[][] is full.
*/
public boolean isFull();
/**
* Return true
iff the byte[] at that index is
* null
. If {@link IRaba#isKeys()} would return
* true
then this method MUST return false
since
* null
s are not permitted for B+Tree keys.
*
* @param index
* The index in [0:{@link #size()}-1].
* @throws IndexOutOfBoundsException
* unless index is in [0:{@link #size()}-1].
*/
public boolean isNull(int index);
/**
* The length of the byte[] at that index.
*
* @param index
* The index in [0:{@link #size()}-1].
*
* @return The length of the byte[] at that index.
*
* @throws NullPointerException
* if the key at that index is null
.
* @throws IndexOutOfBoundsException
* unless index is in [0:{@link #size()}-1].
*/
public int length(int index);
/**
* Return the byte[] at the specified index. For greater efficiency,
* implementations MAY return a reference to an internal the byte[].
*
* @param index
* The index in [0:{@link #size()}-1].
*
* @return The byte[] value at that index and null
if a
* null
value was stored at that index.
*
* @throws IndexOutOfBoundsException
* unless index is in [0:{@link #size()}-1].
*/
public byte[] get(int index);
/**
* Copy the value at the specified index onto the output stream. This is
* often used with an {@link ByteArrayBuffer} so that the same backing
* byte[] can be overwritten by each visited key.
*
* @param index
* The index in [0:{@link #size()}-1].
* @param out
* The output stream onto which the key will be copied.
*
* @return The #of bytes copied.
*
* @throws IndexOutOfBoundsException
* unless index is in [0:{@link #size()}-1].
* @throws NullPointerException
* if the byte[] value at that index is null
.
* @throws RuntimeException
* if the {@link OutputStream} throws an {@link IOException}
* (generally the {@link OutputStream} is writing onto a byte[]
* so it is more convenient to masquerade this exception).
*/
public int copy(int index, OutputStream os);
/**
* Iterator visits the byte[] elements in the view order. If an element is
* null
, then the iterator will report a null
for
* that element.
*/
@Override
public Iterator iterator();
/*
* Mutation operations (optional).
*/
/**
* Set the byte[] value at the specified index (optional operation).
*
* @param index
* The index in [0:{@link #size()}-1].
* @param a
* The byte[] value.
*
* @throws IndexOutOfBoundsException
* unless index is in [0:{@link #size()}-1].
* @throws IllegalArgumentException
* if the value is null
and null values are not
* supported by this implementation.
*/
public void set(int index, byte[] a);
/**
* Append a byte[] value to the end of the logical byte[][] (optional
* operation).
*
* @param a
* A value.
*
* @return The #of values in the logical byte[][] (postcondition).
*
* @throws IllegalArgumentException
* if the value is null
and null values are not
* supported by this implementation.
*/
public int add(byte[] a);
/**
* Append a byte[] value to the end of the logical byte[][] (optional
* operation).
*
* @param value
* A value
* @param off
* The offset of the first byte to be copied.
* @param len
* The #of bytes to be copied.
*
* @return The #of values in the logical byte[][] (postcondition).
*
* @throws IllegalArgumentException
* if the value is null
.
*/
public int add(byte[] value, int off, int len);
/**
* Append a byte[] value to the end of the logical byte[][] (optional
* operation).
*
* @param in
* The input stream from which the byte[] will be read.
* @param len
* The #of bytes to be read.
*
* @return The #of values in the logical byte[][] (postcondition).
*
* @throws IllegalArgumentException
* if in is null
.
*
* @todo also define variant of {@link #set(int, byte[])} that copies bytes
* from an input stream?
*/
public int add(DataInput in, int len) throws IOException;
/*
* Search (optional).
*/
/**
* Search for the given searchKey in the key buffer (optional
* operation). Whether or not search is supported depends on whether the
* logical byte[][] is ordered. However, the efficiency of search,
* where supported, depends on the implementation. Some implementations
* support binary search of the coded byte[] values. Others may require a
* mixture of binary and linear search, etc.
*
*
*
* entryIndex = -entryIndex - 1
*
*
* or just
*
*
* entryIndex = -entryIndex
*
*
* if you are looking for the first key after the searchKey.
*
*
* @param searchKey
* The search key.
*
* @return index of the search key, if it is found; otherwise,
* (-(insertion point) - 1)
. The insertion point is
* defined as the point at which the key would be inserted. Note
* that this guarantees that the return value will be >= 0 if and
* only if the key is found.
*
* @exception IllegalArgumentException
* if the searchKey is null.
*
* @throws UnsupportedOperationException
* if search is not supported.
*/
int search(byte[] searchKey);
}