public class ResultSet extends Object implements ILeafData, Externalizable
Note: The IRangeQuery
bit flags may be used to indicate which data
and metadata are returned. If the corresponding data was not requested then
the access methods for that data will throw an
UnsupportedOperationException
. You can test this using
hasDeleteMarkers()
, hasVersionTimestamps()
and related
methods.
FIXME Do not decode the delete flags or version timestamps. Code per
ReadOnlyLeafData
and then use the coded representations in place.
Modifier and Type | Field and Description |
---|---|
protected static short |
VERSION0 |
Modifier | Constructor and Description |
---|---|
|
ResultSet()
Deserialization constructor.
|
protected |
ResultSet(IIndex ndx,
int flags)
The basic approach is:
Create a new
ResultSet
Invoke init(int) to setup the internal buffers.
Apply the source ITupleIterator , using
copyTuple(ITuple) to copy data into those buffers.
Signal completion using done(boolean, byte[])
|
|
ResultSet(IIndex ndx,
int capacity,
int flags,
ITupleIterator itr)
Constructor used to populate the
ResultSet directly from an
iterator. |
Modifier and Type | Method and Description |
---|---|
protected void |
assertRunning()
|
protected void |
copyTuple(ITuple<?> tuple)
Copies the data from the tuple into the internal buffers.
|
AbstractFixedByteArrayBuffer |
data()
FIXME If we extend
DefaultLeafCoder or implement "ResultSetCoder"
then we can really adhere to these semantics. |
protected void |
done(boolean exhausted,
byte[] lastKey)
Notify that the iterator is done and communicate metadata back to the
client about whether or not a continuation query should be issued against
this index partition.
|
long |
getCommitTime()
Return the commitTime of the index view from which this result set was
read.
|
boolean |
getDeleteMarker(int index)
Return
true iff the entry at the specified index is marked
as deleted. |
int |
getKeyCount()
Return the #of keys in the node or leaf.
|
IRaba |
getKeys()
Return the keys.
|
byte[] |
getLastKey()
The last key visited by the iterator regardless of the
filter imposed -or-
null iff no keys were visited by
the iterator for the specified key range. |
protected int |
getLimit()
The value of the limit specified to the ctor.
|
long |
getMaximumVersionTimestamp()
The most recent tuple revision timestamp associated with any tuple
spanned by this node or leaf.
|
long |
getMinimumVersionTimestamp()
The earliest tuple revision timestamp associated with any tuple spanned
by this node or leaf.
|
long |
getNextAddr()
The address of the next leaf in key order,
0L if it is known
that there is no next leaf, and -1L if either: (a) it is not
known whether there is a next leaf; or (b) it is known but the address of
that leaf is not known to the caller. |
int |
getNumTuples()
Actual #of key-value pairs in the
ResultSet |
long |
getPriorAddr()
The address of the previous leaf in key order,
0L if it is
known that there is no previous leaf, and -1L if either: (a)
it is not known whether there is a previous leaf; or (b) it is known but
the address of that leaf is not known to the caller. |
long |
getRawRecord(int index)
Return the address of the raw record on the backing store of the value
stored in the tuple having the given index -or-
IAddressManager.NULL if
the value is the actual byte[] value associated with the key
in the leaf. |
int |
getSourceIndex(int index)
The values returned by
ITuple.getSourceIndex() for each visited
index entry. |
IResourceMetadata[] |
getSources()
Return the ordered array of sources from which the iterator read and the
ResultSet was populated. |
ITupleSerializer |
getTupleSerializer()
The
ITupleSerializer that should be used to de-serialize the
tuples in the ResultSet . |
int |
getValueCount()
The #of values in the leaf (this MUST be equal to the #of keys for a
leaf).
|
IRaba |
getValues()
Return the values.
|
long |
getVersionTimestamp(int index)
The version timestamp for the entry at the specified index.
|
boolean |
hasDeleteMarkers()
Return
true iff the leaf maintains delete markers. |
boolean |
hasRawRecords()
Return
true iff the leaf promotes large byte[]
values to raw records on the backing store. |
boolean |
hasVersionTimestamps()
Return
true iff the leaf maintains version timestamps. |
protected void |
init(int limit)
Setup the internal buffers.
|
boolean |
isCoded()
true iff this is a coded data structure. |
boolean |
isDoubleLinked()
No.
|
boolean |
isExhausted()
True iff the iterator exhausted the available keys such that no more
results would be available if you formed the successor of the
lastKey . |
protected boolean |
isFull()
true iff the internal buffers are full. |
boolean |
isLeaf()
Yes (this data structure logically corresponds to a leaf since it
implements the
ILeafData API). |
boolean |
isReadOnly()
Yes (the data structure is populated during the ctor and is read-only
thereafter).
|
void |
readExternal(ObjectInput in) |
void |
writeExternal(ObjectOutput out) |
public ResultSet()
protected ResultSet(IIndex ndx, int flags)
ResultSet
init(int)
to setup the internal buffers.ITupleIterator
, using
copyTuple(ITuple)
to copy data into those buffers.done(boolean, byte[])
ndx
- The index.flags
- The flags specified for the iterator. See IRangeQuery
.public ResultSet(IIndex ndx, int capacity, int flags, ITupleIterator itr)
ResultSet
directly from an
iterator.
Note: The itr provided to this method MUST be created with
IRangeQuery.KEYS
so that we can report the lastKey visited for
continuation queries.
ndx
- The index.capacity
- The requested capacity for the operation.flags
- The flags specified for the iterator.itr
- The source iterator.public final int getNumTuples()
ResultSet
public final boolean isExhausted()
lastKey
.public final byte[] getLastKey()
null
iff no keys were visited by
the iterator for the specified key range.#successor()
public final ITupleSerializer getTupleSerializer()
ITupleSerializer
that should be used to de-serialize the
tuples in the ResultSet
.public final IRaba getKeys()
getKeys
in interface IKeysData
UnsupportedOperationException
- if the keys were not retrieved.public final IRaba getValues()
getValues
in interface ILeafData
UnsupportedOperationException
- if the values were not retrieved.ILeafData.hasDeleteMarkers()
,
ILeafData.getDeleteMarker(int)
public final int getSourceIndex(int index)
ITuple.getSourceIndex()
for each visited
index entry.public final long getCommitTime()
ITx.UNISOLATED
or
ITx.READ_COMMITTED
chunked iterator to produce a consistent view
by issuing continuation queries for the commitTime that was returned by
the initial ResultSet
.public final IResourceMetadata[] getSources()
ResultSet
was populated.
The values returned by ITuple.getSourceIndex()
may be used to
identify the resource from which a given tuple was read. That information
is used to direct ITuple.readBlock(long)
requests to the correct
resource on the IDataService
.
protected int getLimit()
Note: This field is transient - it does not get (de-)serialized.
protected void init(int limit)
limit
- The maximum #of tuples that will be materialized. Use (-limit)
for a soft limit. The caller should either use the suggested
capacity, compute either an actual limit or the upper bound
based on additional information, such as a range count, or
treat the suggested capacity as a soft limit if it is not
possible to determine the upper bound.protected void done(boolean exhausted, byte[] lastKey)
Note: the point of this method is to communicate the restart point for a continuation query (or that no continuation query is necessary). If you are scanning ahead to decide whether or not the next coherent chunk of tuples (e.g., a logical row) would fit in the buffer, then the restart point is the point from which the continuation query should start and the key to report is the last key before the start of the first logical row that was rejected because it would overflow the internal buffers.
Note: !exhausted
the caller will issue a continuation
query against this index partition whose fromKey is the successor
of lastKey (the successor is formed using
BytesUtil.successor(byte[])
).
Note: If an index partition is exhausted there may still be data for the key range on subsequent index partitions the caller will discover the locator for the next index partition in key order whose left separator key is LE the toKey and query it for more results. If there is no such index partition then the aggregate iterator is finished.
exhausted
- true
iff the source iterator will not visit any
more tuples Iterator.hasNext()
is false
.lastKey
- The key from the last tuple scanned by the source iterator
regardless of whether it was included in the result set -or-
null
iff no tuples were scanned (this implies
that there is no data for the query in the key range on this
index partition and hence that it is exhausted).protected boolean isFull()
true
iff the internal buffers are full.protected void copyTuple(ITuple<?> tuple)
tuple
- The tuple.protected void assertRunning()
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
readExternal
in interface Externalizable
IOException
ClassNotFoundException
public void writeExternal(ObjectOutput out) throws IOException
writeExternal
in interface Externalizable
IOException
public final boolean hasDeleteMarkers()
ILeafData
true
iff the leaf maintains delete markers.hasDeleteMarkers
in interface ILeafData
public final boolean hasVersionTimestamps()
ILeafData
true
iff the leaf maintains version timestamps.hasVersionTimestamps
in interface IAbstractNodeData
hasVersionTimestamps
in interface ILeafData
public final long getVersionTimestamp(int index)
ILeafData
getVersionTimestamp
in interface ILeafData
public final boolean getDeleteMarker(int index)
ILeafData
true
iff the entry at the specified index is marked
as deleted.getDeleteMarker
in interface ILeafData
public final int getKeyCount()
IKeysData
nkeys+1
children. A leaf has nkeys
keys and values. The maximum #of
keys for a node is one less than the branching factor of the B+Tree. The
maximum #of keys for a leaf is the branching factor of the B+Tree. For a
hash bucket, this is the #of entries in the bucket.getKeyCount
in interface IKeysData
public final int getValueCount()
ILeafData
getValueCount
in interface ILeafData
public final boolean isLeaf()
ILeafData
API).isLeaf
in interface IAbstractNodeData
public final boolean isReadOnly()
isReadOnly
in interface IAbstractNodeData
public final boolean isCoded()
IAbstractNodeData
true
iff this is a coded data structure.isCoded
in interface IAbstractNodeData
public final AbstractFixedByteArrayBuffer data()
DefaultLeafCoder
or implement "ResultSetCoder"
then we can really adhere to these semantics.data
in interface IAbstractNodeData
data
in interface IDataRecordAccess
public final boolean isDoubleLinked()
isDoubleLinked
in interface ILeafData
public final long getNextAddr()
ILeafData
0L
if it is known
that there is no next leaf, and -1L
if either: (a) it is not
known whether there is a next leaf; or (b) it is known but the address of
that leaf is not known to the caller.getNextAddr
in interface ILeafData
public final long getPriorAddr()
ILeafData
0L
if it is
known that there is no previous leaf, and -1L
if either: (a)
it is not known whether there is a previous leaf; or (b) it is known but
the address of that leaf is not known to the caller.getPriorAddr
in interface ILeafData
public final long getMinimumVersionTimestamp()
IAbstractNodeData
Long.MAX_VALUE
since the initial value of the minimum
version timestamp is always the largest possible long integer.getMinimumVersionTimestamp
in interface IAbstractNodeData
public final long getMaximumVersionTimestamp()
IAbstractNodeData
Long.MIN_VALUE
since the initial value of the
maximum version timestamp is always the smallest possible long integer.getMaximumVersionTimestamp
in interface IAbstractNodeData
public final long getRawRecord(int index)
IAddressManager.NULL
if
the value is the actual byte[]
value associated with the key
in the leaf. When the value is the address of a raw record, the actual
byte[] value
should be read from the backing store using the
decoded address.
Raw record addresses are created transparently when a large
byte[]
is associated with a key in the leaf. They are
materialized transparently when the tuple associated with the leaf is
read. They are deleted when the tuple associated with the leaf is
deleted.
Note: Raw records are managed at the leaf, rather than the IRaba
level, because there is not always a backing store associated with an
IRaba
object. This is similar to how deleted tuples are handled.
However, IRabaCoder
s are responsible for coding the
long
address stored in the values raba
.
Raw records are only used for large byte[] values. Highly specialized
IRabaCoder
s can avoid the potential for a conflict with their own
coding scheme by ensuring that the index either will not promote large
values to raw records or by refraining from inserting large values into
the index.
Note: This implementation always returns IAddressManager.NULL
since raw
records have already been materialized.
getRawRecord
in interface ILeafData
IAddressManager.NULL
public final boolean hasRawRecords()
true
iff the leaf promotes large byte[]
values to raw records on the backing store.
Note: This implementation always returns false
since raw
records have already been materialized and therefore can not be reported
by getRawRecord(int)
using this class.
hasRawRecords
in interface ILeafData
Copyright © 2006–2019 SYSTAP, LLC DBA Blazegraph. All rights reserved.