Interface Persistence
Objs. Batch operations
are provided where applicable.
Objs are usually only written but never updated. This enables efficient caching of
persisted data. In certain, exceptional use cases, which should always almost be avoided, CAS
primitives allow conditional creates/updates/deletes. ObjType implementations can provide
custom positive and negative caching rules.
Databases often have hard limits or at least more-or-less strong recommendations on the size
of serialized Objs. The "main" implementation of this interface in
:polaris-persistence-nosql-impl takes care of transparently splitting and re-assembling Objs across multiple database rows. The latter is not supported for conditionally updated Objs.
This interface is a Polaris-internal low-level API interface for NoSQL. Instances of this interface are scoped to a specific realm.
The behavior when fetching a non-existing reference is to throw, which is different from
fetching non-existing Objs, because references are supposed to exist and a non-existence
is usually a sign of a missing initialization step, whereas a missing Obj is often
expected.
Database-specific implementations do implement the Backend interface, not this one.
-
Method Summary
Modifier and TypeMethodDescriptionbucketizedBulkFetches(Stream<ObjRef> objRefs, Class<O> clazz) Convenience function to performfetchMany(Class, ObjRef...)on an arbitrary number of objects to fetch.<V> Index<V> buildReadIndex(IndexContainer<V> indexContainer, IndexValueSerializer<V> indexValueSerializer) <V> UpdatableIndex<V> buildWriteIndex(IndexContainer<V> indexContainer, IndexValueSerializer<V> indexValueSerializer) commits()<T extends Obj>
booleanconditionalDelete(T expected, Class<T> clazz) Delete an object with strong consistent guarantees.<T extends Obj>
TconditionalInsert(T obj, Class<T> clazz) Persistobjwith strong consistent guarantees.<T extends Obj>
TconditionalUpdate(T expected, T update, Class<T> clazz) Update an object with strong consistent guarantees.<REF_OBJ extends BaseCommitObj,RESULT>
Committer<REF_OBJ, RESULT> createCommitter(String refName, Class<REF_OBJ> referencedObjType, Class<RESULT> resultType) createReference(String name, Optional<ObjRef> pointer) Creates the reference with the given name and pointer value.default voidcreateReferenceSilent(String name) Convenience function to create a reference with an empty pointer, if it does not already exist.voidcreateReferencesSilent(Set<String> referenceNames) Ensures that multiple references exist, leveraging bulk operations, if possible.default InstantConvenience formonotonicClock().MonotonicClock.currentInstant().default longConvenience formonotonicClock().MonotonicClock.currentTimeMicros().default longConvenience formonotonicClock().MonotonicClock.currentTimeMillis().voidUnconditionally delete the object with the given id.voiddeleteMany(ObjRef... ids) Unconditionally delete the objects with the given ids.<T extends Obj>
TFetch the objects for the given object Ids.<T extends Obj>
T[]Fetch multiple objects for the given object Ids.default ReferencefetchOrCreateReference(String name, Supplier<Optional<ObjRef>> pointerForCreate) Convenience function to return an existing reference or to create the reference with a supplied pointer, if it does not already exist.fetchReference(String name) Fetch the reference with the given name, leveraging the reference cache.default ReferenceFetches the reference with the given name, but will always fetch the most recent state from the backend database.fetchReferenceHead(String name, Class<T> clazz) Convenience function to return theObjas pointed to from the reference with the given name.longgenerateObjId(ObjType type) <T extends Obj>
TgetImmediate(ObjRef id, Class<T> clazz) If the persistence implementation is caching, this function returns the object with the ID from the cache, but does not consult the backend.org.apache.polaris.ids.api.IdGeneratorintDefines the maximum allowed serialized object size.org.apache.polaris.ids.api.MonotonicClockdefault Durationparams()realmId()updateReferencePointer(Reference reference, ObjRef newPointer) Updates the pointer tonewPointer, if the reference exists and the current persisted pointer is the same as inreference.<T extends Obj>
TPersistobjwith eventually consistent guarantees.<T extends Obj>
T[]Persist multipleobjswith eventually consistent guarantees.
-
Method Details
-
createReference
@Nonnull Reference createReference(@Nonnull String name, @Nonnull Optional<ObjRef> pointer) throws ReferenceAlreadyExistsException Creates the reference with the given name and pointer value.Reference creation is always a strongly consistent operation.
- Throws:
ReferenceAlreadyExistsException- if a reference with the same name already exists
-
createReferenceSilent
Convenience function to create a reference with an empty pointer, if it does not already exist.- See Also:
-
createReferencesSilent
Ensures that multiple references exist, leveraging bulk operations, if possible. References are created with empty pointers.This whole operation is not guaranteed to be atomic, the creation of each reference is atomic.
- See Also:
-
fetchOrCreateReference
@Nonnull default Reference fetchOrCreateReference(@Nonnull String name, @Nonnull Supplier<Optional<ObjRef>> pointerForCreate) Convenience function to return an existing reference or to create the reference with a supplied pointer, if it does not already exist. -
updateReferencePointer
@Nonnull Optional<Reference> updateReferencePointer(@Nonnull Reference reference, @Nonnull ObjRef newPointer) throws ReferenceNotFoundException Updates the pointer tonewPointer, if the reference exists and the current persisted pointer is the same as inreference.Reference update is always a strongly consistent operation.
- Parameters:
reference- the existing reference including the expected pointernewPointer- the pointer to update the reference to. If the reference has a current pointer value, both the current and the new pointer must use the sameObjType.- Returns:
- If the reference was successfully updated, an updated
Referenceinstances will be returned. - Throws:
ReferenceNotFoundException- if the reference does not exist
-
fetchReference
Fetch the reference with the given name, leveraging the reference cache.- Throws:
ReferenceNotFoundException- if the reference does not exist- See Also:
-
fetchReferenceForUpdate
@Nonnull default Reference fetchReferenceForUpdate(@Nonnull String name) throws ReferenceNotFoundException Fetches the reference with the given name, but will always fetch the most recent state from the backend database.- Throws:
ReferenceNotFoundException- See Also:
-
fetchReferenceHead
default <T extends Obj> Optional<T> fetchReferenceHead(@Nonnull String name, @Nonnull Class<T> clazz) throws ReferenceNotFoundException Convenience function to return theObjas pointed to from the reference with the given name.- Throws:
ReferenceNotFoundException- See Also:
-
fetch
Fetch the objects for the given object Ids.Supports assembling object splits across multiple rows by
write(Obj, Class)orwriteMany(Class, Obj[]).- Type Parameters:
T- returned type can also be justObj- Parameters:
id- ID of the object to loadclazz- expectedObjsubtype, passingObj.classis fine- Returns:
- loaded object or
nullif it does not exist - See Also:
-
fetchMany
Fetch multiple objects for the given object Ids.Supports assembling object splits across multiple rows by
write(Obj, Class)orwriteMany(Class, Obj[]).- Type Parameters:
T- returned type can also be justObj- Parameters:
clazz- expectedObjsubtype, passingObj.classis fineids- ID of the object to load, callers must ensure that the IDs are not duplicated within the array- Returns:
- array of the same length as
idscontaining the loaded objects, withnullelements for objects that do not exist - See Also:
-
write
Persistobjwith eventually consistent guarantees.Supports splitting the serialized representation across multiple rows in the backend database, if the serialized representation does not fit entirely in a single row, limited by
maxSerializedValueSize().This function (and
writeMany(Class, Obj[])) are not meant to actually update existing objects with different information, especially not when the size of the serialized object changes the number of splits in the backend database. Note that there is no protection against this scenario.- Returns:
objwith theObj.createdAtMicros()andObj.numParts()fields updated- See Also:
-
writeMany
Persist multipleobjswith eventually consistent guarantees.See
write(Obj, Class)for more information.Supports splitting the serialized representation across multiple rows in the backend database, if the serialized representation does not fit entirely in a single row, limited by
maxSerializedValueSize().This function and
write(Obj, Class)are not meant to actually update existing objects with different information, especially not when the size of the serialized object changes the number of splits in the backend database. Note that there is no protection against this scenario.- Returns:
objswith theObj.createdAtMicros()andObj.numParts()fields updated, callers must ensure that the IDs are not duplicated within the array.nullelements in the returned array will appear fornullelements in theobjsarray.- See Also:
-
delete
Unconditionally delete the object with the given id.Note that it is generally not advised to actively (or prematurely) delete objects. In general, it is better to just leave the object and let the maintenance service take care of purging it.
If the object has been split across multiple database rows, only the number of parts mentioned in
ObjRef.numParts()will be deleted. However, the maintenance service will take care of purging possibly left-over parts.- See Also:
-
deleteMany
Unconditionally delete the objects with the given ids.Note that it is generally not advised to actively (or prematurely) delete objects. In general, it is better to just leave the object and let the maintenance service take care of purging it.
If the object has been split across multiple database rows, only the number of parts mentioned in
ObjRef.numParts()will be deleted. However, the maintenance service will take care of purging possibly left-over parts.- Parameters:
ids- IDs of objects to delete, callers must ensure that the IDs are not duplicated within the array- See Also:
-
conditionalInsert
Persistobjwith strong consistent guarantees.Unlike eventually consistent writes, conditional write operations do not support splitting the serialized representation across multiple rows in the backend database.
The serialized representation must fit entirely in a single row, limited by
maxSerializedValueSize().- Returns:
objwith theObj.createdAtMicros()field updated if and only if no other object with the same object id existed before, otherwisenull
-
conditionalUpdate
@Nullable <T extends Obj> T conditionalUpdate(@Nonnull T expected, @Nonnull T update, @Nonnull Class<T> clazz) Update an object with strong consistent guarantees.Unlike eventually consistent writes, conditional write operations do not support splitting the serialized representation across multiple rows in the backend database.
The serialized representation must fit entirely in a single row, limited by
maxSerializedValueSize().- Parameters:
expected- the object expected to have the sameObj.versionToken()as this oneupdate- the object to be updated to, must have the same id, type but a different version token- Returns:
- updated state in the database, if successful, otherwise
null
-
conditionalDelete
Delete an object with strong consistent guarantees.- Parameters:
expected- the object expected to have the sameObj.versionToken()as this one- Returns:
trueif the object existed with the expected version token and was deleted in the database, if successful, otherwisefalse
-
params
PersistenceParams params() -
maxSerializedValueSize
int maxSerializedValueSize()Defines the maximum allowed serialized object size. Serialized representation larger than this value will be split into multiple database rows. -
generateId
long generateId() -
generateObjId
-
getImmediate
If the persistence implementation is caching, this function returns the object with the ID from the cache, but does not consult the backend.Non-caching implementations default to
fetch(ObjRef, Class). -
commits
Commits commits() -
createCommitter
<REF_OBJ extends BaseCommitObj,RESULT> Committer<REF_OBJ,RESULT> createCommitter(@Nonnull String refName, @Nonnull Class<REF_OBJ> referencedObjType, @Nonnull Class<RESULT> resultType) -
buildReadIndex
<V> Index<V> buildReadIndex(@Nullable IndexContainer<V> indexContainer, @Nonnull IndexValueSerializer<V> indexValueSerializer) -
buildWriteIndex
<V> UpdatableIndex<V> buildWriteIndex(@Nullable IndexContainer<V> indexContainer, @Nonnull IndexValueSerializer<V> indexValueSerializer) -
objAge
-
realmId
String realmId() -
monotonicClock
org.apache.polaris.ids.api.MonotonicClock monotonicClock() -
idGenerator
org.apache.polaris.ids.api.IdGenerator idGenerator() -
currentTimeMicros
default long currentTimeMicros()Convenience formonotonicClock().MonotonicClock.currentTimeMicros(). -
currentTimeMillis
default long currentTimeMillis()Convenience formonotonicClock().MonotonicClock.currentTimeMillis(). -
currentInstant
Convenience formonotonicClock().MonotonicClock.currentInstant(). -
bucketizedBulkFetches
Convenience function to performfetchMany(Class, ObjRef...)on an arbitrary number of objects to fetch.
-