|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
K
- The type of keys in the database.V
- The type of values in the database.P
- The type of the position used to identify and find records in the
database.public interface DatabaseBackend<K,V,P>
The DatabaseBackend
is responsible for how keys and values are stored
and laid out in the underlying storage. A Database
uses
one DatabaseBackend
implementation.
The DatabaseBackend
uses one
Serializer
instance for serializing and
interpreting database keys and another
Serializer
instance for serializing and
interpreting database values.
The database client instantiates a backend object when creating the
Database
, but it should never call the backend's methods
directly. All calls to the database should go through the Database
object.
If database records are deleted, the backend may become fragmented. It can be
defragmented by calling compact()
. (Or, for database clients, rather
the Database.compact()
method.)
The DatabaseBackend
interface extends Iterable
. The iterator
that is returned when iterator()
is called iterates over the
database's Record
:s (its keys and values). Depending on the backend
implementation, the iterator may or may not return the records in a specific
order. If the database is modified after calling iterator()
, the
methods of the iterator returned will throw
ConcurrentModificationException
:s if they are invoked.
Implementation notes:
This interface is designed with the goal that backends should be easy to
implement and that backend methods can be implemented as efficient as
possible.
Database records (a key and its associated value) are identified by their
positions in the backing storage. Exactly what a position is is up to the
implementation. A position object is valid until the record it refers to
moves. If a client wants to be notified whenever a record moves, it registers
a RecordMoveListener
with the
addRecordMoveListener(RecordMoveListener)
method.
Backends never have to bother with locking and transactions. That is the job
of the Database
layer.
Database
,
Serializer
Method Summary | |
---|---|
void |
addRecordMoveListener(RecordMoveListener<? super K,? super V,? super P> l)
Add a listener that will receive notifications whenever a database record is moved to a new position. |
void |
clear()
Wipe out the entire database. |
void |
close()
Close this database backend and release all resources associated with it (close files and release locks, for instance). |
boolean |
compact()
Compact the backing database file if it has become fragmented. |
boolean |
delete(K key)
Delete the record with the supplied key, if it exists. |
P |
find(Comparable<K> key,
SearchMode mode)
Find the position of the record with the supplied key in the database that matches the search mode. |
P |
find(K key)
Find the position of the record with the supplied key in the database backend. |
P |
find(K key,
SearchMode mode,
Comparator<? super K> cmp)
Find the position of the record with the supplied key in the database that matches the search mode. |
void |
forEachKey(ForEachKeyCallback<K,P> callback)
For each key in the database, call the callback object. |
int |
getContentsVersion()
Get a version number for the contents of the database backend. |
P |
getFirstPosition()
Get the position of the "first" record in the backend. |
Set<K> |
getKeys()
Return an immutable Set containing all keys in the database. |
P |
getLastPosition()
Get the position of the "last" record in the backend. |
P |
getNextPosition(P pos)
Get the position of the "next" record in the backend, relative to the record at the supplied position. |
P |
getPreviousPosition(P pos)
Get the position of the "previous" record in the backend, relative to the record at the supplied position. |
Set<Record<K,V>> |
getRecords()
Return an immutable Set containing all database records (keys and
values). |
V |
getValueFor(K key)
Get the value for the record with the supplied key. |
Collection<V> |
getValues()
Return an immutable Collection containing all values in the
database. |
P |
insert(K key,
V value)
Insert a new record in the database. |
P |
insertCheckKeyUnique(K key,
V value)
Insert a new record in the database after verifying that the key is unique within the database. |
boolean |
insertOrUpdate(K key,
V value)
If a record with the supplied key exists, update its value. |
Iterator<K> |
keyIterator()
Get an iterator for all keys in the database. |
K |
readKeyAt(P pos)
Read the key at the supplied position. |
Record<K,V> |
readRecordAt(P pos)
Read the record (key and value) at the specified position. |
V |
readValueAt(P pos)
Read the value at the specified position. |
V |
remove(K key)
Delete the record with the supplied key and return its value. |
void |
removeAt(P pos,
K key)
Delete the record at the supplied position. |
void |
removeRecordMoveListener(RecordMoveListener<? super K,? super V,? super P> l)
Remove a record move listener. |
void |
replaceContentsWith(RandomAccess ra,
long dataSize)
Replace the contents of the database with content read from the supplied RandomAccess . |
Pair<P> |
update(K key,
V value)
Update an existing record with a new value. |
P |
updateAt(P pos,
K key,
V value)
Update the record at the supplied position with the new value. |
Iterator<V> |
valueIterator()
Get an iterator for all the values in the database. |
long |
writeContentsTo(RandomAccess ra)
Write the contents of the entire database to the current position in the supplied RandomAccess . |
Methods inherited from interface java.lang.Iterable |
---|
iterator |
Method Detail |
---|
Set<K> getKeys() throws WrappedIOException, IllegalStateException
Set
containing all keys in the database.
Set
containing all keys in the database. If
the database is empty, this method returns an empty Set
.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.Collection<V> getValues() throws WrappedIOException, IllegalStateException
Collection
containing all values in the
database.
Collection
containing all values in the
database. If the database is empty, this method returns an empty Collection
.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.Set<Record<K,V>> getRecords() throws WrappedIOException, IllegalStateException
Set
containing all database records (keys and
values).
Set
containing all database records. If the
database is empty, this method returns an empty Set
.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.P insert(K key, V value) throws WrappedIOException, IllegalStateException, ReadOnlyException
key
- The key. It is not verified that this key is unique. Inserting
duplicate keys will result in unspecified behavior from the backend.value
- The value.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.
ReadOnlyException
- If the database backend is read only.P insertCheckKeyUnique(K key, V value) throws WrappedIOException, IllegalStateException, ReadOnlyException, KeyExistsException
key
- The key.value
- The value.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.
ReadOnlyException
- If the database backend is read only.
KeyExistsException
- If the key already exists in the database.boolean insertOrUpdate(K key, V value) throws WrappedIOException, IllegalStateException, ReadOnlyException
key
- The key.value
- The value.
true
if an existing record was updated, false
if
a new record was inserted.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.
ReadOnlyException
- If the database backend is read only.P find(K key) throws WrappedIOException, IllegalStateException
key
- The key to find.
null
if not found.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.find(Comparable, SearchMode)
,
find(Object, SearchMode, Comparator)
P find(Comparable<K> key, SearchMode mode) throws WrappedIOException, IllegalStateException
Comparable.compareTo(Object)
method of the supplied key.
key
- The key to find.mode
- The search mode. The backend implementation must support the
SearchMode.EXACT_MATCH
mode (which makes this method behave
exactly like find(Object)
). The backend may also support
SearchMode.CLOSEST_ABOVE
, SearchMode.CLOSEST_BELOW
and
SearchMode.CLOSEST_MATCH
. If not, this method should throw an
UnsupportedOperationException
when called with any of those
search modes. The backend implementation may also invent its own search
modes.
The closest match is defined as the match that gives the lowest positive
(SearchMode.CLOSEST_ABOVE
), negative (
SearchMode.CLOSEST_BELOW
) or absolute (
SearchMode.CLOSEST_MATCH
) value from the supplied key's
Comparable.compareTo(Object)
method when comparing the keys in
the database with the key to search for.
null
if no record matching the search criteria is found.
UnsupportedOperationException
- If this method is called with a
SearchMode
that is not supported by the backend implementation.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.find(Object)
,
find(Object, SearchMode, Comparator)
P find(K key, SearchMode mode, Comparator<? super K> cmp) throws UnsupportedOperationException, WrappedIOException, IllegalStateException
Comparator
is used to
compare the distances between the keys in the database and the key to
search for.
key
- The key to find.mode
- The search mode. The backend implementation must support the
SearchMode.EXACT_MATCH
mode (which makes this method behave
exactly like find(Object)
). The backend may also support
SearchMode.CLOSEST_ABOVE
, SearchMode.CLOSEST_BELOW
and
SearchMode.CLOSEST_MATCH
. If not, this method should throw an
UnsupportedOperationException
when called with any of those
search modes. The backend implementation may also invent its own search
modes.
The closest match is defined as the match that gives the lowest positive
(SearchMode.CLOSEST_ABOVE
), negative (
SearchMode.CLOSEST_BELOW
) or absolute (
SearchMode.CLOSEST_MATCH
) value from the comparator when
comparing the keys in the database with the key to search for.
cmp
- The Comparator
used to compare keys.
null
if no record matching the search criteria is found.
UnsupportedOperationException
- If this method is called with a
SearchMode
that is not supported by the backend implementation.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.find(Object)
,
find(Comparable, SearchMode)
V getValueFor(K key) throws WrappedIOException, IllegalStateException
key
- The record's key.
null
if no record in the database
has the supplied key.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.P updateAt(P pos, K key, V value) throws WrappedIOException, IllegalStateException, ReadOnlyException
It is up to the implementation to decide exactly how this is done. It is not required that the record should be located at the same position in the backend after the update. One strategy for implementing this method is to delete the old record and insert a new record with the updated values.
pos
- The position of the record to update.key
- The record's key. The key is not modified by the update.value
- The new value.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.
ReadOnlyException
- If the database backend is read only.Pair<P> update(K key, V value) throws WrappedIOException, IllegalStateException, ReadOnlyException, KeyNotFoundException
It is up to the implementation to decide exactly how this is done. It is not required that the record should be located at the same position in the backend after the update. One strategy for implementing this method is to delete the old record and insert a new record with the updated values.
key
- The record's key.value
- The record's new value.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.
ReadOnlyException
- If the database backend is read only.
KeyNotFoundException
- If no record with the supplied key was
found.K readKeyAt(P pos) throws WrappedIOException, IllegalStateException
pos
- The position of the record containing the key. This must be a
valid position in the backend. It it is not, the behavior of this method
is unspecified.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.readValueAt(Object)
,
readRecordAt(Object)
V readValueAt(P pos) throws WrappedIOException, IllegalStateException
pos
- The position of the record containing the value. This must be
a valid position in the backend. If it is not, the behavior of this
method is unspecified.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.readKeyAt(Object)
,
readRecordAt(Object)
Record<K,V> readRecordAt(P pos) throws WrappedIOException, IllegalStateException
pos
- The position of the record. This must be a valid position in
the backend. If it is not, the behavior of this method is unspecified.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.readKeyAt(Object)
,
readValueAt(Object)
void clear() throws WrappedIOException, IllegalStateException, ReadOnlyException
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.
ReadOnlyException
- If the database backend is read only.void removeAt(P pos, K key) throws WrappedIOException, IllegalStateException, ReadOnlyException
pos
- The position of the record to delete.key
- The key for the record to remove.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.
ReadOnlyException
- If the database backend is read only.V remove(K key) throws WrappedIOException, IllegalStateException, ReadOnlyException
key
- The record's key.
null
if no record in the database
has the supplied key.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.
ReadOnlyException
- If the database backend is read only.boolean delete(K key) throws WrappedIOException, IllegalStateException, ReadOnlyException
key
- The record's key.
true
if a record was deleted.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.
ReadOnlyException
- If the database backend is read only.void forEachKey(ForEachKeyCallback<K,P> callback) throws IllegalStateException
This can for instance be used for building indices for the database.
callback
- The callback object to call for each key.
IllegalStateException
- If the database backend has been closed.Iterator<K> keyIterator()
If the database is modified after calling this method, the methods of the
Iterator
returned will throw
ConcurrentModificationException
Iterator
over the database's keys.Iterator<V> valueIterator()
If the database is modified after calling this method, the methods of the
Iterator
returned will throw
ConcurrentModificationException
Iterator
over the database's values.void addRecordMoveListener(RecordMoveListener<? super K,? super V,? super P> l)
l
- The listener.removeRecordMoveListener(RecordMoveListener)
void removeRecordMoveListener(RecordMoveListener<? super K,? super V,? super P> l)
l
- The listener to remove.addRecordMoveListener(RecordMoveListener)
long writeContentsTo(RandomAccess ra) throws WrappedIOException, IllegalStateException
RandomAccess
.
After writing, the current position of the RandomAccess
should be
at the end of the written data.
ra
- The RandomAccess
to write to. It is not closed after
writing.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.void replaceContentsWith(RandomAccess ra, long dataSize) throws WrappedIOException, IllegalStateException, ReadOnlyException
RandomAccess
. The database contents start at the RandomAccess
' current position.
ra
- The RandomAccess
to read data from. It should not be
closed after reading.dataSize
- The total size of the database data in bytes.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.
ReadOnlyException
- If the database backend is read only.int getContentsVersion() throws IllegalStateException
The version number is used by database cursors to detect changes in the
backend (upon which they throw
ConcurrentModificationException
:s).
The version number does not have to be persisted. It does not have to be consistent between different backend objects created on the same data.
IllegalStateException
- If the database backend has been closed.P getFirstPosition() throws WrappedIOException, IllegalStateException
null
if the backend is empty.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.getLastPosition()
,
getNextPosition(Object)
,
getPreviousPosition(Object)
P getLastPosition() throws WrappedIOException, IllegalStateException, UnsupportedOperationException
Some backend implementations do not support this method. They let this
method throw an UnsupportedOperationException
.
null
if the backend is empty.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.
UnsupportedOperationException
- If this method is not supported by
the backend implementation.getFirstPosition()
,
getNextPosition(Object)
,
getPreviousPosition(Object)
P getNextPosition(P pos) throws WrappedIOException, IllegalStateException
pos
- The position to search from. This must be the position of a
record in the backend. If it is not, the behavior of this method is
unspecified.
null
if the supplied position references the last record in the backend
(the position returned from getLastPosition()
).
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.getFirstPosition()
,
getLastPosition()
,
getPreviousPosition(Object)
P getPreviousPosition(P pos) throws WrappedIOException, IllegalStateException, UnsupportedOperationException
Some backend implementations do not support this method. They let this
method throw an UnsupportedOperationException
.
pos
- The position to search from. This must be the position of a
record in the backend. If it is not, the behavior of this method is
unspecified.
null
if the supplied position references the first record in the
backend (the position returned from getFirstPosition()
).
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.
UnsupportedOperationException
- If this method is not supported by
the backend implementation.getFirstPosition()
,
getLastPosition()
,
getNextPosition(Object)
boolean compact() throws WrappedIOException, IllegalStateException, ReadOnlyException
true
if the backend was modified, false
if not.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the database backend has been closed.
ReadOnlyException
- If the database backend is read only.void close()
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |