public final class Key extends Object implements Comparable<Object>
Encapsulates the key used in storing, fetching or deleting a key/value pair
from a Persistit™ database. A Key
's state is represented
by an array of bytes that are used to physically locate records in a
Tree
. The architectural maximum length of this byte array is
2,047 bytes. Thus a Key
may be used to represent a significant,
but not unlimited amount of information. Applications may use the Low-Level API methods to access and modify the key's
backing byte array directly. However, Key
provides a recommended
higher-level API that simplifies encoding and decoding Java values.
Within a Tree
, keys are ordered in lexicographic order, by
unsigned byte value. Thus keys encoded physically as shown will be stored in
the following order:
1st: {0x01, 0x01} 2nd: {0x01, 0x01, 0x02, 0x01} 3rd: {0x01, 0x01, 0x03, 0x01} 4th: {0x01, 0x01, 0x03, 0x02} 4th: {0x01, 0x02, 0x01} 6th: {0x01, 0x02, 0x01, 0x01} 7th: {0x01, 0x02, 0x04, 0xE3} 8th: {0xF7, 0x03} 9th: {0xF9}The ordering is important because it governs the order in which the
Exchange.traverse(com.persistit.Key.Direction, boolean)
operations visit records, and the set of keys/value
pairs that will be removed by the range Exchange.remove()
operations.
Key ordering also affects the physical proxmitity of items in the
Tree
's on-disk representation, which can affect performance.
Key
provides methods to encode and decode logical
values into and from the backing byte array. For example, the
append(int)
method encodes an int into the key in such a way that
the natural ordering of integer values is preserved; that is, for integers u
and v if u > v then the key encoded from u always follows that encoded
from v in lexicographic order. The append
method is overloaded
to support each primitive Java type and Object
. The ordering of
key values within each primitive type follows the natural ordering for that
type (see String Encoding for information
on collation of Strings).
There is also an implicit ordering between different encoded types. The ordering of key values with differing types is as follows:
BEFORE < null < boolean < byte < short < char < int < long < float < double < java.math.BigInteger < java.math.BigDecimal < byte[] < java.lang.String < java.util.Date < custom-encoded types < AFTER(Note:
BEFORE
and AFTER
are special pseudo-values that
allow traversal from the first and last keys in a tree.)
By default Key
encodes objects of type Boolean
,
Byte
, Short
, Character
,
Integer
, Long
, Float
and
Double
exactly the same as their primitive counterparts. Thus
the decode()
method, which returns an Object, can be used uniformly to
decode values that were appended as either primitives or their wrapped
equivalents.
By default Strings are encoded in a modified UTF-8 format. This encoding preserves alphabetic ordering of all 7-bit ASCII strings. Character codes above 128 are translated into two- or three-byte sequences according to the UTF-8 specification. The protocol is modified for the NUL character (code 0), because encoded key values are terminated by NUL. Persistit encodes a NUL embedded within a String with the two-byte sequence (0x01, 0x20), and encodes SOH (code 1) with the sequence (0x01, 0x21).
The default string-encoding algorithm does not support localized collation. TODO - add collation information here - TODO
Persistit offers built-in support for encoding and decoding of a few commonly used Object types. These include:
java.lang.String java.math.BigInteger java.math.BigDecimal java.util.Date byte[](Note that for byte array, a zero-valued bytes are converted to two-byte sequences, as described above for strings.)
The default encoding for these types, plus any additional Object types that
are required to be used as key values, can be overridden by a custom
KeyCoder
. For consistency, the application
should register all custom KeyCoder
objects immediately after
initializing Persistit, for example:
All overridden object types sort after all other value types. Ordering
among various custom types is determined by the custom encoding algorithm's
implementation. See
Persistit.initialize();
KeyCoder coder = new MyKeyCoder();
Persistit.getInstance().getCoderManager()
.registerKeyCoder(MyClass.class, coder);
CoderManager
for details.
An application may append multiple values to a Key
, each of
which is called a key segment. Applications use multiple segments to
form concatenated keys. A concatenated key uniquely identifies a particular
record by a combination of data values rather than one simple value. The
number of segments in a Persistit concatenated key is bounded only by the
architectural limitation on the length of the underlying byte array.
Key
encodes strings, byte
arrays, and all other data types that might naturally contain a zero- valued
byte by inserting escape sequences in place of the zero values. Specifically,
NUL (character code 0) in a string, or a zero in a byte array element is
replaced by the two-byte sequence (0x01, 0x20). An SOH (character code 1) or
a one in a byte array element is replaced by the two-byte sequence (0x01,
0x021). This scheme is handled automatically, and only those applications
that manipulate the raw byte buffer using the low-level API need to be aware
of it. This encoding ensures that the key orderering preserves the natural
ordering of the underlying values. For example, the encoded forms of the two
string "AB" and "ABC" are (0x80, 0x41, 0x42, 0x00) and (0x80, 0x41, 0x42,
0x43, 0x00), respectively. The two encodings differ in the third byte (the
zero that terminates the shorter string) which correctly causes the shorter
string to collate before the longer one.
Segments fall naturally into the ordering scheme. If two keys are different,
then the first segment that differs between the two keys controls their
ordering. For example, the code fragment
sets the four keys so that their ordering sequence is
key1.clear().append(1).append(1);
key2.clear().append(1).append(2);
key3.clear().append(2).append(1);
key4.clear().append(2).append(1).append(0);
key1 < key2 < key3 < key4.
The ability to append multiple key segments to a Key
supports a
method of grouping records logically by hierarchical key values. Much as a
paper filing system uses cabinets, drawers, and folders to organize
documents, segmented keys can be used to impose a hierarchical organization
on data. For example, the key for a purchase order record might have a single
segment representing the purchase order number. The purchase order's
subsidiary line items might then be stored with keys that are logical
children of the purchase order number, as suggested in this code snippet:
This example would store the PurchaseOrderSummary under a key containing just
the purchase order number, and then store each of the line items from the
poLineItems List in a key containing the purchase order number and the line
item number as separate segments. (The
PurchaseOrderSummary poSummary = ...
List poLineItems = ...
...
exchange.getValue().put(poSummary)
exchange.clear().append(poSummary.getPurchaseOrderNumber()).store();
..
exchange.append(Key.BEFORE);
for (Iterator items = poLineItems.iterator();
items.hasMore();)
{
LineItem item = (LineItem)lineItems.next();
exchange.getValue().set(item);
exchange.clear().to(item.getLineItemId()).store();
}
...
to(Object)
method is a
convenience method that replaces the final segment of the key with a new
value.)
Logical child relationships between keys are represented solely by the way in
which keys are encoded and ordered within the physical tree; there is no
direct physical representation of the logical hierarchy. However, because of
the way keys are physically ordered within a Tree
, logical child
keys fall closer to their parents in key sort order than other keys, and are
therefore more likely to be located on physical database pages that have
already been read into the buffer pool.
Two families of methods of methods in Exchange
incorporate logic to
handle logical child keys in a special way:
Exchange.traverse(Key.Direction, boolean)
method, and its
variants Exchange.next(boolean)
and
Exchange.previous(boolean)
are capable of either deep or
shallow traversal. If deep traversal is requested then the result is
the next (or previous) physical key in the Tree
, regardless of
whether it is a logical child key. However, if shallow traversal is
requested, all logical children are skipped and the result is the next (or
previous) logical sibling key value.Exchange.remove(Key.Direction)
method optionally removes the
key/value pair specified by the current key value and/or the logical children
of that key value. Continuing the purchase order example, the
remove
method can remove just the line items, just the purchase
order summary, or both.
At times it is convenient to represent a Key value as a String, for example,
to display it or enter it for editing. This class provides an implementation
of toString()
that creates a canonical String representation of a key.
The KeyParser.parseKey(com.persistit.Key)
method provides the inverse functionality,
parsing a canonical string representation to create a key value.
The String representation is of the form:
{ segment,... }where each segment value is one of the following:
null
false
true
Key key = new Key();
key.append("xyz").append(1.23).append((long)456).append(new Date());
System.out.println(key.toString());
would produce a string representation such as
{ "xyz", 1.23, (long) 456, (java.util.Date) 20040901114722.563 + 0500 }All numeric types other than
double
and int
use a
cast segment representation so to permit exact translation to and from the
String representation and the underlying internal key value. The canonical
representation of a Date is designed to allow exact translation to and from
the internal segment value while being somewhat legible.
Applications do two fundamental things with Key
s:
Methods used to construct key values are clear()
, setDepth(int)
,
cut()
, append(boolean)
, append(byte)
,
append(short)
... append(Object)
, to(boolean)
,
to(byte)
to(short)
... to(Object)
. These methods
all modify the current state of the key. As a convenience, these methods all
return the Key
to support method call chaining.
Methods used to decode key values are reset()
, indexTo(int)
,
decodeBoolean()
, decodeByte()
, decodeShort()
...
decode()
. These methods do not modify the value represented by the
key. Each decodeTTTT
method returns a value of type
TTTT. The decode()
method returns a value of type
Object
. The reset
and indexTo
control
which segment the next value will be decoded from.
The low-level API allows an application to bypass the encoding and decoding operations described above and instead to operate directly on the byte array used as the physical B-Tree key. This might be appropriate for an existing application that has already implemented its own serialization mechanisms, for example, or to accommodate special key manipulation requirements. Applications should use these methods only if there is a compelling requirement.
The low-level API methods are:
byte[]getEncodedBytes()
intgetEncodedSize()
voidsetEncodedSize(int)
Modifier and Type | Class and Description |
---|---|
static class |
Key.Direction
|
static class |
Key.EdgeValue
Enumeration of special key segment values used to traverse from the first
or last key.
|
Modifier and Type | Field and Description |
---|---|
static Key.EdgeValue |
AFTER
A
Key segment value that collates after any actual key in a
Tree . |
static Key.EdgeValue |
BEFORE
A
Key segment value that collates before any actual key in a
Tree . |
static Key.Direction[] |
DIRECTIONS
Used by journaling subsystem.
|
static Key.Direction |
EQ |
static Key.Direction |
GT |
static Key.Direction |
GTEQ |
static Key |
LEFT_GUARD_KEY
Key that always occupies the left edge of any
Tree |
static Key.Direction |
LT |
static Key.Direction |
LTEQ |
static int |
MAX_KEY_LENGTH
Absolute architectural maximum number of bytes in the encoding of a key.
|
static int |
MAX_KEY_LENGTH_UPPER_BOUND |
static String |
PREFIX_BIG_DECIMAL
Displayable prefix for BigDecimal values
|
static String |
PREFIX_BIG_DECIMAL0 |
static String |
PREFIX_BIG_INTEGER
Displayable prefix for BigInteger values
|
static String |
PREFIX_BIG_INTEGER0 |
static String |
PREFIX_BOOLEAN
Displayable prefix for boolean values (optional for input, implied and
supressed on output)
|
static String |
PREFIX_BYTE
Displayable prefix for byte values
|
static String |
PREFIX_BYTE_ARRAY
Displayable prefix for byte array values
|
static String |
PREFIX_CHAR
Displayable prefix for char values
|
static String |
PREFIX_DATE
Displayable prefix for Date values
|
static String |
PREFIX_DATE0 |
static String |
PREFIX_DOUBLE
Displayable prefix for double values (optional for input, implied and
suppressed on output)
|
static String |
PREFIX_FLOAT
Displayable prefix for float values
|
static String |
PREFIX_INT
Displayable prefix for int values (optional for input, implied and
supressed on output)
|
static String |
PREFIX_LONG
Displayable prefix for long values
|
static String |
PREFIX_SHORT
Displayable prefix for short values
|
static String |
PREFIX_STRING
Displayable prefix for String values (optional for input, implied and
suppressed on output)
|
static String |
PREFIX_STRING0 |
static Key |
RIGHT_GUARD_KEY
Key that always occupies the right edge of any
Tree |
static SimpleDateFormat |
SDF
The
java.text.SimpleDateFormat used in formatting
Date - valued keys in the decodeDisplayable(boolean) methods. |
Constructor and Description |
---|
Key(Key source)
Constructs a
Key which duplicates the state of the supplied
Key . |
Key(Persistit persistit)
Construct a
Key with a maximum length of
2047. |
Key(Persistit persistit,
int maxLength)
Construct a
Key with the specified maximum length. |
Modifier and Type | Method and Description |
---|---|
Key |
append(boolean v)
Encodes and appends a boolean value to the key.
|
Key |
append(byte v)
Encodes and appends a byte value to the key.
|
Key |
append(char v)
Encodes and appends a char value to the key.
|
Key |
append(double v)
Encodes and appends a double value to the key.
|
Key |
append(float v)
Encodes and appends a float value to the key.
|
Key |
append(int v)
Encodes and appends an int value to the key.
|
Key |
append(long v)
Encodes and appends a long value to the key.
|
Key |
append(Object object)
Encodes and appends an
Object value to the key. |
Key |
append(Object object,
CoderContext context)
Encodes and appends an
Object value to the key. |
Key |
append(short v)
Encodes and appends a short value to the key.
|
Key |
appendByteArray(byte[] bytes,
int offset,
int size)
Append a key segment that encodes a subarray from a supplied array of
bytes.
|
Key |
appendKeySegment(Key key)
Append the next key segment of the supplied
Key to this
Key . |
Key |
clear()
Sets the current location and size of this
Key to zero,
effectively removing any previously appended key segments. |
int |
compareKeyFragment(Key key,
int fragmentStart,
int fragmentSize)
Compare a bounded subarray of the backing byte array for this
Key with another Key . |
int |
compareKeySegment(Key key)
Compare the next key segment of this key to the next key segment of the
supplied Key.
|
int |
compareTo(Object target)
Returns a positive integer if this
Key is larger than the
supplied Key , a negative integer if it is smaller, or zero
if they are equal. |
void |
copyTo(Key key)
Copies all state information from this to the supplied
Key . |
Key |
cut()
Remove one key segment value from the end of this
Key . |
Key |
cut(int count)
Remove up to
count key segment values from the end of this
Key . |
Object |
decode()
Decodes the next key segment as an
Object , advances the
index to the next key segment and returns the result. |
Object |
decode(Object target)
Decodes the next key segment as an
Object , advances the
index to the next key segment and returns the result. |
Object |
decode(Object target,
CoderContext context)
Decodes the next key segment as an
Object , advances the
index to the next key segment and returns the result. |
BigDecimal |
decodeBigDecimal()
Decodes the next key segment as a
java.math.BigDecimal ,
advances the index to the next key segment and returns the result. |
BigInteger |
decodeBigInteger()
Decodes the next key segment as a
java.math.BigInteger ,
advances the index to the next key segment and returns the result. |
boolean |
decodeBoolean()
Decodes the next key segment as a primitive boolean, advances the index
to the next key segment and returns the result.
|
byte |
decodeByte()
Decodes the next key segment as a primitive byte, advances the index to
the next key segment and returns the result.
|
byte[] |
decodeByteArray()
Decodes the next key segment as an array of bytes, advances the index to
the next key segment and returns the result.
|
char |
decodeChar()
Decodes the next key segment as a primitive char, advances the index to
the next key segment and returns the result.
|
Date |
decodeDate()
Decodes the next key segment as a
java.util.Date , advances
the index to the next key segment and returns the result. |
String |
decodeDisplayable(boolean quoted)
Decodes the next key segment as a displayable String, advances the index
to the next key segment and returns the result.
|
void |
decodeDisplayable(boolean quoted,
Appendable sb,
CoderContext context)
Decode the next key segment as a displayable String and advances the
index to the next key segment.
|
double |
decodeDouble()
Decodess the next key segment as a primitive double, advance the index to
the next key segment and returns the result.
|
float |
decodeFloat()
Decodes the next key segment as a primitive float, advances the index to
the next key segment and returns the result.
|
int |
decodeInt()
Decodes the next key segment as a primitive int, advances the index to
the next key segment and returns the result.
|
long |
decodeLong()
Decodes the next key segment as a primitive long, advances the index to
the next key segment and returns the result.
|
short |
decodeShort()
Decodes the next key segment as a primitive short, advances the index to
the next key segment and returns the result.
|
String |
decodeString()
Decodes the next key segment as a
String , advances the index
to the next key segment and returns the result. |
Appendable |
decodeString(Appendable sb)
Decodes the next key segment as a
String , appends the result
to the supplied Appendable and advance the index to the next
key segment. |
Class<?> |
decodeType()
Decodes the
Class of the next key segment. |
boolean |
equals(Object target)
|
int |
firstUniqueByteIndex(Key key)
Returns the index of the first encoded byte of this key that is different
than the corresponding byte of the supplied
Key . |
int |
firstUniqueSegmentDepth(Key key)
Returns the depth of the first segment of this key that is different than
the corresponding byte of the supplied
Key . |
int |
getDepth()
The number of key segments in this
Key . |
byte[] |
getEncodedBytes()
Returns the byte array that backs this
Key . |
int |
getEncodedSize()
Count of encoded bytes in the backing byte array.
|
long |
getGeneration()
An integer that is incremented every time the content of this Key
changes.
|
int |
getIndex()
Returns the index from which the next invocation of
decode() will
decode a key segment. |
int |
getMaximumSize()
Returns the maximum number of bytes permitting in the backing byte array
for this
Key . |
int |
hashCode()
Computes a hash code for key value currently represented by this
Key . |
Key |
indexTo(int depth)
Sets the index to a specified
depth . |
boolean |
isLeftEdge()
Determine if this is the special
Key value that is stored at
the left edge of a Tree . |
boolean |
isNull()
Determine if the current segment would return
null if
decode() were called. |
boolean |
isNull(boolean skipNull)
Determine if the current segment would return
null if
decode() were called. |
boolean |
isRightEdge()
Determine if this is the special
Key value that is stored at
the right edge of a Tree . |
Key |
reset()
Sets the index to 0.
|
Key |
setDepth(int depth)
Truncates this
Key to the specified depth . |
void |
setEncodedSize(int size)
Sets the count of valid encoded bytes in the backing array for this
Key . |
Key |
setIndex(int index)
The index is the next position in the backing byte array from which a
segment value will be decoded.
|
void |
setMaximumSize(int size)
Allocates a new backing byte array of the specified size.
|
Key |
to(boolean v)
Replaces the final key segment with the supplied boolean value.
|
Key |
to(byte v)
Replaces the final key segment with the supplied byte value.
|
Key |
to(char v)
Replaces the final key segment with the supplied char value.
|
Key |
to(double v)
Replaces the final key segment with the supplied double value.
|
Key |
to(float v)
Replaces the final key segment with the supplied float value.
|
Key |
to(int v)
Replaces the final key segment with the supplied int value.
|
Key |
to(long v)
Replaces the final key segment with the supplied long value.
|
Key |
to(Object v)
Replaces the final key segment with the supplied
Object
value. |
Key |
to(short v)
Replaces the final key segment with the supplied short value.
|
String |
toString()
Returns a displayable String representation of the content of this
Key |
public static final Key.Direction GT
public static final Key.Direction GTEQ
public static final Key.Direction EQ
public static final Key.Direction LTEQ
public static final Key.Direction LT
public static final Key LEFT_GUARD_KEY
Tree
public static final Key RIGHT_GUARD_KEY
Tree
public static final int MAX_KEY_LENGTH
public static final int MAX_KEY_LENGTH_UPPER_BOUND
public static final Key.EdgeValue BEFORE
Key
segment value that collates before any actual key in a
Tree
. A Key
may include an instance of this
value as its final segment, but the store
and
fetch
methods will not permit such a key as
inputs. Use BEFORE
to seed a traverse
loop, as shown in this code fragment:
key.to(BEFORE); while (exchange.next(key)) { ... do actions }
public static final Key.EdgeValue AFTER
Key
segment value that collates after any actual key in a
Tree
. A Key
may include an instance of this
value as its final segment, but the store
and
fetch
methods will not permit such a key as
inputs. Use AFTER
to seed a traverse
loop, as shown in this code fragment:
key.to(AFTER); while (exchange.previous(key)) { ... do actions }
public static final SimpleDateFormat SDF
java.text.SimpleDateFormat
used in formatting
Date
- valued keys in the decodeDisplayable(boolean)
methods.
This format also governs the conversion of dates for the
toString
method. This format provides millisecond resolution
so that the precise stored representation of a date used as a key can be
represented exactly, but readably, in the displayable version.public static final String PREFIX_BOOLEAN
public static final String PREFIX_BYTE
public static final String PREFIX_SHORT
public static final String PREFIX_CHAR
public static final String PREFIX_INT
public static final String PREFIX_LONG
public static final String PREFIX_FLOAT
public static final String PREFIX_DOUBLE
public static final String PREFIX_STRING
public static final String PREFIX_STRING0
public static final String PREFIX_BIG_INTEGER
public static final String PREFIX_BIG_INTEGER0
public static final String PREFIX_BIG_DECIMAL
public static final String PREFIX_BIG_DECIMAL0
public static final String PREFIX_DATE
public static final String PREFIX_DATE0
public static final String PREFIX_BYTE_ARRAY
public static final Key.Direction[] DIRECTIONS
public Key(Persistit persistit)
Key
with a maximum length of
2047.persistit
- public Key(Persistit persistit, int maxLength)
Key
with the specified maximum length. The
specified length must be positive and less than or equal to
2047.persistit
- the Persistit instancemaxLength
- The maximum lengthpublic Key(Key source)
Key
which duplicates the state of the supplied
Key
.source
- The Key
to copypublic void copyTo(Key key)
Key
.
To create a new Key
with state identical to this one, the
preferred mechanism for use outside of this package is this the copy
constructor:
Key copiedKey = new Key(originalKey);
key
- The Key
to copy.public int getMaximumSize()
Key
.public byte[] getEncodedBytes()
Key
. This method is
part of the Low-Level API.public int getEncodedSize()
public void setEncodedSize(int size)
Key
. This method is part of the Low-Level API.public int getDepth()
Key
. For example, the
code
key.clear().append("a").append("b").append("c");
results in a depth of 3.public Key setIndex(int index)
indexTo(int)
method to set the index to a valid location.index
- Key
, to permit method call chainingpublic int hashCode()
Key
. Changing the key will result in a different hashCode
value. A KeyState
holds an immutable copy of the state of a
Key
for use in maps. The hashCode
and
equals
methods of Key
and KeyState
are compatible so that an application can perform a map lookup using a
Key
when the map's key is actually a KeyState
.public boolean equals(Object target)
Key
to another Key
or
KeyState
. A KeyState
holds an immutable copy of the
state of a Key
for use in maps. The hashCode
and equals
methods of Key
and
KeyState
are compatible so that an application can perform a
map lookup using a Key
when the map's key is actually a
KeyState
.public int compareTo(Object target)
Key
is larger than the
supplied Key
, a negative integer if it is smaller, or zero
if they are equal.compareTo
in interface Comparable<Object>
public int compareKeyFragment(Key key, int fragmentStart, int fragmentSize)
Key
with another Key
. This method is intended
for use within the library and is generally not useful for applications.key
- The Key
to compare.fragmentStart
- Index of first byte to comparefragmentSize
- The number of bytes to compare.Key
's fragment is larger
than, a negative value if this Key
's fragment is
smaller than, or 0 if this Key
's fragment is equal
to the corresponding fragment of the supplied Key
.public int compareKeySegment(Key key)
setIndex(int)
method. Returns a
positive integer if the next segment of this Key
is larger
than the next segment of the supplied Key
, a negative
integer if it is smaller, or zero if the segments are equal.key
- public int firstUniqueByteIndex(Key key)
Key
. If all
bytes match, then returns the encoded length of the shorter key.key
- The code on which to count matching bytesKey
.public int firstUniqueSegmentDepth(Key key)
Key
. If all bytes
match, then returns the depth of the shorter key.key
- The code on which to count matching bytesKey
.public Key clear()
Key
to zero,
effectively removing any previously appended key segments.Key
, to permit method call chainingpublic void setMaximumSize(int size)
Allocates a new backing byte array of the specified size. This method is
for specialized use cases in which it may be convenient to serialize long
values into a Key
for purposes other than storing them in a
Tree
. However, regardless of the size of the backing byte
array, an encoded key value larger than the architectural maximum size of
2047 cannot be stored in a Tree
.
The specified size must be between 0 and
4194304. As a side-effect, this method also
calls the clear()
method.
size
- IllegalArgumentException
- if the specified size is not valid.public Key setDepth(int depth)
Key
to the specified depth
. If
depth
is 0 then this method is equivalent to clear()
.
If depth
is positive, then this Key
is
truncated so that it has no more than depth
key segments. If
depth
is negative, then up to -depth
segments
are removed from the end. For example,
key.clear().append("a").append("b").append("c").setDepth(-1);
results in a key with two segment, "a" and "b".depth
- The depth, as defined above.Key
, to permit method call chainingpublic Key reset()
decode()
operation will decode a
segment value.) This method is equivalent to indexTo(0)
.Key
, to permit method call chainingpublic Key indexTo(int depth)
depth
. (The index is
the location within the backing byte array from which the next
decode()
operation will decode a segment value.) If
depth
is 0 then this method is equivalent to reset()
.
If depth
is positive, then the index is set to point to the
depth
th key segment. If depth
is negative, then
the index is set to point to a key segment -depth
segments
from the end. For example,
key.clear().append("a").append("b").append("c");
return key.indexTo(-1).decode();
returns "c".depth
- The depth, as defined above.Key
, to permit method call chainingpublic int getIndex()
decode()
will
decode a key segment.public Key cut()
Key
. If
the key is empty this method does nothing.Key
, to permit method call chainingpublic Key cut(int count)
count
key segment values from the end of this
Key
. For example, the code fragment
key.clear();
key.append("a").append("b").append("c");
key.cut(2).append("d");
leaves a key with the just the segment values {"a","d"}.count
- The number of key segments to cut.Key
, to permit method call chainingpublic String toString()
Key
public Key append(boolean v)
v
- The boolean value to appendKey
, to permit method call chainingpublic Key append(byte v)
v
- The byte value to appendKey
, to permit method call chainingpublic Key append(short v)
v
- The short value to appendKey
, to permit method call chainingpublic Key append(char v)
v
- The char value to appendKey
, to permit method call chainingpublic Key append(int v)
v
- The int value to appendKey
, to permit method call chainingpublic Key append(long v)
v
- The long value to appendKey
, to permit method call chainingpublic Key append(float v)
v
- The float value to appendKey
, to permit method call chainingpublic Key append(double v)
v
- The double value to appendKey
, to permit method call chainingpublic Key append(Object object)
Object
value to the key. Only objects
of certain classes can be encoded in a Key
(see Object Encoding for details). This method
throws a ConversionException
for unsupported types.object
- The object to appendKey
, to permit method call chainingConversionException
- if the supplied object is not an implicitly supported type
and does not have a KeyCoder
.public Key append(Object object, CoderContext context)
Object
value to the key. Only objects
of certain classes can be encoded in a Key
(see Object Encoding for details). This method
throws a ConversionException
for unsupported types.object
- The object to appendcontext
- An application-specified value that may assist a
KeyCoder
. The context is passed to the
KeyCoder.appendKeySegment(com.persistit.Key, java.lang.Object, com.persistit.encoding.CoderContext)
method.Key
, to permit method call chainingConversionException
- if the supplied object is not an implicitly supported type
and does not have a KeyCoder
.public Key appendKeySegment(Key key)
Key
to this
Key
. The next key segment is determined by the current index
of the key and can be set using the setIndex(int)
method.key
- public Key to(boolean v)
cut()
and then append(boolean)
.v
- The boolean value to appendKey
, to permit method call chainingpublic Key to(byte v)
cut()
and then append(byte)
.v
- The byte value to appendKey
, to permit method call chainingpublic Key to(short v)
cut()
and then append(short)
.v
- The short value to appendKey
, to permit method call chainingpublic Key to(char v)
cut()
and then append(char)
.v
- The char value to appendKey
, to permit method call chainingpublic Key to(int v)
cut()
and then append(int)
.v
- The int value to appendKey
, to permit method call chainingpublic Key to(long v)
cut()
and then append(long)
.v
- The long value to appendKey
, to permit method call chainingpublic Key to(float v)
cut()
and then append(float)
.v
- The float value to appendKey
, to permit method call chainingpublic Key to(double v)
cut()
and then append(double)
.v
- The double value to appendKey
, to permit method call chainingpublic Key to(Object v)
Object
value. If the key is currently empty, this method simply appends the
value. This method is equivalent to invoking cut()
and then
append(Object)
. See append(Object)
for restrictions on
permissible Object values.v
- The Object value to appendKey
, to permit method call chainingpublic boolean decodeBoolean()
ConversionException
- if the next key segment value is not a boolean.public byte decodeByte()
ConversionException
- if the next key segment value is not a byte.public short decodeShort()
ConversionException
- if the next key segment value is not a short.public char decodeChar()
ConversionException
- if the next key segment value is not a char.public int decodeInt()
ConversionException
- if the next key segment value is not a int.public long decodeLong()
ConversionException
- if the next key segment value is not a long.public float decodeFloat()
ConversionException
- if the next key segment value is not a float.public double decodeDouble()
ConversionException
- if the next key segment value is not a double.public String decodeString()
String
, advances the index
to the next key segment and returns the result.ConversionException
- if the next key segment value is not a String.public Appendable decodeString(Appendable sb)
String
, appends the result
to the supplied Appendable
and advance the index to the next
key segment.sb
- The Appendable
Appendable
to permit operation
chaining.ConversionException
- if the next key segment value is not a String.public Date decodeDate()
java.util.Date
, advances
the index to the next key segment and returns the result.ConversionException
- if the next key segment value is not a Date.public BigInteger decodeBigInteger()
java.math.BigInteger
,
advances the index to the next key segment and returns the result.ConversionException
- if the next key segment value is not a BigInteger.public BigDecimal decodeBigDecimal()
java.math.BigDecimal
,
advances the index to the next key segment and returns the result.ConversionException
- if the next key segment value is not a BigDecimal.public byte[] decodeByteArray()
ConversionException
- if the next key segment value is not a boolean.public Object decode()
Object
, advances the
index to the next key segment and returns the result.null
if the encoded value is
null.ConversionException
- if the next key segment value is not a boolean.public Object decode(Object target)
Decodes the next key segment as an Object
, advances the
index to the next key segment and returns the result.
Value
is null then this method
returns null
. Otherwise this method returns either (a) a new
object instance, or (b) the target object. Specifically, if the supplied
target is non-null, and if the class of the object encoded in the
Value
is supported by a registered KeyRenderer
, then
the target object will be returned after the KeyRenderer
has
populated its state. Otherwise the target object will be ignored and this
method will return a newly created object instance. target
- A mutable object into which this method may attempt to decode
the valueObject
representing the key segment encoded in
the Key
, or null
if the encoded value
is null.public Object decode(Object target, CoderContext context)
Decodes the next key segment as an Object
, advances the
index to the next key segment and returns the result.
Value
is null then this method
returns null
. Otherwise this method returns either (a) a new
object instance, or (b) the target object. Specifically, if the supplied
target is non-null, and if the class of the object encoded in the
Value
is supported by a registered KeyRenderer
, then
the target object will be returned after the KeyRenderer
has
populated its state. Otherwise the target object will be ignored and this
method will return a newly created object instance. target
- A mutable object into which this method may attempt to decode
the valuecontext
- An application-specified value that may assist a
KeyCoder
. The context is passed to the
KeyCoder.decodeKeySegment(com.persistit.Key, java.lang.Class<?>, com.persistit.encoding.CoderContext)
method.Object
representing the key segment encoded in
the Key
, or null
if the encoded value
is null.public Class<?> decodeType()
Class
of the next key segment.Class
of the next key segmentConversionException
- if the encoded value is malformed.public String decodeDisplayable(boolean quoted)
ConversionException
- if the next key segment value is not a boolean.public void decodeDisplayable(boolean quoted, Appendable sb, CoderContext context)
quoted
is true, and
if the segment value is a String, then the String value is surrounded by
quote (") characters, and backslashes are inserted into the display
string to quote any embedded any backslash or quote characters. This
method is intended to generate a human-readable, canonical String
representation for any type of key segment value.quoted
- true
if the resulting string is to be quoted.sb
- The StringBuilder
to which the displayable string
is to be appended.ConversionException
- if the next key segment value is not a boolean.public long getGeneration()
Key
's value did not change.public boolean isLeftEdge()
Key
value that is stored at
the left edge of a Tree
. If so then there is no other
Key
before this one in the Tree
.true
if the content of this Key
represents the special left edge key of a Tree
public boolean isRightEdge()
Key
value that is stored at
the right edge of a Tree
. If so then there is no other
Key
after this one in the Tree
.true
if the content of this Key
represents the special right edge key of a Tree
public boolean isNull()
null
if
decode()
were called. This is not only a fast test to perform
but also allows for safe decoding of primitives, such as
decodeInt()
, without object creation.true
if the current segment is null,
false
otherwise.public boolean isNull(boolean skipNull)
null
if
decode()
were called. As a side effect, if skipNull
is true and the segment does encode a null
value, then the
index is advanced to the beginning of the next segment.skipNull
- whether to advance the index past a null segment valuetrue
if the current segment is null,
false
otherwise.public Key appendByteArray(byte[] bytes, int offset, int size)
bytes
- The byte array from which the key segment is createdoffset
- Offset of first byte of subarraysize
- Size of subarrayKey
, to permit method call chainingCopyright © 2025 Open Identity Platform Community. All rights reserved.