public class ReadCommittedView extends Object implements ILocalBTreeView
This class is designed to work both with a Journal and with an
IndexManager. For the latter, the live StoreManager.ManagedJournal will
periodically be replaced by another StoreManager.ManagedJournal. This means that
we need two levels of indirection. First, we need to be able to identify the
current journal and read the lastCommitTime off of the current root block for
that journal. Second, we need to replace the view of the BTree for
the named index with the canonical read-only BTree instance loaded
from the commit record corresponding to the lastCommitTime.
Note: We are not required to obtain a lock on the live journal since it will not be closed if it overflows, just closed for writes. Therefore this class will provide a read-committed view as of (a) the moment that it obtains the then current journal; and (b) checks the lastCommitTime on that journal. If there are intervening commits or an overflow event then the data will be "only slightly stale".
Note: This class has very little state of its own. The bulk of the state is
on the BTree objects corresponding to the lastCommitTime. Those are
thread-safe for readers and are shared across instances of this class.
Note: At any given moment, two instances of this class for the same named index MAY have a different view. However, the views will always reflect the lastCommitTime for each instance that is resolved when a method is invoked on its public API.
| Constructor and Description |
|---|
ReadCommittedView(IResourceManager resourceManager,
String name) |
| Modifier and Type | Method and Description |
|---|---|
boolean |
contains(byte[] key)
Return
true iff there is a (non-deleted) index entry for
the key. |
boolean |
contains(Object key)
Return true iff there is an entry for the key.
|
IBloomFilter |
getBloomFilter()
Return the bloom filter.
|
ICounter |
getCounter()
A restart-safe counter.
|
CounterSet |
getCounters()
Return performance counters.
|
IndexMetadata |
getIndexMetadata()
The metadata for the index.
|
BTree |
getMutableBTree()
The
BTree that is absorbing writes for the view. |
IResourceMetadata[] |
getResourceMetadata()
The description of the resources comprising the index view.
|
int |
getSourceCount()
The #of
AbstractBTrees sources for the view. |
AbstractBTree[] |
getSources()
An array containing the ordered sources in the view.
|
byte[] |
insert(byte[] key,
byte[] value)
Insert or update a value under the key.
|
Object |
insert(Object key,
Object value)
Insert with auto-magic handling of keys and value objects.
|
byte[] |
lookup(byte[] key)
Lookup a value for a key.
|
Object |
lookup(Object key)
Lookup a value for a key.
|
byte[] |
putIfAbsent(byte[] key,
byte[] value)
Insert or update a value under the key iff there is no entry for that key
in the index.
|
long |
rangeCount()
Return the #of tuples in the index.
|
long |
rangeCount(byte[] fromKey,
byte[] toKey)
Return the #of tuples in a half-open key range.
|
long |
rangeCountExact(byte[] fromKey,
byte[] toKey)
Return the exact #of tuples in a half-open key range.
|
long |
rangeCountExactWithDeleted(byte[] fromKey,
byte[] toKey)
Return the exact #of tuples in a half-open key range, including any
deleted tuples.
|
ITupleIterator |
rangeIterator()
Note: The iterators returned by this view will be
read-consistent as of the lastCommitTime when they are
created.
|
ITupleIterator |
rangeIterator(byte[] fromKey,
byte[] toKey)
Return an iterator that visits the entries in a half-open key range.
|
ITupleIterator |
rangeIterator(byte[] fromKey,
byte[] toKey,
int capacity,
int flags,
IFilter filterCtor)
Designated variant (the one that gets overridden) for an iterator that
visits the entries in a half-open key range.
|
byte[] |
remove(byte[] key)
Remove the key and its associated value.
|
Object |
remove(Object key)
Remove the key and its associated value.
|
void |
submit(byte[] fromKey,
byte[] toKey,
IKeyRangeIndexProcedure proc,
IResultHandler handler)
The procedure will be transparently applied against each index partition
spanned by the given key range.
|
Object |
submit(byte[] key,
ISimpleIndexProcedure proc)
Submits an index procedure that operations on a single key to the
appropriate index partition returning the result of that procedure.
|
void |
submit(int fromIndex,
int toIndex,
byte[][] keys,
byte[][] vals,
AbstractKeyArrayIndexProcedureConstructor ctor,
IResultHandler resultHandler)
Runs a procedure against an index.
|
public ReadCommittedView(IResourceManager resourceManager, String name)
resourceManager - The object that will report to us the live journal.name - The name of the index.public ICounter getCounter()
IIndexLocalCounterCheckpoint record. For a partitioned index, there is a
distinct counter for each index partition, the partition identifier is
used as the high int32 bits of the counter, and the low int32 of the
counter has an initial value of zero (0) in each index partition.getCounter in interface IIndexLocalCounterpublic CounterSet getCounters()
IIndexInteresting performance counters and other statistics about the index.
getCounters in interface IIndexgetCounters in interface ICounterSetAccesspublic IndexMetadata getIndexMetadata()
IIndex
Note: The same method is exposed by ICheckpointProtocol. It is
also exposed here in order to provide access to the IndexMetadata
to remote clients in the scale-out architecture.
getIndexMetadata in interface IIndexICheckpointProtocol.getIndexMetadata()public IResourceMetadata[] getResourceMetadata()
IIndexgetResourceMetadata in interface IIndexpublic boolean contains(byte[] key)
ISimpleBTreetrue iff there is a (non-deleted) index entry for
the key. An index entry with a null value will cause this
method to return true. A deleted index entry will cause
this method to return false.contains in interface ISimpleBTreekey - The key.true if the index contains an (un-deleted) entry
for that key.public boolean contains(Object key)
IAutoboxBTreecontains in interface IAutoboxBTreekey - The key is implicitly converted to an unsigned
byte[].public byte[] lookup(byte[] key)
ISimpleBTreelookup in interface ISimpleBTreenull if there
is no entry for that key or if the entry under that key is marked
as deleted.public Object lookup(Object key)
IAutoboxBTreelookup in interface IAutoboxBTreekey - The key is implicitly converted to an unsigned
byte[].null if there is no
entry for that key.public byte[] remove(byte[] key)
ISimpleBTreeremove in interface ISimpleBTreekey - The key.null if the key
was not found or if the previous entry under that key was marked
as deleted.public Object remove(Object key)
IAutoboxBTreeremove in interface IAutoboxBTreekey - The key is implicitly converted to an unsigned
byte[].null if the key was not found.public byte[] insert(byte[] key,
byte[] value)
ISimpleBTreeinsert in interface ISimpleBTreekey - The key.value - The value (may be null).null if the
key was not found or if the previous entry for that key was
marked as deleted.public byte[] putIfAbsent(byte[] key,
byte[] value)
ISimpleBTree
if (!contains(key))
insert(key, value);
However, if the index allows null values to be stored under
a key and the application in fact stores null values for
some tuples, then caller is not able to decide using this method whether
or not the mutation was applied based on the return value. For these
cases if the caller needs to know whether or not the conditional mutation
actually took place, the caller CAN use the pattern
if(!contains()) insert(key,value); to obtain that
information.putIfAbsent in interface ISimpleBTreekey - The key.value - The value (may be null).null if the key
was not found or if the previous entry for that key was marked as
deleted. Note that the return value MAY be null even
if there was an entry under the key. This is because the index is
capable of storing a null value. In such cases the
conditional mutation WAS NOT applied.(putIfAbsent)public Object insert(Object key, Object value)
IAutoboxBTreeinsert in interface IAutoboxBTreekey - The key is implicitly converted to an unsigned
byte[].value - The value is implicitly converted to a byte[].null if there was
no value stored under that key.public long rangeCount()
IRangeQueryNote: If the index supports deletion markers then the range count will be an upper bound and may double count tuples which have been overwritten, including the special case where the overwrite is a delete.
rangeCount in interface IRangeQueryISimpleIndexAccess.rangeCount()public long rangeCount(byte[] fromKey,
byte[] toKey)
IRangeQueryNote: If the index supports deletion markers then the range count will be an upper bound and may double count tuples which have been overwritten, including the special case where the overwrite is a delete.
rangeCount in interface IRangeQueryfromKey - The lowest key that will be counted (inclusive). When
null there is no lower bound.toKey - The first key that will not be counted (exclusive). When
null there is no upper bound.public long rangeCountExact(byte[] fromKey,
byte[] toKey)
IRangeQueryNote: If the index supports deletion markers then this operation will require a key-range scan.
rangeCountExact in interface IRangeQueryfromKey - The lowest key that will be counted (inclusive). When
null there is no lower bound.toKey - The first key that will not be counted (exclusive). When
null there is no upper bound.public long rangeCountExactWithDeleted(byte[] fromKey,
byte[] toKey)
IRangeQuery
When the view is just an AbstractBTree the result is the same as
for IRangeQuery.rangeCount(byte[], byte[]), which already
reports all tuples regardless of whether or not they are deleted.
When the index is a view with multiple sources, this operation requires a key-range scan where both deleted and undeleted tuples are visited.
rangeCountExactWithDeleted in interface IRangeQueryfromKey - The lowest key that will be counted (inclusive). When
null there is no lower bound.toKey - The first key that will not be counted (exclusive). When
null there is no upper bound.IRangeQuery.rangeCountExact(byte[], byte[])public ITupleIterator rangeIterator()
rangeIterator in interface IRangeQuerypublic ITupleIterator rangeIterator(byte[] fromKey, byte[] toKey, int capacity, int flags, IFilter filterCtor)
IRangeQueryrangeIterator in interface IRangeQueryfromKey - The first key that will be visited (inclusive lower bound).
When null there is no lower bound.toKey - The first key that will NOT be visited (exclusive upper
bound). When null there is no upper bound.capacity - The #of entries to buffer at a time. This is a hint and MAY be
zero (0) to use an implementation specific default
capacity. A non-zero value may be used if you know that you
want at most N results or if you want to override the default
#of results to be buffered before sending them across a
network interface. (Note that you can control the default
value using
IBigdataClient.Options#DEFAULT_CLIENT_RANGE_QUERY_CAPACITY).flags - A bitwise OR of IRangeQuery.KEYS, IRangeQuery.VALS, etc.filterCtor - An optional object used to construct a stacked iterator. When
IRangeQuery.CURSOR is specified in flags, the base
iterator will implement ITupleCursor and the first
filter in the stack can safely cast the source iterator to an
ITupleCursor. If the outermost filter in the stack
does not implement ITupleIterator, then it will be
wrapped an ITupleIterator.SuccessorUtil, which may be used to compute the successor of a value
before encoding it as a component of a key.,
BytesUtil#successor(byte[]), which may be used to compute the
successor of an encoded key.,
IFilterConstructor, which may be used to construct an iterator stack
performing filtering or other operations.public ITupleIterator rangeIterator(byte[] fromKey, byte[] toKey)
IRangeQueryrangeIterator in interface IRangeQueryfromKey - The first key that will be visited (inclusive lower bound).
When null there is no lower bound.toKey - The first key that will NOT be visited (exclusive upper
bound). When null there is no upper bound.SuccessorUtil, which may be used to compute the successor of a value
before encoding it as a component of a key.,
BytesUtil#successor(byte[]), which may be used to compute the
successor of an encoded key.,
EntryFilter, which may be used to filter the entries visited by the
iterator.public void submit(byte[] fromKey,
byte[] toKey,
IKeyRangeIndexProcedure proc,
IResultHandler handler)
IIndex
Note: Since this variant of submit() does not split keys the
fromIndex and toIndex in the Splits reported to
the IResultHandler will be zero (0).
submit in interface IIndexfromKey - The lower bound (inclusive) -or- null if there
is no lower bound.toKey - The upper bound (exclusive) -or- null if there
is no upper bound.proc - The procedure. If the procedure implements the
IParallelizableIndexProcedure marker interface then it
MAY be executed in parallel against the relevant index
partition(s).public Object submit(byte[] key, ISimpleIndexProcedure proc)
IIndexsubmit in interface IIndexkey - The key.proc - The procedure.IIndexProcedure.apply(IIndex)public void submit(int fromIndex,
int toIndex,
byte[][] keys,
byte[][] vals,
AbstractKeyArrayIndexProcedureConstructor ctor,
IResultHandler resultHandler)
IIndex
Note: This may be used to send custom logic together with the data to a
remote index or index partition. When the index is remote both the
procedure and the return value MUST be Serializable.
Note: The scale-out indices add support for auto-split of the procedure such that it runs locally against each relevant index partition.
submit in interface IIndexfromIndex - The index of the first key to be used (inclusive).toIndex - The index of the last key to be used (exclusive).keys - The keys (required).vals - The values (optional depending on the procedure).ctor - An object that can create instances of the procedure.resultHandler - When defined, results from each procedure application will be
reported to this object.
TODO In order to allow parallelization within a shard, we need to modify
this method signature to pass in an IResultHandler constructor
object. That might be something which could be pushed down onto the ctor
argument. It would be used in scale-out to create a DS local result handler
so we can locally aggregate when parallelizing against each shard and then
return that aggregated result to the client which would extract the aggregate
result across the shards from the client's result handler. See BLZG-1537.(Schedule more IOs when loading data)public IBloomFilter getBloomFilter()
ILocalBTreeViewgetBloomFilter in interface ILocalBTreeViewnull.public BTree getMutableBTree()
ILocalBTreeViewBTree that is absorbing writes for the view.getMutableBTree in interface ILocalBTreeViewpublic int getSourceCount()
ILocalBTreeViewAbstractBTrees sources for the view. This will be ONE (1)
if the view is a BTree.getSourceCount in interface ILocalBTreeViewpublic AbstractBTree[] getSources()
ILocalBTreeViewAbstractBTree then the
array will contain a single element which is that AbstractBTree.getSources in interface ILocalBTreeViewCopyright © 2006–2019 SYSTAP, LLC DBA Blazegraph. All rights reserved.