Skip to content

Module hb_store.erl

A simple abstraction layer for AO key value store operations.

Description

This interface allows us to swap out the underlying store implementation(s) as desired, without changing the API that hb_cache employs. Additionally, it enables node operators to customize their configuration to maximize performance, data availability, and other factors.

Stores can be represented in a node's configuration as either a single message, or a (structured@1.0) list of store messages. If a list of stores is provided, the node will cycle through each until a viable store is found to execute the given function.

A valid store must implement a subset of the following functions: `start/1: Initialize the store. stop/1: Stop any processes (etc.) that manage the store. reset/1: Restore the store to its original, empty state. scope/0: A tag describing thescope' of a stores search: in_memory, local, remote, arweave, etc. Used in order to allow node operators to prioritize their stores for search. make_group/2: Create a new group of keys in the store with the given ID. make_link/3: Create a link (implying one key should redirect to another) from existing to new (in that order). type/2: Return whether the value found at the given key is a composite (group) type, or a simple direct binary. read/2: Read the data at the given location, returning a binary if it is a simple value, or a message if it is a complex term. write/3: Write the given key with the associated value (in that order) to the store. list/2: For composite type keys, return a list of its child keys. path/2: Optionally transform a list of path parts into the store's canonical form. ''' Each function takes a store message first, containing an arbitrary set of its necessary configuration keys, as well as the store-module key which refers to the Erlang module that implements the store.

All functions must return ok or {ok, Result}, as appropriate. Other results will lead to the store manager (this module) iterating to the next store message given by the user. If none of the given store messages are able to execute a requested service, the store manager will return not_found.

Function Index

add_path/2Add two path components together.
add_path/3
behavior_info/1
benchmark_key_read_write/1*Benchmark a store.
benchmark_key_read_write/3*
benchmark_message_read_write/1*
benchmark_message_read_write/3*
benchmark_suite_test_/0*
call_all/3*Call a function on all modules in the store.
call_function/3*Call a function on the first store module that succeeds.
do_call_function/3*
do_find/1*
ensure_instance_alive/2*Handle a found instance message.
filter/2Takes a store object and a filter function or match spec, returning a new store object with only the modules that match the filter.
find/1Find or spawn a store instance by its store opts.
generate_test_suite/1
generate_test_suite/2
get_store_scope/1*Ask a store for its own scope.
hierarchical_path_resolution_test/1*Ensure that we can resolve links through a directory.
join/1Join a list of path components together.
list/2List the keys in a group in the store.
make_group/2Make a group in the store.
make_link/3Make a link from one path to another in the store.
path/1Create a path from a list of path components.
path/2
read/2Read a key from the store.
reset/1Delete all of the keys in a store.
resolve/2Follow links through the store to resolve a path to its ultimate target.
resursive_path_resolution_test/1*Ensure that we can resolve links recursively.
rocks_stores/0*
scope/2Limit the store scope to only a specific (set of) option(s).
simple_path_resolution_test/1*Test path resolution dynamics.
sort/2Order a store by a preference of its scopes.
spawn_instance/1*Create a new instance of a store and return its term.
start/1Ensure that a store, or list of stores, have all been started.
stop/1
store_suite_test_/0*
test_stores/0Return a list of stores for testing.
type/2Get the type of element of a given path in the store.
write/3Write a key with a value to the store.

Function Details

add_path/2

add_path(Path1, Path2) -> any()

Add two path components together. If no store implements the add_path function, we concatenate the paths.

add_path/3

add_path(Store, Path1, Path2) -> any()

behavior_info/1

behavior_info(X1) -> any()

benchmark_key_read_write/1 *

benchmark_key_read_write(Store) -> any()

Benchmark a store. By default, we write 10,000 keys and read 10,000 keys. This can be altered by setting the STORE_BENCH_WRITE_OPS and STORE_BENCH_READ_OPS macros.

benchmark_key_read_write/3 *

benchmark_key_read_write(Store, WriteOps, ReadOps) -> any()

benchmark_message_read_write/1 *

benchmark_message_read_write(Store) -> any()

benchmark_message_read_write/3 *

benchmark_message_read_write(Store, WriteOps, ReadOps) -> any()

benchmark_suite_test_/0 *

benchmark_suite_test_() -> any()

call_all/3 *

call_all(X, Function, Args) -> any()

Call a function on all modules in the store.

call_function/3 *

call_function(X, Function, Args) -> any()

Call a function on the first store module that succeeds. Returns its result, or not_found if none of the stores succeed. If TIME_CALLS is set, this function will also time the call and increment the appropriate event counter.

do_call_function/3 *

do_call_function(X, Function, Args) -> any()

do_find/1 *

do_find(StoreOpts) -> any()

ensure_instance_alive/2 *

ensure_instance_alive(StoreOpts, InstanceMessage) -> any()

Handle a found instance message. If it contains a PID, we check if it is alive. If it does not, we return it as is.

filter/2

filter(Module, Filter) -> any()

Takes a store object and a filter function or match spec, returning a new store object with only the modules that match the filter. The filter function takes 2 arguments: the scope and the options. It calls the store's scope function to get the scope of the module.

find/1

find(StoreOpts) -> any()

Find or spawn a store instance by its store opts.

generate_test_suite/1

generate_test_suite(Suite) -> any()

generate_test_suite/2

generate_test_suite(Suite, Stores) -> any()

get_store_scope/1 *

get_store_scope(Store) -> any()

Ask a store for its own scope. If it doesn't have one, return the default scope (local).

hierarchical_path_resolution_test/1 *

hierarchical_path_resolution_test(Store) -> any()

Ensure that we can resolve links through a directory.

join/1

join(Path) -> any()

Join a list of path components together.

list/2

list(Modules, Path) -> any()

List the keys in a group in the store. Use only in debugging. The hyperbeam model assumes that stores are built as efficient hash-based structures, so this is likely to be very slow for most stores.

make_group/2

make_group(Modules, Path) -> any()

Make a group in the store. A group can be seen as a namespace or 'directory' in a filesystem.

make_link/3

make_link(Modules, Existing, New) -> any()

Make a link from one path to another in the store.

path/1

path(Path) -> any()

Create a path from a list of path components. If no store implements the path function, we return the path with the 'default' transformation (id).

path/2

path(X1, Path) -> any()

read/2

read(Modules, Key) -> any()

Read a key from the store.

reset/1

reset(Modules) -> any()

Delete all of the keys in a store. Should be used with extreme caution. Lost data can lose money in many/most of hyperbeam's use cases.

resolve/2

resolve(Modules, Path) -> any()

Follow links through the store to resolve a path to its ultimate target.

resursive_path_resolution_test/1 *

resursive_path_resolution_test(Store) -> any()

Ensure that we can resolve links recursively.

rocks_stores/0 *

rocks_stores() -> any()

scope/2

scope(Opts, Scope) -> any()

Limit the store scope to only a specific (set of) option(s). Takes either an Opts message or store, and either a single scope or a list of scopes.

simple_path_resolution_test/1 *

simple_path_resolution_test(Store) -> any()

Test path resolution dynamics.

sort/2

sort(Stores, PreferenceOrder) -> any()

Order a store by a preference of its scopes. This is useful for making sure that faster (or perhaps cheaper) stores are used first. If a list is provided, it will be used as a preference order. If a map is provided, scopes will be ordered by the scores in the map. Any unknown scopes will default to a score of 0.

spawn_instance/1 *

spawn_instance(StoreOpts) -> any()

Create a new instance of a store and return its term.

start/1

start(StoreOpts) -> any()

Ensure that a store, or list of stores, have all been started.

stop/1

stop(Modules) -> any()

store_suite_test_/0 *

store_suite_test_() -> any()

test_stores/0

test_stores() -> any()

Return a list of stores for testing. Additional individual functions are used to generate store options for those whose drivers are not built by default into all HyperBEAM distributions.

type/2

type(Modules, Path) -> any()

Get the type of element of a given path in the store. This can be a performance killer if the store is remote etc. Use only when necessary.

write/3

write(Modules, Key, Value) -> any()

Write a key with a value to the store.