java.lang.Object
com.renomad.minum.database.AbstractDb<T>
com.renomad.minum.database.Db<T>
- Type Parameters:
T- the type of data we'll be persisting (must extend fromDbData
a memory-based disk-persisted database class.
-
Field Summary
Fields inherited from class com.renomad.minum.database.AbstractDb
context, data, dbDirectory, emptyInstance, fileUtils, index, logger, partitioningMap, registeredIndexes -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidDelete datagetIndexedData(String indexName, String key) Given the name of a registered index (seeregisterIndex(String, Function)), use the key to find the collection of data that matches it.voidloadData()This is what loads the data from disk the first time someone needs it.booleanregisterIndex(String indexName, Function<T, String> keyObtainingFunction) Register an index in the database for higher performance data access.voidstop()This function will stop the minum.database persistence cleanly.voidstop(int count, int sleepTime) Similar tostop()but gives more control over how long we'll wait before crashing it closed.values()This method provides read capability for the values of a database.Write data to the database.Methods inherited from class com.renomad.minum.database.AbstractDb
addToIndexes, deleteFromMemory, findExactlyOne, findExactlyOne, getSetOfIndexes, processDataIndex, writeToMemory
-
Constructor Details
-
Db
Constructs an in-memory disk-persisted database. Loading of data from disk happens at the first invocation of any command changing or requesting data, such aswrite(DbData),delete(DbData), orvalues(). See the private method loadData() for details.- Parameters:
dbDirectory- this uniquely names your database, and also sets the directory name for this data. The expected use case is to name this after the data in question. For example, "users", or "accounts".context- used to provide important state data to several componentsinstance- an instance of theDbDataobject relevant for use in this database. Note that each database (that is, each instance of this class), focuses on just one data, which must be an implementation ofDbData.
-
-
Method Details
-
write
Write data to the database. Use an index of 0 to store new data, and a positive non-zero value to update data.Example of adding new data to the database:
final var newSalt = StringUtils.generateSecureRandomString(10); final var hashedPassword = CryptoUtils.createPasswordHash(newPassword, newSalt); final var newUser = new User(0L, newUsername, hashedPassword, newSalt); userDb.write(newUser);Example of updating data:
// write the updated salted password to the database final var updatedUser = new User( user().getIndex(), user().getUsername(), hashedPassword, newSalt); userDb.write(updatedUser);- Specified by:
writein classAbstractDb<T extends DbData<?>>- Parameters:
newData- the data we are writing- Returns:
- the data with its new index assigned.
-
delete
Delete dataExample:
userDb.delete(user);- Specified by:
deletein classAbstractDb<T extends DbData<?>>- Parameters:
dataToDelete- the data we are serializing and writing
-
values
Description copied from class:AbstractDbThis method provides read capability for the values of a database.
The returned collection is a read-only view over the data, throughCollections.unmodifiableCollection(Collection)Example:
boolean doesUserAlreadyExist(String username) { return userDb.values().stream().anyMatch(x -> x.getUsername().equals(username)); }- Specified by:
valuesin classAbstractDb<T extends DbData<?>>
-
loadData
public void loadData()This is what loads the data from disk the first time someone needs it. Because it is locked, only one thread can enter at a time. The first one in will load the data, and the second will encounter a branch which skips loading.- Specified by:
loadDatain classAbstractDb<T extends DbData<?>>
-
registerIndex
Register an index in the database for higher performance data access.This command should be run immediately after database declaration, or more specifically, before any data is loaded from disk. Otherwise, it would be possible to skip indexing that data.
Example:final var myDatabase = context.getDb("photos", Photograph.EMPTY); myDatabase.registerIndex("url", photo -> photo.getUrl());- Overrides:
registerIndexin classAbstractDb<T extends DbData<?>>- Parameters:
indexName- a string used to distinguish this index. This string will be used again when requesting data in a method likegetIndexedData(java.lang.String, java.lang.String)orAbstractDb.findExactlyOne(java.lang.String, java.lang.String)keyObtainingFunction- a function which obtains data from the data in this database, used to partition the data into groups (potentially up to a 1-to-1 correspondence between id and object)- Returns:
- true if the registration succeeded
- Throws:
DbException- if the parameters are not entered properly, if the index has already been registered, or if the data has already been loaded. It is necessary that this is run immediately after declaring the database. To explain further: the data is not actually loaded until the first time it is needed, such as running a write or delete, or if theloadDataFromDisk()method is run. Creating an index map for the data that is read from disk only occurs once, at data load time. Thus, it is crucial that the registerIndex command is run before any data is loaded.
-
getIndexedData
Given the name of a registered index (seeregisterIndex(String, Function)), use the key to find the collection of data that matches it.- Overrides:
getIndexedDatain classAbstractDb<T extends DbData<?>>- Parameters:
indexName- the name of an indexkey- a string value that matches a partition calculated from the partition function provided toregisterIndex(String, Function)- Returns:
- a collection of data, an empty collection if nothing found
-
stop
public void stop()This function will stop the minum.database persistence cleanly.In order to do this, we need to wait for our threads to finish their work. In particular, we have offloaded our file writes to [actionQueue], which has an internal thread for serializing all actions on our minum.database
- Specified by:
stopin classAbstractDb<T extends DbData<?>>
-
stop
public void stop(int count, int sleepTime) Similar tostop()but gives more control over how long we'll wait before crashing it closed. SeeActionQueue.stop(int, int)- Specified by:
stopin classAbstractDb<T extends DbData<?>>- Parameters:
count- number of loops before we are done waiting for a clean close and instead crash the instance closed.sleepTime- how long to wait, in milliseconds, for each iteration of the waiting loop.
-