%%% -*- erlang -*- %% %% Copyright (c) 2012-2015 Rakuten, Inc. %% Copyright (c) 2016-2026 Benoit Chesneau %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% @doc Erlang Wrapper for RocksDB -module(rocksdb). -export([ open/2, open/3, open_readonly/2, open_readonly/3, open_optimistic_transaction_db/2, open_optimistic_transaction_db/3, open_with_ttl/4, open_with_ttl_cf/4, get_ttl/2, set_ttl/2, set_ttl/3, create_column_family_with_ttl/4, close/1, set_db_background_threads/2, set_db_background_threads/3, destroy/2, repair/2, is_empty/1, list_column_families/2, create_column_family/3, drop_column_family/2, destroy_column_family/2, checkpoint/2, flush/2, flush/3, sync_wal/1, flush_wal/2, supported_compressions/0, pause_background_work/1, continue_background_work/1, disable_manual_compaction/1, enable_manual_compaction/1, abort_all_compactions/1, resume_all_compactions/1, stats/1, stats/2, get_property/2, get_property/3, get_approximate_sizes/3, get_approximate_sizes/4, get_approximate_memtable_stats/3, get_approximate_memtable_stats/4 ]). -export([open_with_cf_readonly/3]). -export([get_column_family_metadata/1, get_column_family_metadata/2]). -export([get_latest_sequence_number/1]). %% snapshot -export([ snapshot/1, release_snapshot/1, get_snapshot_sequence/1 ]). %% KV API -export([ put/4, put/5, merge/4, merge/5, delete/3, delete/4, single_delete/3, single_delete/4, get/3, get/4, multi_get/3, multi_get/4, put_entity/4, put_entity/5, get_entity/3, get_entity/4, delete_range/4, delete_range/5, compact_range/4, compact_range/5, iterator/2, iterator/3, iterators/3, coalescing_iterator/3, iterator_move/2, iterator_refresh/1, iterator_prepare_value/1, iterator_close/1, iterator_columns/1, delete_entity/3, delete_entity/4 ]). %% Cache API -export([new_cache/2, release_cache/1, cache_info/1, cache_info/2, set_capacity/2, set_strict_capacity_limit/2]). %% Limiter API -export([ new_rate_limiter/2, release_rate_limiter/1 ]). %% sst file manager API -export([ new_sst_file_manager/1, new_sst_file_manager/2, release_sst_file_manager/1, sst_file_manager_flag/3, sst_file_manager_info/1, sst_file_manager_info/2, sst_file_manager_tracked_files/1 ]). %% sst file writer API -export([ sst_file_writer_open/2, sst_file_writer_put/3, sst_file_writer_put_entity/3, sst_file_writer_merge/3, sst_file_writer_delete/2, sst_file_writer_delete_range/3, sst_file_writer_finish/1, sst_file_writer_finish/2, sst_file_writer_file_size/1, release_sst_file_writer/1 ]). %% ingest external file API -export([ ingest_external_file/3, ingest_external_file/4 ]). %% sst file reader API -export([ sst_file_reader_open/2, sst_file_reader_iterator/2, sst_file_reader_get_table_properties/1, sst_file_reader_verify_checksum/1, sst_file_reader_verify_checksum/2, sst_file_reader_iterator_move/2, sst_file_reader_iterator_close/1, release_sst_file_reader/1 ]). %% write buffer manager API -export([ new_write_buffer_manager/1, new_write_buffer_manager/2, release_write_buffer_manager/1, write_buffer_manager_info/1, write_buffer_manager_info/2 ]). %% Statistics API -export([ new_statistics/0, set_stats_level/2, statistics_info/1, statistics_ticker/2, statistics_histogram/2, release_statistics/1 ]). %% Env API -export([ new_env/0, new_env/1, set_env_background_threads/2, set_env_background_threads/3, destroy_env/1 ]). %% Log Iterator API -export([tlog_iterator/2, tlog_iterator_close/1, tlog_next_binary_update/1, tlog_next_update/1]). -export([write_binary_update/3]). %% Batch API -export([batch/0, release_batch/1, write_batch/3, batch_put/3, batch_put/4, batch_merge/3, batch_merge/4, batch_delete/2, batch_delete/3, batch_single_delete/2, batch_single_delete/3, batch_delete_range/3, batch_delete_range/4, batch_clear/1, batch_savepoint/1, batch_rollback/1, batch_count/1, batch_data_size/1, batch_tolist/1]). %% Transaction API (Optimistic) -export([ transaction/2, release_transaction/1, transaction_put/3, transaction_put/4, transaction_get/3, transaction_get/4, transaction_get_for_update/3, transaction_get_for_update/4, transaction_multi_get/3, transaction_multi_get/4, transaction_multi_get_for_update/3, transaction_multi_get_for_update/4, %% see comment in c_src/transaction.cc %% transaction_merge/3, transaction_merge/4, transaction_delete/2, transaction_delete/3, transaction_iterator/2, transaction_iterator/3, transaction_commit/1, transaction_rollback/1 ]). %% Pessimistic Transaction API -export([ open_pessimistic_transaction_db/2, open_pessimistic_transaction_db/3, pessimistic_transaction/2, pessimistic_transaction/3, release_pessimistic_transaction/1, pessimistic_transaction_put/3, pessimistic_transaction_put/4, pessimistic_transaction_get/3, pessimistic_transaction_get/4, pessimistic_transaction_get_for_update/3, pessimistic_transaction_get_for_update/4, pessimistic_transaction_multi_get/3, pessimistic_transaction_multi_get/4, pessimistic_transaction_multi_get_for_update/3, pessimistic_transaction_multi_get_for_update/4, pessimistic_transaction_delete/2, pessimistic_transaction_delete/3, pessimistic_transaction_iterator/2, pessimistic_transaction_iterator/3, pessimistic_transaction_commit/1, pessimistic_transaction_rollback/1, pessimistic_transaction_set_savepoint/1, pessimistic_transaction_rollback_to_savepoint/1, pessimistic_transaction_pop_savepoint/1, pessimistic_transaction_get_id/1, pessimistic_transaction_get_waiting_txns/1 ]). %% Backup Engine -export([ open_backup_engine/1, close_backup_engine/1, gc_backup_engine/1, create_new_backup/2, stop_backup/1, get_backup_info/1, verify_backup/2, delete_backup/2, purge_old_backup/2, restore_db_from_backup/3, restore_db_from_backup/4, restore_db_from_latest_backup/2, restore_db_from_latest_backup/3 ]). %% Compaction Filter -export([compaction_filter_reply/2]). %% Posting List Helpers -export([ posting_list_decode/1, posting_list_fold/3, posting_list_keys/1, posting_list_contains/2, posting_list_find/2, posting_list_count/1, posting_list_to_map/1, %% V2 format support posting_list_version/1, posting_list_intersection/2, posting_list_union/2, posting_list_difference/2, posting_list_intersection_count/2, posting_list_bitmap_contains/2, posting_list_intersect_all/1, %% Postings resource API (Lucene-style naming) postings_open/1, postings_contains/2, postings_bitmap_contains/2, postings_count/1, postings_keys/1, postings_intersection/2, postings_union/2, postings_difference/2, postings_intersection_count/2, postings_intersect_all/1, postings_to_binary/1 ]). -export_type([ env/0, env_handle/0, db_handle/0, cache_handle/0, cf_handle/0, itr_handle/0, snapshot_handle/0, batch_handle/0, transaction_handle/0, rate_limiter_handle/0, compression_type/0, compaction_style/0, access_hint/0, wal_recovery_mode/0, backup_engine/0, backup_info/0, sst_file_manager/0, sst_file_writer/0, sst_file_info/0, sst_file_reader/0, sst_file_reader_itr/0, table_properties/0, ingest_external_file_option/0, write_buffer_manager/0, statistics_handle/0, stats_level/0, filter_rule/0, filter_decision/0, compaction_filter_opts/0 ]). -record(db_path, {path :: file:filename_all(), target_size :: non_neg_integer()}). -type cf_descriptor() :: {string(), cf_options()}. -type cache_type() :: lru | clock. -type compression_type() :: snappy | zlib | bzip2 | lz4 | lz4h | zstd | none. -type compaction_style() :: level | universal | fifo | none. -type compaction_pri() :: compensated_size | oldest_largest_seq_first | oldest_smallest_seq_first. -type access_hint() :: normal | sequential | willneed | none. -type wal_recovery_mode() :: tolerate_corrupted_tail_records | absolute_consistency | point_in_time_recovery | skip_any_corrupted_records. -opaque env_handle() :: reference() | binary(). -opaque sst_file_manager() :: reference() | binary(). -opaque sst_file_writer() :: reference() | binary(). -type sst_file_info() :: #{ file_path := binary(), smallest_key := binary(), largest_key := binary(), smallest_range_del_key := binary(), largest_range_del_key := binary(), file_size := non_neg_integer(), num_entries := non_neg_integer(), num_range_del_entries := non_neg_integer(), sequence_number := non_neg_integer() }. -type ingest_external_file_option() :: {move_files, boolean()} | {failed_move_fall_back_to_copy, boolean()} | {snapshot_consistency, boolean()} | {allow_global_seqno, boolean()} | {allow_blocking_flush, boolean()} | {ingest_behind, boolean()} | {verify_checksums_before_ingest, boolean()} | {verify_checksums_readahead_size, non_neg_integer()} | {verify_file_checksum, boolean()} | {fail_if_not_bottommost_level, boolean()} | {allow_db_generated_files, boolean()} | {fill_cache, boolean()}. -opaque sst_file_reader() :: reference() | binary(). -opaque sst_file_reader_itr() :: reference() | binary(). -type table_properties() :: #{ data_size := non_neg_integer(), index_size := non_neg_integer(), index_partitions := non_neg_integer(), top_level_index_size := non_neg_integer(), filter_size := non_neg_integer(), raw_key_size := non_neg_integer(), raw_value_size := non_neg_integer(), num_data_blocks := non_neg_integer(), num_entries := non_neg_integer(), num_deletions := non_neg_integer(), num_merge_operands := non_neg_integer(), num_range_deletions := non_neg_integer(), format_version := non_neg_integer(), fixed_key_len := non_neg_integer(), column_family_id := non_neg_integer(), column_family_name := binary(), filter_policy_name := binary(), comparator_name := binary(), merge_operator_name := binary(), prefix_extractor_name := binary(), property_collectors_names := binary(), compression_name := binary(), compression_options := binary(), creation_time := non_neg_integer(), oldest_key_time := non_neg_integer(), file_creation_time := non_neg_integer(), slow_compression_estimated_data_size := non_neg_integer(), fast_compression_estimated_data_size := non_neg_integer(), external_sst_file_global_seqno_offset := non_neg_integer() }. -opaque db_handle() :: reference() | binary(). -opaque cf_handle() :: reference() | binary(). -opaque itr_handle() :: reference() | binary(). -opaque snapshot_handle() :: reference() | binary(). -opaque batch_handle() :: reference() | binary(). -opaque transaction_handle() :: reference() | binary(). -opaque backup_engine() :: reference() | binary(). -opaque cache_handle() :: reference() | binary(). -opaque rate_limiter_handle() :: reference() | binary(). -opaque write_buffer_manager() :: reference() | binary(). -opaque statistics_handle() :: reference() | binary(). -type column_family() :: cf_handle() | default_column_family. -type env_type() :: default | memenv | {encrypted, Key :: <<_:256>>} | #{encrypted := Key :: <<_:256>>}. -opaque env() :: env_type() | env_handle(). -type env_priority() :: priority_high | priority_low. -type compaction_options_fifo() :: [{max_table_file_size, pos_integer()} | {allow_compaction, boolean()} | %% RocksDB 11.0+ {max_data_files_size, non_neg_integer()} | {use_kv_ratio_compaction, boolean()}]. %% Note: RocksDB 11.0 dropped support for `format_version' < 2. -type block_based_table_options() :: [{no_block_cache, boolean()} | {block_size, pos_integer()} | {block_cache, cache_handle()} | {block_cache_size, pos_integer()} | {bloom_filter_policy, BitsPerKey :: pos_integer()} | {format_version, 2 | 3 | 4 | 5 | 6 | 7} | {cache_index_and_filter_blocks, boolean()} | %% RocksDB 11.0/11.1 {index_block_search_type, binary_search | interpolation | auto} | {uniform_cv_threshold, float()} | {prepopulate_block_cache, disable | flush_only | flush_and_compaction}]. -type merge_operator() :: erlang_merge_operator | bitset_merge_operator | {bitset_merge_operator, non_neg_integer()} | counter_merge_operator. -type read_tier() :: read_all_tier | block_cache_tier | persisted_tier | memtable_tier. -type prepopulate_blob_cache() :: disable | flush_only. %% Compaction Filter Types -type filter_rule() :: {key_prefix, binary()} | {key_suffix, binary()} | {key_contains, binary()} | {value_empty} | {value_prefix, binary()} | {ttl_from_key, Offset :: non_neg_integer(), Length :: non_neg_integer(), TTLSeconds :: non_neg_integer()} | {always_delete}. -type filter_decision() :: keep | remove | {change_value, binary()}. -type compaction_filter_opts() :: #{rules := [filter_rule()]} | #{handler := pid(), batch_size => pos_integer(), timeout => pos_integer()}. -type cf_options() :: [{block_cache_size_mb_for_point_lookup, non_neg_integer()} | {memtable_memory_budget, pos_integer()} | {write_buffer_size, pos_integer()} | {max_write_buffer_number, pos_integer()} | {min_write_buffer_number_to_merge, pos_integer()} | {enable_blob_files, boolean()} | {min_blob_size, non_neg_integer()} | {blob_file_size, non_neg_integer()} | {blob_compression_type, compression_type()} | {enable_blob_garbage_collection, boolean()} | {blob_garbage_collection_age_cutoff, float()} | {blob_garbage_collection_force_threshold, float()} | {blob_compaction_readahead_size, non_neg_integer()} | {blob_file_starting_level, non_neg_integer()} | {blob_cache, cache_handle()} | {prepopulate_blob_cache, prepopulate_blob_cache()} | {compression, compression_type()} | {bottommost_compression, compression_type()} | {compression_opts, compression_opts()} | {bottommost_compression_opts, compression_opts()} | {num_levels, pos_integer()} | {ttl, pos_integer()} | {level0_file_num_compaction_trigger, integer()} | {level0_slowdown_writes_trigger, integer()} | {level0_stop_writes_trigger, integer()} | {target_file_size_base, pos_integer()} | {target_file_size_multiplier, pos_integer()} | {max_bytes_for_level_base, pos_integer()} | {max_bytes_for_level_multiplier, pos_integer()} | {max_compaction_bytes, pos_integer()} | {arena_block_size, integer()} | {disable_auto_compactions, boolean()} | {compaction_style, compaction_style()} | {compaction_pri, compaction_pri()} | {compaction_options_fifo, compaction_options_fifo()} | {filter_deletes, boolean()} | {max_sequential_skip_in_iterations, pos_integer()} | {inplace_update_support, boolean()} | {inplace_update_num_locks, pos_integer()} | {table_factory_block_cache_size, pos_integer()} | {in_memory_mode, boolean()} | {block_based_table_options, block_based_table_options()} | {level_compaction_dynamic_level_bytes, boolean()} | {optimize_filters_for_hits, boolean()} | {prefix_extractor, {fixed_prefix_transform, integer()} |  {capped_prefix_transform, integer()}} | {merge_operator, merge_operator()} | {compaction_filter, compaction_filter_opts()} | {target_file_size_is_upper_bound, boolean()} | %% RocksDB 11.1+ {memtable_batch_lookup_optimization, boolean()} ]. -type db_options() :: [{env, env()} | {total_threads, pos_integer()} | {create_if_missing, boolean()} | {create_missing_column_families, boolean()} | {error_if_exists, boolean()} | {paranoid_checks, boolean()} | {max_open_files, integer()} | {max_total_wal_size, non_neg_integer()} | {use_fsync, boolean()} | {db_paths, list(#db_path{})} | {db_log_dir, file:filename_all()} | {wal_dir, file:filename_all()} | {delete_obsolete_files_period_micros, pos_integer()} | {max_background_jobs, pos_integer()} | {max_background_compactions, pos_integer()} | {max_background_flushes, pos_integer()} | {max_log_file_size, non_neg_integer()} | {log_file_time_to_roll, non_neg_integer()} | {keep_log_file_num, pos_integer()} | {max_manifest_file_size, pos_integer()} | {table_cache_numshardbits, pos_integer()} | {wal_ttl_seconds, non_neg_integer()} | {manual_wal_flush, boolean()} | {wal_size_limit_mb, non_neg_integer()} | {manifest_preallocation_size, pos_integer()} | {allow_mmap_reads, boolean()} | {allow_mmap_writes, boolean()} | {is_fd_close_on_exec, boolean()} | {stats_dump_period_sec, non_neg_integer()} | {advise_random_on_open, boolean()} | {access_hint, access_hint()} | {compaction_readahead_size, non_neg_integer()} | {use_adaptive_mutex, boolean()} | {bytes_per_sync, non_neg_integer()} | {skip_stats_update_on_db_open, boolean()} | {wal_recovery_mode, wal_recovery_mode()} | {allow_concurrent_memtable_write, boolean()} | {enable_write_thread_adaptive_yield, boolean()} | {db_write_buffer_size, non_neg_integer()} | {in_memory, boolean()} | {rate_limiter, rate_limiter_handle()} | {sst_file_manager, sst_file_manager()} | {write_buffer_manager, write_buffer_manager()} | {max_subcompactions, non_neg_integer()} | {atomic_flush, boolean()} | {use_direct_reads, boolean()} | {use_direct_io_for_flush_and_compaction, boolean()} | {enable_pipelined_write, boolean()} | {unordered_write, boolean()} | {two_write_queues, boolean()} | {statistics, statistics_handle()} | {max_manifest_space_amp_pct, integer()} | %% RocksDB 11.1+ %% open_files_async requires skip_stats_update_on_db_open = true {open_files_async, boolean()} | {enforce_write_buffer_manager_during_recovery, boolean()} | {verify_manifest_content_on_close, boolean()}]. -type options() :: db_options() | cf_options(). -type read_options() :: [{read_tier, read_tier()} | {verify_checksums, boolean()} | {fill_cache, boolean()} | {iterate_upper_bound, binary()} | {iterate_lower_bound, binary()} | {tailing, boolean()} | {total_order_seek, boolean()} | {prefix_same_as_start, boolean()} | {snapshot, snapshot_handle()} | {auto_refresh_iterator_with_snapshot, boolean()} | {auto_readahead_size, boolean()} | {readahead_size, non_neg_integer()} | {async_io, boolean()} | {allow_unprepared_value, boolean()}]. -type write_options() :: [{sync, boolean()} | {disable_wal, boolean()} | {ignore_missing_column_families, boolean()} | {no_slowdown, boolean()} | {low_pri, boolean()}]. -type write_actions() :: [{put, Key::binary(), Value::binary()} | {put, ColumnFamilyHandle::cf_handle(), Key::binary(), Value::binary()} | {delete, Key::binary()} | {delete, ColumnFamilyHandle::cf_handle(), Key::binary()} | {single_delete, Key::binary()} | {single_delete, ColumnFamilyHandle::cf_handle(), Key::binary()} | clear]. -type bottommost_level_compaction() :: skip | if_have_compaction_filter | force | force_optimized. -type compact_range_options() :: [{exclusive_manual_compaction, boolean()} | {change_level, boolean()} | {target_level, integer()} | {allow_write_stall, boolean()} | {max_subcompactions, non_neg_integer()} | {bottommost_level_compaction, bottommost_level_compaction()}]. -type flush_options() :: [{wait, boolean()} | {allow_write_stall, boolean()}]. -type compression_opts() :: [{enabled, boolean()} | {window_bits, pos_integer()} | {level, non_neg_integer()} | {strategy, integer()} | {max_dict_bytes, non_neg_integer()} | {zstd_max_train_bytes, non_neg_integer()}]. -type iterator_action() :: first | last | next | prev | binary() | {seek, binary()} | {seek_for_prev, binary()}. -type backup_info() :: #{ id := non_neg_integer(), timestamp := non_neg_integer(), size := non_neg_integer(), number_files := non_neg_integer() }. -type size_approximation_flag() :: none | include_memtables | include_files | include_both. -type range() :: {Start::binary(), Limit::binary()}. -type stats_level() :: stats_disable_all | stats_except_tickers | stats_except_histogram_or_timers | stats_except_timers | stats_except_detailed_timers | stats_except_time_for_mutex | stats_all. -type blob_db_ticker() :: blob_db_num_put | blob_db_num_write | blob_db_num_get | blob_db_num_multiget | blob_db_num_seek | blob_db_num_next | blob_db_num_prev | blob_db_num_keys_written | blob_db_num_keys_read | blob_db_bytes_written | blob_db_bytes_read | blob_db_write_inlined | blob_db_write_inlined_ttl | blob_db_write_blob | blob_db_write_blob_ttl | blob_db_blob_file_bytes_written | blob_db_blob_file_bytes_read | blob_db_blob_file_synced | blob_db_blob_index_expired_count | blob_db_blob_index_expired_size | blob_db_blob_index_evicted_count | blob_db_blob_index_evicted_size | blob_db_gc_num_files | blob_db_gc_num_new_files | blob_db_gc_failures | blob_db_gc_num_keys_relocated | blob_db_gc_bytes_relocated | blob_db_fifo_num_files_evicted | blob_db_fifo_num_keys_evicted | blob_db_fifo_bytes_evicted | blob_db_cache_miss | blob_db_cache_hit | blob_db_cache_add | blob_db_cache_add_failures | blob_db_cache_bytes_read | blob_db_cache_bytes_write. -type blob_db_histogram() :: blob_db_key_size | blob_db_value_size | blob_db_write_micros | blob_db_get_micros | blob_db_multiget_micros | blob_db_seek_micros | blob_db_next_micros | blob_db_prev_micros | blob_db_blob_file_write_micros | blob_db_blob_file_read_micros | blob_db_blob_file_sync_micros | blob_db_compression_micros | blob_db_decompression_micros. -type core_operation_histogram() :: db_get | db_write | db_multiget | db_seek | compaction_time | flush_time. -type io_sync_histogram() :: sst_read_micros | sst_write_micros | table_sync_micros | wal_file_sync_micros | bytes_per_read | bytes_per_write. -type transaction_histogram() :: num_op_per_transaction. -type compaction_ticker() :: compact_read_bytes | compact_write_bytes | flush_write_bytes | compaction_key_drop_newer_entry | compaction_key_drop_obsolete | compaction_key_drop_range_del | compaction_key_drop_user | compaction_cancelled | number_superversion_acquires | number_superversion_releases. -type db_operation_ticker() :: number_keys_written | number_keys_read | number_keys_updated | bytes_written | bytes_read | iter_bytes_read | number_db_seek | number_db_next | number_db_prev | number_db_seek_found | number_db_next_found | number_db_prev_found. -type block_cache_ticker() :: block_cache_miss | block_cache_hit | block_cache_add | block_cache_add_failures | block_cache_index_miss | block_cache_index_hit | block_cache_filter_miss | block_cache_filter_hit | block_cache_data_miss | block_cache_data_hit | block_cache_bytes_read | block_cache_bytes_write. -type memtable_stall_ticker() :: memtable_hit | memtable_miss | stall_micros | write_done_by_self | write_done_by_other | wal_file_synced. -type transaction_ticker() :: txn_prepare_mutex_overhead | txn_old_commit_map_mutex_overhead | txn_duplicate_key_overhead | txn_snapshot_mutex_overhead | txn_get_try_again. -type histogram_info() :: #{median => float(), percentile95 => float(), percentile99 => float(), average => float(), standard_deviation => float(), max => float(), count => non_neg_integer(), sum => non_neg_integer()}. -type blob_metadata() :: #{blob_file_number => non_neg_integer(), blob_file_name => binary(), blob_file_path => binary(), size => non_neg_integer(), total_blob_count => non_neg_integer(), total_blob_bytes => non_neg_integer(), garbage_blob_count => non_neg_integer(), garbage_blob_bytes => non_neg_integer()}. -type cf_metadata() :: #{size => non_neg_integer(), file_count => non_neg_integer(), name => binary(), blob_file_size => non_neg_integer(), blob_files => [blob_metadata()]}. -compile(no_native). -on_load(on_load/0). -define(nif_stub,nif_stub_error(?LINE)). nif_stub_error(Line) -> erlang:nif_error({nif_not_loaded,module,?MODULE,line,Line}). %% This cannot be a separate function. Code must be inline to trigger %% Erlang compiler's use of optimized selective receive. -define(WAIT_FOR_REPLY(Ref), receive {Ref, Reply} -> Reply end). -spec on_load() -> ok | {error, any()}. on_load() -> SoName = case code:priv_dir(?MODULE) of {error, bad_name} -> case code:which(?MODULE) of Filename when is_list(Filename) -> filename:join([filename:dirname(Filename),"../priv", "liberocksdb"]); _ -> filename:join("../priv", "liberocksdb") end; Dir -> filename:join(Dir, "liberocksdb") end, erlang:load_nif(SoName, application:get_all_env(rocksdb)). %%-------------------------------------------------------------------- %%% API %%-------------------------------------------------------------------- %% @doc Open RocksDB with the defalut column family -spec open(Name, DBOpts) -> Result when Name :: file:filename_all(), DBOpts :: options(), Result :: {ok, db_handle()} | {error, any()}. open(_Name, _DBOpts) -> ?nif_stub. -spec open_readonly(Name, DBOpts) -> Result when Name :: file:filename_all(), DBOpts :: options(), Result :: {ok, db_handle()} | {error, any()}. open_readonly(_Name, _DBOpts) -> ?nif_stub. %% @doc Open RocksDB with the specified column families -spec(open(Name, DBOpts, CFDescriptors) -> {ok, db_handle(), list(cf_handle())} | {error, any()} when Name::file:filename_all(), DBOpts :: db_options(), CFDescriptors :: list(cf_descriptor())). open(_Name, _DBOpts, _CFDescriptors) -> ?nif_stub. %% @doc Open read-only RocksDB with the specified column families -spec(open_readonly(Name, DBOpts, CFDescriptors) -> {ok, db_handle(), list(cf_handle())} | {error, any()} when Name::file:filename_all(), DBOpts :: db_options(), CFDescriptors :: list(cf_descriptor())). open_readonly(_Name, _DBOpts, _CFDescriptors) -> ?nif_stub. open_with_cf_readonly(Name, DbOpts, CFDescriptors) -> open_readonly(Name, DbOpts, CFDescriptors). open_optimistic_transaction_db(_Name, _DbOpts) -> open_optimistic_transaction_db(_Name, _DbOpts, [{"default", []}]). open_optimistic_transaction_db(_Name, _DbOpts, _CFDescriptors) -> ?nif_stub. %% @doc Open RocksDB with TTL support %% This API should be used to open the db when key-values inserted are %% meant to be removed from the db in a non-strict `TTL' amount of time %% Therefore, this guarantees that key-values inserted will remain in the %% db for >= TTL amount of time and the db will make efforts to remove the %% key-values as soon as possible after ttl seconds of their insertion. %% %% BEHAVIOUR: %% TTL is accepted in seconds %% (int32_t)Timestamp(creation) is suffixed to values in Put internally %% Expired TTL values deleted in compaction only:(`Timestamp+ttl=5 %% Readonly=true opens in the usual read-only mode. Compactions will not be %% triggered(neither manual nor automatic), so no expired entries removed -spec(open_with_ttl(Name, DBOpts, TTL, ReadOnly) -> {ok, db_handle()} | {error, any()} when Name::file:filename_all(), DBOpts :: db_options(), TTL :: integer(), ReadOnly :: boolean()). open_with_ttl(_Name, _DBOpts, _TTL, _ReadOnly) -> ?nif_stub. %% @doc Open a RocksDB database with TTL support and multiple column families. %% Each column family can have its own TTL value. %% @see open_with_ttl/4 -spec open_with_ttl_cf(Name, DBOpts, CFDescriptors, ReadOnly) -> {ok, db_handle(), [cf_handle()]} | {error, any()} when Name :: file:filename_all(), DBOpts :: db_options(), CFDescriptors :: [{Name :: string(), CFOpts :: cf_options(), TTL :: integer()}], ReadOnly :: boolean(). open_with_ttl_cf(_Name, _DBOpts, _CFDescriptors, _ReadOnly) -> ?nif_stub. %% @doc Get the current TTL for a column family in a TTL database. %% Returns the TTL in seconds. -spec get_ttl(DBHandle, CFHandle) -> {ok, integer()} | {error, any()} when DBHandle :: db_handle(), CFHandle :: cf_handle(). get_ttl(_DBHandle, _CFHandle) -> ?nif_stub. %% @doc Set the default TTL for a TTL database. %% The TTL is specified in seconds. -spec set_ttl(DBHandle, TTL) -> ok | {error, any()} when DBHandle :: db_handle(), TTL :: integer(). set_ttl(_DBHandle, _TTL) -> ?nif_stub. %% @doc Set the TTL for a specific column family in a TTL database. %% The TTL is specified in seconds. -spec set_ttl(DBHandle, CFHandle, TTL) -> ok | {error, any()} when DBHandle :: db_handle(), CFHandle :: cf_handle(), TTL :: integer(). set_ttl(_DBHandle, _CFHandle, _TTL) -> ?nif_stub. %% @doc Create a new column family with a specific TTL in a TTL database. %% The TTL is specified in seconds. -spec create_column_family_with_ttl(DBHandle, Name, CFOpts, TTL) -> {ok, cf_handle()} | {error, any()} when DBHandle :: db_handle(), Name :: string(), CFOpts :: cf_options(), TTL :: integer(). create_column_family_with_ttl(_DBHandle, _Name, _CFOpts, _TTL) -> ?nif_stub. %% @doc Close RocksDB -spec close(DBHandle) -> Res when DBHandle :: db_handle(), Res :: ok | {error, any()}. close(_DBHandle) -> ?nif_stub. %% =============================================== %% Column Families API %% =============================================== %% @doc List column families -spec list_column_families(Name, DBOpts) -> Res when Name::file:filename_all(), DBOpts::db_options(), Res :: {ok, list(string())} | {error, any()}. list_column_families(_Name, _DbOpts) -> ?nif_stub. %% @doc Create a new column family -spec create_column_family(DBHandle, Name, CFOpts) -> Res when DBHandle :: db_handle(), Name ::string(), CFOpts :: cf_options(), Res :: {ok, cf_handle()} | {error, any()}. create_column_family(_DBHandle, _Name, _CFOpts) -> ?nif_stub. %% @doc Drop a column family -spec drop_column_family(DBHandle, CFHandle) -> Res when DBHandle :: db_handle(), CFHandle :: cf_handle(), Res :: ok | {error, any()}. drop_column_family(_DbHandle, _CFHandle) -> ?nif_stub. %% @doc Destroy a column family -spec destroy_column_family(DBHandle, CFHandle) -> Res when DBHandle :: db_handle(), CFHandle :: cf_handle(), Res :: ok | {error, any()}. destroy_column_family(_DBHandle, _CFHandle) -> ?nif_stub. %% @doc Get column family metadata including blob file information. -spec get_column_family_metadata(DBHandle) -> {ok, cf_metadata()} when DBHandle :: db_handle(). get_column_family_metadata(_DBHandle) -> ?nif_stub. %% @doc Get column family metadata for a specific column family. -spec get_column_family_metadata(DBHandle, CFHandle) -> {ok, cf_metadata()} when DBHandle :: db_handle(), CFHandle :: cf_handle(). get_column_family_metadata(_DBHandle, _CFHandle) -> ?nif_stub. %% @doc return a database snapshot %% Snapshots provide consistent read-only views over the entire state of the key-value store -spec snapshot(DbHandle::db_handle()) -> {ok, snapshot_handle()} | {error, any()}. snapshot(_DbHandle) -> ?nif_stub. %% @doc release a snapshot -spec release_snapshot(SnapshotHandle::snapshot_handle()) -> ok | {error, any()}. release_snapshot(_SnapshotHandle) -> ?nif_stub. %% @doc returns Snapshot's sequence number -spec get_snapshot_sequence(SnapshotHandle::snapshot_handle()) -> Sequence::non_neg_integer(). get_snapshot_sequence(_SnapshotHandle) -> ?nif_stub. %% @doc Put a key/value pair into the default column family -spec put(DBHandle, Key, Value, WriteOpts) -> Res when DBHandle::db_handle(), Key::binary(), Value::binary(), WriteOpts::write_options(), Res :: ok | {error, any()}. put(_DBHandle, _Key, _Value, _WriteOpts) -> ?nif_stub. %% @doc Put a key/value pair into the specified column family -spec put(DBHandle, CFHandle, Key, Value, WriteOpts) -> Res when DBHandle::db_handle(), CFHandle::cf_handle(), Key::binary(), Value::binary(), WriteOpts::write_options(), Res :: ok | {error, any()}. put(_DBHandle, _CFHandle, _Key, _Value, _WriteOpts) -> ?nif_stub. %% @doc Merge a key/value pair into the default column family %% For posting list operations, Value can be: %% - `{posting_add, Key}' to add a key to the posting list %% - `{posting_delete, Key}' to mark a key as tombstoned -spec merge(DBHandle, Key, Value, WriteOpts) -> Res when DBHandle::db_handle(), Key::binary(), Value::binary() | {posting_add, binary()} | {posting_delete, binary()}, WriteOpts::write_options(), Res :: ok | {error, any()}. merge(DBHandle, Key, Value, WriteOpts) -> merge_nif(DBHandle, Key, encode_merge_value(Value), WriteOpts). %% @doc Merge a key/value pair into the specified column family %% For posting list operations, Value can be: %% - `{posting_add, Key}' to add a key to the posting list %% - `{posting_delete, Key}' to mark a key as tombstoned -spec merge(DBHandle, CFHandle, Key, Value, WriteOpts) -> Res when DBHandle::db_handle(), CFHandle::cf_handle(), Key::binary(), Value::binary() | {posting_add, binary()} | {posting_delete, binary()}, WriteOpts::write_options(), Res :: ok | {error, any()}. merge(DBHandle, CFHandle, Key, Value, WriteOpts) -> merge_nif(DBHandle, CFHandle, Key, encode_merge_value(Value), WriteOpts). %% Internal NIF stubs for merge merge_nif(_DBHandle, _Key, _Value, _WriteOpts) -> ?nif_stub. merge_nif(_DBHandle, _CFHandle, _Key, _Value, _WriteOpts) -> ?nif_stub. %% Encode merge value - convert posting list tuples to term_to_binary format encode_merge_value({posting_add, Key}) when is_binary(Key) -> term_to_binary({posting_add, Key}); encode_merge_value({posting_delete, Key}) when is_binary(Key) -> term_to_binary({posting_delete, Key}); encode_merge_value(Value) when is_binary(Value) -> Value. %% @doc Delete a key/value pair in the default column family -spec(delete(DBHandle, Key, WriteOpts) -> ok | {error, any()} when DBHandle::db_handle(), Key::binary(), WriteOpts::write_options()). delete(_DBHandle, _Key, _WriteOpts) -> ?nif_stub. %% @doc Delete a key/value pair in the specified column family -spec delete(DBHandle, CFHandle, Key, WriteOpts) -> Res when DBHandle::db_handle(), CFHandle::cf_handle(), Key::binary(), WriteOpts::write_options(), Res :: ok | {error, any()}. delete(_DBHandle, _CFHandle, _Key, _WriteOpts) -> ?nif_stub. %% @doc Remove the database entry for "key". Requires that the key exists %% and was not overwritten. Returns OK on success, and a non-OK status %% on error. It is not an error if "key" did not exist in the database. %% %% If a key is overwritten (by calling Put() multiple times), then the result %% of calling SingleDelete() on this key is undefined. SingleDelete() only %% behaves correctly if there has been only one Put() for this key since the %% previous call to SingleDelete() for this key. %% %% This feature is currently an experimental performance optimization %% for a very specific workload. It is up to the caller to ensure that %% SingleDelete is only used for a key that is not deleted using Delete() or %% written using Merge(). Mixing SingleDelete operations with Deletes %% can result in undefined behavior. %% %% Note: consider setting options `{sync, true}'. -spec(single_delete(DBHandle, Key, WriteOpts) -> ok | {error, any()} when DBHandle::db_handle(), Key::binary(), WriteOpts::write_options()). single_delete(_DBHandle, _Key, _WriteOpts) -> ?nif_stub. %% @doc like `single_delete/3' but on the specified column family -spec single_delete(DBHandle, CFHandle, Key, WriteOpts) -> Res when DBHandle::db_handle(), CFHandle::cf_handle(), Key::binary(), WriteOpts::write_options(), Res :: ok | {error, any()}. single_delete(_DBHandle, _CFHandle, _Key, _WriteOpts) -> ?nif_stub. %% @doc Retrieve a key/value pair in the default column family -spec get(DBHandle, Key, ReadOpts) -> Res when DBHandle::db_handle(), Key::binary(), ReadOpts::read_options(), Res :: {ok, binary()} | not_found | {error, {corruption, string()}} | {error, any()}. get(_DBHandle, _Key, _ReadOpts) -> ?nif_stub. %% @doc Retrieve a key/value pair in the specified column family -spec get(DBHandle, CFHandle, Key, ReadOpts) -> Res when DBHandle::db_handle(), CFHandle::cf_handle(), Key::binary(), ReadOpts::read_options(), Res :: {ok, binary()} | not_found | {error, {corruption, string()}} | {error, any()}. get(_DBHandle, _CFHandle, _Key, _ReadOpts) -> ?nif_stub. %% @doc Retrieve multiple key/value pairs in a single call. %% Returns a list of results in the same order as the input keys. %% Each result is either `{ok, Value}', `not_found', or `{error, Reason}'. %% This is more efficient than calling get/3 multiple times. -spec multi_get(DBHandle, Keys, ReadOpts) -> Results when DBHandle :: db_handle(), Keys :: [binary()], ReadOpts :: read_options(), Results :: [{ok, binary()} | not_found | {error, any()}]. multi_get(_DBHandle, _Keys, _ReadOpts) -> ?nif_stub. %% @doc Retrieve multiple key/value pairs from a specific column family. %% Returns a list of results in the same order as the input keys. -spec multi_get(DBHandle, CFHandle, Keys, ReadOpts) -> Results when DBHandle :: db_handle(), CFHandle :: cf_handle(), Keys :: [binary()], ReadOpts :: read_options(), Results :: [{ok, binary()} | not_found | {error, any()}]. multi_get(_DBHandle, _CFHandle, _Keys, _ReadOpts) -> ?nif_stub. %% @doc Put an entity (wide-column key) in the default column family. %% An entity is a key with multiple named columns stored as a proplist. -spec put_entity(DBHandle, Key, Columns, WriteOpts) -> Res when DBHandle::db_handle(), Key::binary(), Columns::[{binary(), binary()}], WriteOpts::write_options(), Res :: ok | {error, any()}. put_entity(_DBHandle, _Key, _Columns, _WriteOpts) -> ?nif_stub. %% @doc Put an entity (wide-column key) in the specified column family. -spec put_entity(DBHandle, CFHandle, Key, Columns, WriteOpts) -> Res when DBHandle::db_handle(), CFHandle::cf_handle(), Key::binary(), Columns::[{binary(), binary()}], WriteOpts::write_options(), Res :: ok | {error, any()}. put_entity(_DBHandle, _CFHandle, _Key, _Columns, _WriteOpts) -> ?nif_stub. %% @doc Retrieve an entity (wide-column key) from the default column family. %% Returns the columns as a proplist of {Name, Value} tuples. -spec get_entity(DBHandle, Key, ReadOpts) -> Res when DBHandle::db_handle(), Key::binary(), ReadOpts::read_options(), Res :: {ok, [{binary(), binary()}]} | not_found | {error, any()}. get_entity(_DBHandle, _Key, _ReadOpts) -> ?nif_stub. %% @doc Retrieve an entity (wide-column key) from the specified column family. -spec get_entity(DBHandle, CFHandle, Key, ReadOpts) -> Res when DBHandle::db_handle(), CFHandle::cf_handle(), Key::binary(), ReadOpts::read_options(), Res :: {ok, [{binary(), binary()}]} | not_found | {error, any()}. get_entity(_DBHandle, _CFHandle, _Key, _ReadOpts) -> ?nif_stub. %% @doc For each i in [0,n-1], store in "Sizes[i]", the approximate %% file system space used by keys in "[range[i].start .. range[i].limit)". %% %% Note that the returned sizes measure file system space usage, so %% if the user data compresses by a factor of ten, the returned %% sizes will be one-tenth the size of the corresponding user data size. %% %% If `IncludeFlags' defines whether the returned size should include %% the recently written data in the mem-tables (if %% the mem-table type supports it), data serialized to disk, or both. -spec get_approximate_sizes(DBHandle, Ranges, IncludeFlags) -> Sizes when DBHandle::db_handle(), Ranges::[range()], IncludeFlags::size_approximation_flag(), Sizes :: [non_neg_integer()]. get_approximate_sizes(_DBHandle, _Ranges, _IncludeFlags) -> ?nif_stub. -spec get_approximate_sizes(DBHandle, CFHandle, Ranges, IncludeFlags) -> Sizes when DBHandle::db_handle(), CFHandle::cf_handle(), Ranges::[range()], IncludeFlags::size_approximation_flag(), Sizes :: [non_neg_integer()]. get_approximate_sizes(_DBHandle, _CFHandle, _Ranges, _IncludeFlags) -> ?nif_stub. %% @doc The method is similar to GetApproximateSizes, except it %% returns approximate number of records in memtables. -spec get_approximate_memtable_stats(DBHandle, StartKey, LimitKey) -> Res when DBHandle::db_handle(), StartKey :: binary(), LimitKey :: binary(), Res :: {ok, {Count::non_neg_integer(), Size::non_neg_integer()}}. get_approximate_memtable_stats(_DBHandle, _StartKey, _LimitKey) -> ?nif_stub. -spec get_approximate_memtable_stats(DBHandle, CFHandle, StartKey, LimitKey) -> Res when DBHandle::db_handle(), CFHandle::cf_handle(), StartKey :: binary(), LimitKey :: binary(), Res :: {ok, {Count::non_neg_integer(), Size::non_neg_integer()}}. get_approximate_memtable_stats(_DBHandle, _CFHandle, _StartKey, _LimitKey) -> ?nif_stub. %% @doc Removes the database entries in the range ["BeginKey", "EndKey"), i.e., %% including "BeginKey" and excluding "EndKey". Returns OK on success, and %% a non-OK status on error. It is not an error if no keys exist in the range %% ["BeginKey", "EndKey"). %% %% This feature is currently an experimental performance optimization for %% deleting very large ranges of contiguous keys. Invoking it many times or on %% small ranges may severely degrade read performance; in particular, the %% resulting performance can be worse than calling Delete() for each key in %% the range. Note also the degraded read performance affects keys outside the %% deleted ranges, and affects database operations involving scans, like flush %% and compaction. %% %% Consider setting ReadOptions::ignore_range_deletions = true to speed %% up reads for key(s) that are known to be unaffected by range deletions. -spec delete_range(DBHandle, BeginKey, EndKey, WriteOpts) -> Res when DBHandle::db_handle(), BeginKey::binary(), EndKey::binary(), WriteOpts::write_options(), Res :: ok | {error, any()}. delete_range(_DbHandle, _Start, _End, _WriteOpts) -> ?nif_stub. %% @doc Removes the database entries in the range ["BeginKey", "EndKey"). %% like `delete_range/3' but for a column family -spec delete_range(DBHandle, CFHandle, BeginKey, EndKey, WriteOpts) -> Res when DBHandle::db_handle(), CFHandle::cf_handle(), BeginKey::binary(), EndKey::binary(), WriteOpts::write_options(), Res :: ok | {error, any()}. delete_range(_DbHandle, _CFHandle, _Start, _End, _WriteOpts) -> ?nif_stub. %% @doc Compact the underlying storage for the key range [*begin,*end]. %% The actual compaction interval might be superset of [*begin, *end]. %% In particular, deleted and overwritten versions are discarded, %% and the data is rearranged to reduce the cost of operations %% needed to access the data. This operation should typically only %% be invoked by users who understand the underlying implementation. %% %% "begin==undefined" is treated as a key before all keys in the database. %% "end==undefined" is treated as a key after all keys in the database. %% Therefore the following call will compact the entire database: %% rocksdb::compact_range(Options, undefined, undefined); %% Note that after the entire database is compacted, all data are pushed %% down to the last level containing any data. If the total data size after %% compaction is reduced, that level might not be appropriate for hosting all %% the files. In this case, client could set options.change_level to true, to %% move the files back to the minimum level capable of holding the data set %% or a given level (specified by non-negative target_level). -spec compact_range(DBHandle, BeginKey, EndKey, CompactRangeOpts) -> Res when DBHandle::db_handle(), BeginKey::binary() | undefined, EndKey::binary() | undefined, CompactRangeOpts::compact_range_options(), Res :: ok | {error, any()}. compact_range(_DbHandle, _Start, _End, _CompactRangeOpts) -> ?nif_stub. %% @doc Compact the underlying storage for the key range ["BeginKey", "EndKey"). %% like `compact_range/3' but for a column family -spec compact_range(DBHandle, CFHandle, BeginKey, EndKey, CompactRangeOpts) -> Res when DBHandle::db_handle(), CFHandle::cf_handle(), BeginKey::binary() | undefined, EndKey::binary() | undefined, CompactRangeOpts::compact_range_options(), Res :: ok | {error, any()}. compact_range(_DbHandle, _CFHandle, _Start, _End, _CompactRangeOpts) -> ?nif_stub. %% @doc Return a iterator over the contents of the database. %% The result of iterator() is initially invalid (caller must %% call iterator_move function on the iterator before using it). -spec iterator(DBHandle, ReadOpts) -> Res when DBHandle::db_handle(), ReadOpts::read_options(), Res :: {ok, itr_handle()} | {error, any()}. iterator(_DBHandle, _ReadOpts) -> ?nif_stub. %% @doc Return a iterator over the contents of the database. %% The result of iterator() is initially invalid (caller must %% call iterator_move function on the iterator before using it). -spec iterator(DBHandle, CFHandle, ReadOpts) -> Res when DBHandle::db_handle(), CFHandle::cf_handle(), ReadOpts::read_options(), Res :: {ok, itr_handle()} | {error, any()}. iterator(_DBHandle, _CfHandle, _ReadOpts) -> ?nif_stub. %% @doc %% Return a iterator over the contents of the specified column family. -spec(iterators(DBHandle, CFHandle, ReadOpts) -> {ok, itr_handle()} | {error, any()} when DBHandle::db_handle(), CFHandle::cf_handle(), ReadOpts::read_options()). iterators(_DBHandle, _CFHandle, _ReadOpts) -> ?nif_stub. %% @doc %% Return a coalescing iterator over multiple column families. %% The iterator merges results from all column families and returns %% keys in sorted order. When the same key exists in multiple column %% families, only one value is returned (from the first CF in the list). -spec(coalescing_iterator(DBHandle, CFHandles, ReadOpts) -> {ok, itr_handle()} | {error, any()} when DBHandle::db_handle(), CFHandles::[cf_handle()], ReadOpts::read_options()). coalescing_iterator(_DBHandle, _CFHandles, _ReadOpts) -> ?nif_stub. %% @doc %% Move to the specified place -spec(iterator_move(ITRHandle, ITRAction) -> {ok, Key::binary(), Value::binary()} | {ok, Key::binary()} | {error, invalid_iterator} | {error, iterator_closed} when ITRHandle::itr_handle(), ITRAction::iterator_action()). iterator_move(_ITRHandle, _ITRAction) -> ?nif_stub. %% @doc %% Refresh iterator -spec(iterator_refresh(ITRHandle) -> ok when ITRHandle::itr_handle()). iterator_refresh(_ITRHandle) -> ?nif_stub. %% @doc Load the blob value for the current iterator position. %% Use with `{allow_unprepared_value, true}' to enable efficient key-only %% scanning with selective value loading. -spec(iterator_prepare_value(ITRHandle) -> ok | {error, any()} when ITRHandle::itr_handle()). iterator_prepare_value(_ITRHandle) -> ?nif_stub. %% @doc %% Close a iterator -spec(iterator_close(ITRHandle) -> ok | {error, _} when ITRHandle::itr_handle()). iterator_close(_ITRHandle) -> ?nif_stub. %% @doc Get the columns of the current iterator entry. %% Returns the wide columns for the current entry. For entities, returns %% all columns. For regular key-values, returns a single column with an %% empty name (the default column) containing the value. -spec iterator_columns(ITRHandle) -> Res when ITRHandle::itr_handle(), Res :: {ok, [{binary(), binary()}]} | {error, any()}. iterator_columns(_ITRHandle) -> ?nif_stub. %% @doc Delete an entity (same as regular delete). %% Entities are deleted using the normal delete operation - all columns %% are removed when the key is deleted. -spec delete_entity(DBHandle, Key, WriteOpts) -> Res when DBHandle::db_handle(), Key::binary(), WriteOpts::write_options(), Res :: ok | {error, any()}. delete_entity(DBHandle, Key, WriteOpts) -> delete(DBHandle, Key, WriteOpts). %% @doc Delete an entity from a column family (same as regular delete). -spec delete_entity(DBHandle, CFHandle, Key, WriteOpts) -> Res when DBHandle::db_handle(), CFHandle::cf_handle(), Key::binary(), WriteOpts::write_options(), Res :: ok | {error, any()}. delete_entity(DBHandle, CFHandle, Key, WriteOpts) -> delete(DBHandle, CFHandle, Key, WriteOpts). %% @doc is the database empty -spec is_empty(DBHandle::db_handle()) -> true | false. is_empty(_DbHandle) -> ?nif_stub. %% @doc Destroy the contents of the specified database. %% Be very careful using this method. -spec destroy(Name::file:filename_all(), DBOpts::db_options()) -> ok | {error, any()}. destroy(_Name, _DBOpts) -> ?nif_stub. %% @doc Try to repair as much of the contents of the database as possible. %% Some data may be lost, so be careful when calling this function -spec repair(Name::file:filename_all(), DBOpts::db_options()) -> ok | {error, any()}. repair(_Name, _DBOpts) -> ?nif_stub. %% @doc take a snapshot of a running RocksDB database in a separate directory %% http://rocksdb.org/blog/2609/use-checkpoints-for-efficient-snapshots/ -spec checkpoint( DbHandle::db_handle(), Path::file:filename_all() ) -> ok | {error, any()}. checkpoint(_DbHandle, _Path) -> ?nif_stub. %% @doc Flush all mem-table data. -spec flush(db_handle(), flush_options()) -> ok | {error, term()}. flush(DbHandle, FlushOptions) -> flush(DbHandle, default_column_family, FlushOptions). %% @doc Flush all mem-table data for a column family -spec flush(db_handle(), column_family(), flush_options()) -> ok | {error, term()}. flush(_DbHandle, _Cf, _FlushOptions) -> ?nif_stub. %% @doc Sync the wal. Note that Write() followed by SyncWAL() is not exactly the %% same as Write() with sync=true: in the latter case the changes won't be %% visible until the sync is done. %% Currently only works if allow_mmap_writes = false in Options. -spec sync_wal(db_handle()) -> ok | {error, term()}. sync_wal(_DbHandle) -> ?nif_stub. %% @doc Flush WAL with options. %% Options: %% {sync, boolean()} - If true, calls SyncWAL() afterwards (default: false) %% {rate_limiter_priority, io_low | io_mid | io_high | io_user | io_total} - %% Rate limiter priority for IO operations (default: io_total which disables rate limiting) -type flush_wal_option() :: {sync, boolean()} | {rate_limiter_priority, io_low | io_mid | io_high | io_user | io_total}. -type flush_wal_options() :: [flush_wal_option()]. -spec flush_wal(db_handle(), flush_wal_options()) -> ok | {error, term()}. flush_wal(_DbHandle, _Options) -> ?nif_stub. %% @doc Return the list of compression types supported by this build. %% This queries RocksDB to determine which compression libraries were %% compiled in. Common types include: snappy, lz4, lz4h, zstd, zlib, bzip2, none. -spec supported_compressions() -> [compression_type()]. supported_compressions() -> ?nif_stub. %% @doc Pause all background work (flush, compaction) for the database. %% This is useful when you need to take a consistent backup. %% Use continue_background_work/1 to resume. -spec pause_background_work(db_handle()) -> ok | {error, term()}. pause_background_work(_DbHandle) -> ?nif_stub. %% @doc Continue background work (flush, compaction) that was previously paused. %% Call this after pause_background_work/1 to resume normal operation. -spec continue_background_work(db_handle()) -> ok | {error, term()}. continue_background_work(_DbHandle) -> ?nif_stub. %% @doc Disable manual compaction (CompactRange, CompactFiles). %% If a manual compaction is in progress, this will wait until it completes. -spec disable_manual_compaction(db_handle()) -> ok. disable_manual_compaction(_DbHandle) -> ?nif_stub. %% @doc Re-enable manual compaction after it was disabled. -spec enable_manual_compaction(db_handle()) -> ok. enable_manual_compaction(_DbHandle) -> ?nif_stub. %% @doc Abort all running and scheduled compactions (RocksDB 11.0+). %% In-progress compactions are actively cancelled and report a status for which %% `rocksdb:is_compaction_aborted/1' (a RocksDB `kCompactionAborted' status) is %% true. Call `resume_all_compactions/1' as many times as this was called to %% resume. -spec abort_all_compactions(db_handle()) -> ok | {error, term()}. abort_all_compactions(_DbHandle) -> ?nif_stub. %% @doc Resume compactions previously aborted by `abort_all_compactions/1' %% (RocksDB 11.0+). Must be called as many times as `abort_all_compactions/1'. -spec resume_all_compactions(db_handle()) -> ok | {error, term()}. resume_all_compactions(_DbHandle) -> ?nif_stub. %% @doc Return the current stats of the default column family %% Implemented by calling GetProperty with "rocksdb.stats" -spec stats(DBHandle::db_handle()) -> {ok, any()} | {error, any()}. stats(DBHandle) -> get_property(DBHandle, <<"rocksdb.stats">>). %% @doc Return the current stats of the specified column family %% Implemented by calling GetProperty with "rocksdb.stats" -spec stats( DBHandle::db_handle(), CFHandle::cf_handle() ) -> {ok, any()} | {error, any()}. stats(DBHandle, CfHandle) -> get_property(DBHandle, CfHandle, <<"rocksdb.stats">>). %% @doc Return the RocksDB internal status of the default column family specified at Property -spec get_property( DBHandle::db_handle(), Property::binary() ) -> {ok, any()} | {error, any()}. get_property(_DBHandle, _Property) -> ?nif_stub. %% @doc Return the RocksDB internal status of the specified column family specified at Property -spec get_property( DBHandle::db_handle(), CFHandle::cf_handle(), Property::binary() ) -> {ok, binary()} | {error, any()}. get_property(_DBHandle, _CFHandle, _Property) -> ?nif_stub. %% @doc gThe sequence number of the most recent transaction. -spec get_latest_sequence_number(Db :: db_handle()) -> Seq :: non_neg_integer(). get_latest_sequence_number(_DbHandle) -> ?nif_stub. %% =================================================================== %% Transaction Log API %% @doc create a new iterator to retrive ethe transaction log since a sequce -spec tlog_iterator(Db :: db_handle(),Since :: non_neg_integer()) -> {ok, Iterator :: term()}. tlog_iterator(_DbHandle, _Since) -> ?nif_stub. %% @doc close the transaction log -spec tlog_iterator_close(term()) -> ok. tlog_iterator_close(_Iterator) -> ?nif_stub. %% @doc go to the last update as a binary in the transaction log, can be ussed with the write_binary_update function. -spec tlog_next_binary_update( Iterator :: term() ) -> {ok, LastSeq :: non_neg_integer(), BinLog :: binary()} | {error, term()}. tlog_next_binary_update(_Iterator) -> ?nif_stub. %% @doc like `tlog_nex_binary_update/1' but also return the batch as a list of operations -spec tlog_next_update( Iterator :: term() ) -> {ok, LastSeq :: non_neg_integer(), Log :: write_actions(), BinLog :: binary()} | {error, term()}. tlog_next_update(_Iterator) -> ?nif_stub. %% @doc apply a set of operation coming from a transaction log to another database. Can be useful to use it in slave %% mode. %% -spec write_binary_update( DbHandle :: db_handle(), BinLog :: binary(), WriteOptions :: write_options() ) -> ok | {error, term()}. write_binary_update(_DbHandle, _Update, _WriteOptions) -> ?nif_stub. %% =================================================================== %% Batch API %% @doc create a new batch in memory. A batch is a nif resource attached to the current process. Pay attention when you %% share it with other processes as it may not been released. To force its release you will need to use the release_batch %% function. -spec batch() -> {ok, Batch :: batch_handle()}. batch() -> ?nif_stub. -spec release_batch(Batch :: batch_handle()) -> ok. release_batch(_Batch) -> ?nif_stub. %% @doc write the batch to the database -spec write_batch(Db :: db_handle(), Batch :: batch_handle(), WriteOptions :: write_options()) -> ok | {error, term()}. write_batch(_DbHandle, _Batch, _WriteOptions) -> ?nif_stub. %% @doc add a put operation to the batch -spec batch_put(Batch :: batch_handle(), Key :: binary(), Value :: binary()) -> ok. batch_put(_Batch, _Key, _Value) -> ?nif_stub. %% @doc like `batch_put/3' but apply the operation to a column family -spec batch_put(Batch :: batch_handle(), ColumnFamily :: cf_handle(), Key :: binary(), Value :: binary()) -> ok. batch_put(_Batch, _ColumnFamily, _Key, _Value) -> ?nif_stub. %% @doc add a merge operation to the batch %% For posting list operations, Value can be: %% - `{posting_add, Key}' to add a key to the posting list %% - `{posting_delete, Key}' to mark a key as tombstoned -spec batch_merge(Batch :: batch_handle(), Key :: binary(), Value :: binary() | {posting_add, binary()} | {posting_delete, binary()}) -> ok. batch_merge(Batch, Key, Value) -> batch_merge_nif(Batch, Key, encode_merge_value(Value)). %% @doc like `batch_mege/3' but apply the operation to a column family %% For posting list operations, Value can be: %% - `{posting_add, Key}' to add a key to the posting list %% - `{posting_delete, Key}' to mark a key as tombstoned -spec batch_merge(Batch :: batch_handle(), ColumnFamily :: cf_handle(), Key :: binary(), Value :: binary() | {posting_add, binary()} | {posting_delete, binary()}) -> ok. batch_merge(Batch, ColumnFamily, Key, Value) -> batch_merge_nif(Batch, ColumnFamily, Key, encode_merge_value(Value)). %% Internal NIF stubs for batch_merge batch_merge_nif(_Batch, _Key, _Value) -> ?nif_stub. batch_merge_nif(_Batch, _ColumnFamily, _Key, _Value) -> ?nif_stub. %% @doc batch implementation of delete operation to the batch -spec batch_delete(Batch :: batch_handle(), Key :: binary()) -> ok. batch_delete(_Batch, _Key) -> ?nif_stub. %% @doc like `batch_delete/2' but apply the operation to a column family -spec batch_delete(Batch :: batch_handle(), ColumnFamily :: cf_handle(), Key :: binary()) -> ok. batch_delete(_Batch, _ColumnFamily, _Key) -> ?nif_stub. %% @doc batch implementation of single_delete operation to the batch -spec batch_single_delete(Batch :: batch_handle(), Key :: binary()) -> ok. batch_single_delete(_Batch, _Key) -> ?nif_stub. %% @doc like `batch_single_delete/2' but apply the operation to a column family -spec batch_single_delete(Batch :: batch_handle(), ColumnFamily :: cf_handle(), Key :: binary()) -> ok. batch_single_delete(_Batch, _ColumnFamily, _Key) -> ?nif_stub. %% @doc Batch implementation of `delete_range/5' -spec batch_delete_range(Batch :: batch_handle(), Begin :: binary(), End :: binary()) -> ok. batch_delete_range(_Batch, _Begin, _End) -> ?nif_stub. %% @doc Like `batch_delete_range/3' but apply the operation to a column family -spec batch_delete_range(Batch :: batch_handle(), ColumnFamily :: cf_handle(), Begin :: binary(), End :: binary()) -> ok. batch_delete_range(_Batch, _ColumnFamily, _Begin, _End) -> ?nif_stub. %% @doc return the number of operations in the batch -spec batch_count(_Batch :: batch_handle()) -> Count :: non_neg_integer(). batch_count(_Batch) -> ?nif_stub. %% @doc Retrieve data size of the batch. -spec batch_data_size(_Batch :: batch_handle()) -> BatchSize :: non_neg_integer(). batch_data_size(_Batch) -> ?nif_stub. %% @doc reset the batch, clear all operations. -spec batch_clear(Batch :: batch_handle()) -> ok. batch_clear(_Batch) -> ?nif_stub. %% @doc store a checkpoint in the batch to which you can rollback later -spec batch_savepoint(Batch :: batch_handle()) -> ok. batch_savepoint(_Batch) -> ?nif_stub. %% @doc rollback the operations to the latest checkpoint -spec batch_rollback(Batch :: batch_handle()) -> ok. batch_rollback(_Batch) -> ?nif_stub. %% @doc return all the operation sin the batch as a list of operations -spec batch_tolist(Batch :: batch_handle()) -> Ops :: write_actions(). batch_tolist(_Batch) -> ?nif_stub. %% =================================================================== %% Transaction API %% @doc create a new transaction %% When opened as a Transaction or Optimistic Transaction db, %% a user can both read and write to a transaction without committing %% anything to the disk until they decide to do so. -spec transaction(TransactionDB :: db_handle(), WriteOptions :: write_options()) -> {ok, transaction_handle()}. transaction(_TransactionDB, _WriteOptions) -> ?nif_stub. %% @doc release a transaction -spec release_transaction(TransactionHandle::transaction_handle()) -> ok. release_transaction(_TransactionHandle) -> ?nif_stub. %% @doc add a put operation to the transaction -spec transaction_put(Transaction :: transaction_handle(), Key :: binary(), Value :: binary()) -> ok | {error, any()}. transaction_put(_Transaction, _Key, _Value) -> ?nif_stub. %% @doc like `transaction_put/3' but apply the operation to a column family -spec transaction_put(Transaction :: transaction_handle(), ColumnFamily :: cf_handle(), Key :: binary(), Value :: binary()) -> ok | {error, any()}. transaction_put(_Transaction, _ColumnFamily, _Key, _Value) -> ?nif_stub. %% @doc do a get operation on the contents of the transaction -spec transaction_get(Transaction :: transaction_handle(), Key :: binary(), Opts :: read_options()) -> Res :: {ok, binary()} | not_found | {error, {corruption, string()}} | {error, any()}. transaction_get(_Transaction, _Key, _Opts) -> ?nif_stub. %% @doc like `transaction_get/3' but apply the operation to a column family -spec transaction_get(Transaction :: transaction_handle(), ColumnFamily :: cf_handle(), Key :: binary(), Opts :: read_options()) -> Res :: {ok, binary()} | not_found | {error, {corruption, string()}} | {error, any()}. transaction_get(_Transaction, _ColumnFamily, _Key, _Opts) -> ?nif_stub. %% @doc get a value and track the key for conflict detection at commit time. %% For optimistic transactions, this records the key so that if another %% transaction modifies it before commit, the commit will fail with a conflict. -spec transaction_get_for_update(Transaction :: transaction_handle(), Key :: binary(), Opts :: read_options()) -> Res :: {ok, binary()} | not_found | {error, busy} | {error, {corruption, string()}} | {error, any()}. transaction_get_for_update(_Transaction, _Key, _Opts) -> ?nif_stub. %% @doc like `transaction_get_for_update/3' but apply the operation to a column family -spec transaction_get_for_update(Transaction :: transaction_handle(), ColumnFamily :: cf_handle(), Key :: binary(), Opts :: read_options()) -> Res :: {ok, binary()} | not_found | {error, busy} | {error, {corruption, string()}} | {error, any()}. transaction_get_for_update(_Transaction, _ColumnFamily, _Key, _Opts) -> ?nif_stub. %% @doc batch get multiple values within a transaction. %% Returns a list of results in the same order as the input keys. -spec transaction_multi_get(Transaction :: transaction_handle(), Keys :: [binary()], Opts :: read_options()) -> [{ok, binary()} | not_found | {error, any()}]. transaction_multi_get(_Transaction, _Keys, _Opts) -> ?nif_stub. %% @doc like `transaction_multi_get/3' but apply the operation to a column family -spec transaction_multi_get(Transaction :: transaction_handle(), ColumnFamily :: cf_handle(), Keys :: [binary()], Opts :: read_options()) -> [{ok, binary()} | not_found | {error, any()}]. transaction_multi_get(_Transaction, _ColumnFamily, _Keys, _Opts) -> ?nif_stub. %% @doc batch get multiple values and track keys for conflict detection. %% For optimistic transactions, this records the keys so that if another %% transaction modifies any of them before commit, the commit will fail. -spec transaction_multi_get_for_update(Transaction :: transaction_handle(), Keys :: [binary()], Opts :: read_options()) -> [{ok, binary()} | not_found | {error, any()}]. transaction_multi_get_for_update(_Transaction, _Keys, _Opts) -> ?nif_stub. %% @doc like `transaction_multi_get_for_update/3' but apply to a column family -spec transaction_multi_get_for_update(Transaction :: transaction_handle(), ColumnFamily :: cf_handle(), Keys :: [binary()], Opts :: read_options()) -> [{ok, binary()} | not_found | {error, any()}]. transaction_multi_get_for_update(_Transaction, _ColumnFamily, _Keys, _Opts) -> ?nif_stub. %% see comment in c_src/transaction.cc %% %% @doc add a merge operation to the transaction %% -spec transaction_merge(Transaction :: transaction_handle(), Key :: binary(), Value :: binary()) -> ok. %% transaction_merge(_Transaction, _Key, _Value) -> %% ?nif_stub. %% %% @doc like `transaction_merge/3' but apply the operation to a column family %% -spec transaction_merge(Transaction :: transaction_handle(), ColumnFamily :: cf_handle(), Key :: binary(), Value :: binary()) -> ok. %% transaction_merge(_Transaction, _ColumnFamily, _Key, _Value) -> %% ?nif_stub. %% @doc transaction implementation of delete operation to the transaction -spec transaction_delete(Transaction :: transaction_handle(), Key :: binary()) -> ok. transaction_delete(_Transaction, _Key) -> ?nif_stub. %% @doc like `transaction_delete/2' but apply the operation to a column family -spec transaction_delete(Transaction :: transaction_handle(), ColumnFamily :: cf_handle(), Key :: binary()) -> ok. transaction_delete(_Transaction, _ColumnFamily, _Key) -> ?nif_stub. %% @doc Return a iterator over the contents of the database and %% uncommited writes and deletes in the current transaction. %% The result of iterator() is initially invalid (caller must %% call iterator_move function on the iterator before using it). -spec transaction_iterator(TransactionHandle, ReadOpts) -> Res when TransactionHandle::transaction_handle(), ReadOpts::read_options(), Res :: {ok, itr_handle()} | {error, any()}. transaction_iterator(_TransactionHandle, _Ta_ReadOpts) -> ?nif_stub. %% @doc Return a iterator over the contents of the database and %% uncommited writes and deletes in the current transaction. %% The result of iterator() is initially invalid (caller must %% call iterator_move function on the iterator before using it). -spec transaction_iterator(TransactionHandle, CFHandle, ReadOpts) -> Res when TransactionHandle::transaction_handle(), CFHandle::cf_handle(), ReadOpts::read_options(), Res :: {ok, itr_handle()} | {error, any()}. transaction_iterator(_TransactionHandle, _CfHandle, _ReadOpts) -> ?nif_stub. %% @doc commit a transaction to disk atomically (?) -spec transaction_commit(Transaction :: transaction_handle()) -> ok | {error, term()}. transaction_commit(_Transaction) -> ?nif_stub. %% @doc rollback a transaction to disk atomically (?) -spec transaction_rollback(Transaction :: transaction_handle()) -> ok | {error, term()}. transaction_rollback(_Transaction) -> ?nif_stub. %% =================================================================== %% Pessimistic Transaction API %% @doc open a database with pessimistic transaction support. %% Pessimistic transactions acquire locks on keys when they are accessed, %% providing strict serializability at the cost of potential lock contention. -spec open_pessimistic_transaction_db(Name :: file:filename_all(), DbOpts :: db_options()) -> {ok, db_handle(), [cf_handle()]} | {error, any()}. open_pessimistic_transaction_db(_Name, _DbOpts) -> open_pessimistic_transaction_db(_Name, _DbOpts, [{"default", []}]). %% @doc open a database with pessimistic transaction support and column families. -spec open_pessimistic_transaction_db(Name :: file:filename_all(), DbOpts :: db_options(), CfDescriptors :: [cf_descriptor()]) -> {ok, db_handle(), [cf_handle()]} | {error, any()}. open_pessimistic_transaction_db(_Name, _DbOpts, _CFDescriptors) -> ?nif_stub. %% @doc create a new pessimistic transaction. %% Pessimistic transactions use row-level locking with deadlock detection. -spec pessimistic_transaction(TransactionDB :: db_handle(), WriteOptions :: write_options()) -> {ok, transaction_handle()} | {error, any()}. pessimistic_transaction(_TransactionDB, _WriteOptions) -> ?nif_stub. %% @doc create a new pessimistic transaction with transaction options. %% Transaction options include: %% {set_snapshot, boolean()} - acquire a snapshot at start %% {deadlock_detect, boolean()} - enable deadlock detection %% {lock_timeout, integer()} - lock wait timeout in ms -spec pessimistic_transaction(TransactionDB :: db_handle(), WriteOptions :: write_options(), TxnOptions :: list()) -> {ok, transaction_handle()} | {error, any()}. pessimistic_transaction(_TransactionDB, _WriteOptions, _TxnOptions) -> ?nif_stub. %% @doc release a pessimistic transaction. -spec release_pessimistic_transaction(TransactionHandle :: transaction_handle()) -> ok. release_pessimistic_transaction(_TransactionHandle) -> ?nif_stub. %% @doc put a key-value pair in the transaction. -spec pessimistic_transaction_put(Transaction :: transaction_handle(), Key :: binary(), Value :: binary()) -> ok | {error, busy} | {error, timed_out} | {error, any()}. pessimistic_transaction_put(_Transaction, _Key, _Value) -> ?nif_stub. %% @doc put a key-value pair in a column family within the transaction. -spec pessimistic_transaction_put(Transaction :: transaction_handle(), ColumnFamily :: cf_handle(), Key :: binary(), Value :: binary()) -> ok | {error, busy} | {error, timed_out} | {error, any()}. pessimistic_transaction_put(_Transaction, _ColumnFamily, _Key, _Value) -> ?nif_stub. %% @doc get a value from the transaction (read without acquiring lock). -spec pessimistic_transaction_get(Transaction :: transaction_handle(), Key :: binary(), Opts :: read_options()) -> {ok, binary()} | not_found | {error, any()}. pessimistic_transaction_get(_Transaction, _Key, _Opts) -> ?nif_stub. %% @doc get a value from a column family within the transaction. -spec pessimistic_transaction_get(Transaction :: transaction_handle(), ColumnFamily :: cf_handle(), Key :: binary(), Opts :: read_options()) -> {ok, binary()} | not_found | {error, any()}. pessimistic_transaction_get(_Transaction, _ColumnFamily, _Key, _Opts) -> ?nif_stub. %% @doc get a value and acquire an exclusive lock on the key. %% This is useful for read-modify-write patterns. -spec pessimistic_transaction_get_for_update(Transaction :: transaction_handle(), Key :: binary(), Opts :: read_options()) -> {ok, binary()} | not_found | {error, busy} | {error, timed_out} | {error, any()}. pessimistic_transaction_get_for_update(_Transaction, _Key, _Opts) -> ?nif_stub. %% @doc get a value from a column family and acquire an exclusive lock. -spec pessimistic_transaction_get_for_update(Transaction :: transaction_handle(), ColumnFamily :: cf_handle(), Key :: binary(), Opts :: read_options()) -> {ok, binary()} | not_found | {error, busy} | {error, timed_out} | {error, any()}. pessimistic_transaction_get_for_update(_Transaction, _ColumnFamily, _Key, _Opts) -> ?nif_stub. %% @doc batch get multiple values within a pessimistic transaction. %% Returns a list of results in the same order as the input keys. %% This does not acquire locks on the keys. -spec pessimistic_transaction_multi_get(Transaction :: transaction_handle(), Keys :: [binary()], Opts :: read_options()) -> [{ok, binary()} | not_found | {error, any()}]. pessimistic_transaction_multi_get(_Transaction, _Keys, _Opts) -> ?nif_stub. %% @doc like `pessimistic_transaction_multi_get/3' but apply to a column family -spec pessimistic_transaction_multi_get(Transaction :: transaction_handle(), ColumnFamily :: cf_handle(), Keys :: [binary()], Opts :: read_options()) -> [{ok, binary()} | not_found | {error, any()}]. pessimistic_transaction_multi_get(_Transaction, _ColumnFamily, _Keys, _Opts) -> ?nif_stub. %% @doc batch get multiple values and acquire exclusive locks on all keys. %% This is useful for read-modify-write patterns on multiple keys. -spec pessimistic_transaction_multi_get_for_update(Transaction :: transaction_handle(), Keys :: [binary()], Opts :: read_options()) -> [{ok, binary()} | not_found | {error, busy} | {error, timed_out} | {error, any()}]. pessimistic_transaction_multi_get_for_update(_Transaction, _Keys, _Opts) -> ?nif_stub. %% @doc like `pessimistic_transaction_multi_get_for_update/3' but apply to a column family -spec pessimistic_transaction_multi_get_for_update(Transaction :: transaction_handle(), ColumnFamily :: cf_handle(), Keys :: [binary()], Opts :: read_options()) -> [{ok, binary()} | not_found | {error, busy} | {error, timed_out} | {error, any()}]. pessimistic_transaction_multi_get_for_update(_Transaction, _ColumnFamily, _Keys, _Opts) -> ?nif_stub. %% @doc delete a key from the transaction. -spec pessimistic_transaction_delete(Transaction :: transaction_handle(), Key :: binary()) -> ok | {error, busy} | {error, timed_out} | {error, any()}. pessimistic_transaction_delete(_Transaction, _Key) -> ?nif_stub. %% @doc delete a key from a column family within the transaction. -spec pessimistic_transaction_delete(Transaction :: transaction_handle(), ColumnFamily :: cf_handle(), Key :: binary()) -> ok | {error, busy} | {error, timed_out} | {error, any()}. pessimistic_transaction_delete(_Transaction, _ColumnFamily, _Key) -> ?nif_stub. %% @doc create an iterator over the transaction's view of the database. -spec pessimistic_transaction_iterator(TransactionHandle :: transaction_handle(), ReadOpts :: read_options()) -> {ok, itr_handle()} | {error, any()}. pessimistic_transaction_iterator(_TransactionHandle, _ReadOpts) -> ?nif_stub. %% @doc create an iterator over a column family within the transaction. -spec pessimistic_transaction_iterator(TransactionHandle :: transaction_handle(), CFHandle :: cf_handle(), ReadOpts :: read_options()) -> {ok, itr_handle()} | {error, any()}. pessimistic_transaction_iterator(_TransactionHandle, _CfHandle, _ReadOpts) -> ?nif_stub. %% @doc commit the transaction atomically. -spec pessimistic_transaction_commit(Transaction :: transaction_handle()) -> ok | {error, busy} | {error, expired} | {error, any()}. pessimistic_transaction_commit(_Transaction) -> ?nif_stub. %% @doc rollback the transaction, discarding all changes. -spec pessimistic_transaction_rollback(Transaction :: transaction_handle()) -> ok | {error, any()}. pessimistic_transaction_rollback(_Transaction) -> ?nif_stub. %% @doc set a savepoint in a pessimistic transaction. %% Use {@link pessimistic_transaction_rollback_to_savepoint/1} to rollback to this point. -spec pessimistic_transaction_set_savepoint(Transaction :: transaction_handle()) -> ok. pessimistic_transaction_set_savepoint(_Transaction) -> ?nif_stub. %% @doc rollback a pessimistic transaction to the most recent savepoint. %% All operations since the last call to {@link pessimistic_transaction_set_savepoint/1} %% are undone and the savepoint is removed. -spec pessimistic_transaction_rollback_to_savepoint(Transaction :: transaction_handle()) -> ok | {error, any()}. pessimistic_transaction_rollback_to_savepoint(_Transaction) -> ?nif_stub. %% @doc pop the most recent savepoint without rolling back. %% The savepoint is simply discarded. -spec pessimistic_transaction_pop_savepoint(Transaction :: transaction_handle()) -> ok | {error, any()}. pessimistic_transaction_pop_savepoint(_Transaction) -> ?nif_stub. %% @doc get the unique ID of a pessimistic transaction. %% This ID can be used to identify the transaction in deadlock detection %% and waiting transaction lists. -spec pessimistic_transaction_get_id(Transaction :: transaction_handle()) -> {ok, non_neg_integer()}. pessimistic_transaction_get_id(_Transaction) -> ?nif_stub. %% @doc get information about transactions this transaction is waiting on. %% Returns a map with: %% - `column_family_id': The column family ID of the key being waited on %% - `key': The key being waited on (binary) %% - `waiting_txns': List of transaction IDs that hold locks this transaction needs %% %% If the transaction is not currently waiting, returns an empty waiting_txns list. -spec pessimistic_transaction_get_waiting_txns(Transaction :: transaction_handle()) -> {ok, #{column_family_id := non_neg_integer(), key := binary(), waiting_txns := [non_neg_integer()]}}. pessimistic_transaction_get_waiting_txns(_Transaction) -> ?nif_stub. %% =================================================================== %% Backup Engine API %% @doc open a new backup engine for creating new backups. -spec open_backup_engine(Path :: string()) -> {ok, backup_engine()} | {error, term()}. open_backup_engine(_Path) -> ?nif_stub. %% @doc stop and close the backup engine %% note: experimental for testing only -spec close_backup_engine(backup_engine()) -> ok. close_backup_engine(_BackupEngine) -> ?nif_stub. %% @doc Will delete all the files we don't need anymore %% It will do the full scan of the files/ directory and delete all the %% files that are not referenced. -spec gc_backup_engine(backup_engine()) -> ok. gc_backup_engine(_BackupEngine) -> ?nif_stub. %% %% @doc Call this from another process if you want to stop the backup %% that is currently happening. It will return immediatelly, will %% not wait for the backup to stop. %% The backup will stop ASAP and the call to CreateNewBackup will %% return Status::Incomplete(). It will not clean up after itself, but %% the state will remain consistent. The state will be cleaned up %% next time you create BackupableDB or RestoreBackupableDB. -spec stop_backup(backup_engine()) -> ok. stop_backup(_BackupEngine) -> ?nif_stub. %% @doc Captures the state of the database in the latest backup -spec create_new_backup(BackupEngine :: backup_engine(), Db :: db_handle()) -> ok | {error, term()}. create_new_backup(_BackupEngine, _DbHandle) -> ?nif_stub. %% @doc Returns info about backups in backup_info -spec get_backup_info(backup_engine()) -> [backup_info()]. get_backup_info(_BackupEngine) -> ?nif_stub. %% @doc checks that each file exists and that the size of the file matches %% our expectations. it does not check file checksum. -spec verify_backup(BackupEngine :: backup_engine(), BackupId :: non_neg_integer()) -> ok | {error, any()}. verify_backup(_BackupEngine, _BackupId) -> ?nif_stub. %% @doc deletes a specific backup -spec delete_backup(BackupEngine :: backup_engine(), BackupId :: non_neg_integer()) -> ok | {error, any()}. delete_backup(_BackupEngine, _BackupId) -> ?nif_stub. %% @doc deletes old backups, keeping latest num_backups_to_keep alive -spec purge_old_backup(BackupEngine :: backup_engine(), NumBackupToKeep :: non_neg_integer()) -> ok | {error, any()}. purge_old_backup(_BackupEngine, _NumBackupToKeep) -> ?nif_stub. %% @doc restore from backup with backup_id -spec restore_db_from_backup(BackupEngine, BackupId, DbDir) -> Result when BackupEngine :: backup_engine(), BackupId :: non_neg_integer(), DbDir :: string(), Result :: ok | {error, any()}. restore_db_from_backup(_BackupEngine, _BackupId, _DbDir) -> ?nif_stub. %% @doc restore from backup with backup_id -spec restore_db_from_backup(BackupEngine, BackupId, DbDir, WalDir) -> Result when BackupEngine :: backup_engine(), BackupId :: non_neg_integer(), DbDir :: string(), WalDir :: string(), Result :: ok | {error, any()}. restore_db_from_backup(_BackupEngine, _BackupId, _DbDir, _WalDir) -> ?nif_stub. %% @doc restore from the latest backup -spec restore_db_from_latest_backup(BackupEngine, DbDir) -> Result when BackupEngine :: backup_engine(), DbDir :: string(), Result :: ok | {error, any()}. restore_db_from_latest_backup(_BackupEngine, _DbDir) -> ?nif_stub. %% @doc restore from the latest backup -spec restore_db_from_latest_backup(BackupEngine, DbDir, WalDir) -> Result when BackupEngine :: backup_engine(), DbDir :: string(), WalDir :: string(), Result :: ok | {error, any()}. restore_db_from_latest_backup(_BackupEngine, _DbDir, _WalDir) -> ?nif_stub. %% =================================================================== %% Cache API %% @doc // Create a new cache. %M Whi the type `lru' it create a cache with a fixed size capacity. The cache is sharded %% to 2^num_shard_bits shards, by hash of the key. The total capacity %% is divided and evenly assigned to each shard. With the type `clock`, it creates a %% cache based on CLOCK algorithm with better concurrent performance in some cases. See util/clock_cache.cc for %% more detail. -spec new_cache(Type :: cache_type(), Capacity :: non_neg_integer()) -> {ok, cache_handle()}. new_cache(_Type, _Capacity) -> ?nif_stub. %% @doc return informations of a cache as a list of tuples. %% * `{capacity, integer >=0}' %% the maximum configured capacity of the cache. %% * `{strict_capacity, boolean}' %% the flag whether to return error on insertion when cache reaches its full capacity. %% * `{usage, integer >=0}' %% the memory size for the entries residing in the cache. %% * `{pinned_usage, integer >= 0}' %% the memory size for the entries in use by the system -spec cache_info(Cache) -> InfoList when Cache :: cache_handle(), InfoList :: [InfoTuple], InfoTuple :: {capacity, non_neg_integer()} | {strict_capacity, boolean()} | {usage, non_neg_integer()} | {pinned_usage, non_neg_integer()}.   cache_info(_Cache) -> ?nif_stub. %% @doc return the information associated with Item for cache Cache -spec cache_info(Cache, Item) -> Value when Cache :: cache_handle(), Item :: capacity | strict_capacity | usage | pinned_usage, Value :: term(). cache_info(_Cache, _Item) -> ?nif_stub. %% @doc sets the maximum configured capacity of the cache. When the new %% capacity is less than the old capacity and the existing usage is %% greater than new capacity, the implementation will do its best job to %% purge the released entries from the cache in order to lower the usage -spec set_capacity(Cache :: cache_handle(), Capacity :: non_neg_integer()) -> ok. set_capacity(_Cache, _Capacity) -> ?nif_stub. %% @doc sets strict_capacity_limit flag of the cache. If the flag is set %% to true, insert to cache will fail if no enough capacity can be free. -spec set_strict_capacity_limit(Cache :: cache_handle(), StrictCapacityLimit :: boolean()) -> ok. set_strict_capacity_limit(_Cache, _StrictCapacityLimit) -> ?nif_stub. %% @doc release the cache release_cache(_Cache) -> ?nif_stub. %% =================================================================== %% Limiter functions %% @doc create new Limiter new_rate_limiter(_RateBytesPerSec, _Auto) -> ?nif_stub. %% @doc release the limiter release_rate_limiter(_Limiter) -> ?nif_stub. %% =================================================================== %% Env API %% @doc return a default db environment -spec new_env() -> {ok, env_handle()}. new_env() -> new_env(default). %% @doc return a db environment %% %% `default' returns the shared process-wide environment. `memenv' returns an %% in-memory environment. %% %% `{encrypted, Key}' (or `#{encrypted => Key}') returns an environment that %% transparently encrypts all on-disk data with AES-256-CTR. `Key' must be a %% 32-byte binary. Pass the returned handle as `{env, Env}' in the open %% options. Wrong-key detection is checksum-based, not authenticated: reading %% with the wrong key yields garbage that RocksDB block checksums reject as a %% corruption error. -spec new_env(EnvType :: env_type()) -> {ok, env_handle()}. new_env(_EnvType) -> ?nif_stub. %% @doc set background threads of an environment -spec set_env_background_threads(Env :: env_handle(), N :: non_neg_integer()) -> ok. set_env_background_threads(_Env, _N) -> ?nif_stub. %% @doc set background threads of low and high prioriry threads pool of an environment %% Flush threads are in the HIGH priority pool, while compaction threads are in the %% LOW priority pool. To increase the number of threads in each pool call: -spec set_env_background_threads(Env :: env_handle(), N :: non_neg_integer(), Priority :: env_priority()) -> ok. set_env_background_threads(_Env, _N, _PRIORITY) -> ?nif_stub. %% @doc destroy an environment -spec destroy_env(Env :: env_handle()) -> ok. destroy_env(_Env) -> ?nif_stub. %% @doc set background threads of a database -spec set_db_background_threads(DB :: db_handle(), N :: non_neg_integer()) -> ok. set_db_background_threads(_Db, _N) -> ?nif_stub. %% @doc set database background threads of low and high prioriry threads pool of an environment %% Flush threads are in the HIGH priority pool, while compaction threads are in the %% LOW priority pool. To increase the number of threads in each pool call: -spec set_db_background_threads(DB :: db_handle(), N :: non_neg_integer(), Priority :: env_priority()) -> ok. set_db_background_threads(_Db, _N, _PRIORITY) -> ?nif_stub. %% =================================================================== %% SstFileManager functions %% @doc create new SstFileManager with the default options: %% RateBytesPerSec = 0, MaxTrashDbRatio = 0.25, BytesMaxDeleteChunk = 64 * 1024 * 1024. -spec new_sst_file_manager(env_handle()) -> {ok, sst_file_manager()} | {error, any()}. new_sst_file_manager(Env) -> ?MODULE:new_sst_file_manager(Env, []). %% @doc create new SstFileManager that can be shared among multiple RocksDB %% instances to track SST file and control there deletion rate. %% %% * `Env' is an environment resource created using `rocksdb:new_env/{0,1}'. %% * `delete_rate_bytes_per_sec': How many bytes should be deleted per second, If %% this value is set to 1024 (1 Kb / sec) and we deleted a file of size 4 Kb %% in 1 second, we will wait for another 3 seconds before we delete other %% files, Set to 0 to disable deletion rate limiting. %% * `max_trash_db_ratio': If the trash size constitutes for more than this %% fraction of the total DB size we will start deleting new files passed to %% DeleteScheduler immediately %% * `bytes_max_delete_chunk': if a file to delete is larger than delete %% chunk, ftruncate the file by this size each time, rather than dropping the %% whole file. 0 means to always delete the whole file. If the file has more %% than one linked names, the file will be deleted as a whole. Either way, %% `delete_rate_bytes_per_sec' will be appreciated. NOTE that with this option, %% files already renamed as a trash may be partial, so users should not %% directly recover them without checking. -spec new_sst_file_manager(Env, OptionsList) -> Result when Env :: env_handle(), OptionsList :: [OptionTuple], OptionTuple :: {delete_rate_bytes_per_sec, non_neg_integer()} | {max_trash_db_ratio, float()} | {bytes_max_delete_chunk, non_neg_integer()}, Result :: {ok, sst_file_manager()} | {error, any()}. new_sst_file_manager(_Env, _OptionsList) -> ?nif_stub. %% @doc release the SstFileManager -spec release_sst_file_manager(sst_file_manager()) -> ok. release_sst_file_manager(_SstFileManager) -> ?nif_stub. %% @doc set certains flags for the SST file manager %% * `max_allowed_space_usage': Update the maximum allowed space that should be used by RocksDB, if %% the total size of the SST files exceeds MaxAllowedSpace, writes to %% RocksDB will fail. %% %% Setting MaxAllowedSpace to 0 will disable this feature; maximum allowed %% pace will be infinite (Default value). %% * `compaction_buffer_size': Set the amount of buffer room each compaction should be able to leave. %% In other words, at its maximum disk space consumption, the compaction %% should still leave compaction_buffer_size available on the disk so that %% other background functions may continue, such as logging and flushing. %% * `delete_rate_bytes_per_sec': Update the delete rate limit in bytes per second. %% zero means disable delete rate limiting and delete files immediately %% * `max_trash_db_ratio': Update trash/DB size ratio where new files will be deleted immediately (float) -spec sst_file_manager_flag(SstFileManager, Flag, Value) -> Result when SstFileManager :: sst_file_manager(), Flag :: max_allowed_space_usage | compaction_buffer_size | delete_rate_bytes_per_sec | max_trash_db_ratio, Value :: non_neg_integer() | float(), Result :: ok. sst_file_manager_flag(_SstFileManager, _Flag, _Val) -> ?nif_stub. %% @doc return informations of a Sst File Manager as a list of tuples. %% %% * `{total_size, Int>0}': total size of all tracked files %% * `{delete_rate_bytes_per_sec, Int > 0}': delete rate limit in bytes per second %% * `{max_trash_db_ratio, Float>0}': trash/DB size ratio where new files will be deleted immediately %% * `{total_trash_size, Int > 0}': total size of trash files %% * `{is_max_allowed_space_reached, Boolean}' true if the total size of SST files exceeded the maximum allowed space usage %% * `{max_allowed_space_reached_including_compactions, Boolean}': true if the total size of SST files as well as %% estimated size of ongoing compactions exceeds the maximums allowed space usage -spec sst_file_manager_info(SstFileManager) -> InfoList when SstFileManager :: sst_file_manager(), InfoList :: [InfoTuple], InfoTuple :: {total_size, non_neg_integer()} | {delete_rate_bytes_per_sec, non_neg_integer()} | {max_trash_db_ratio, float()} | {total_trash_size, non_neg_integer()} | {is_max_allowed_space_reached, boolean()} | {max_allowed_space_reached_including_compactions, boolean()}. sst_file_manager_info(_SstFileManager) -> ?nif_stub. %% @doc return the information associated with Item for an SST File Manager SstFileManager -spec sst_file_manager_info(SstFileManager, Item) -> Value when SstFileManager :: sst_file_manager(), Item :: total_size | delete_rate_bytes_per_sec | max_trash_db_ratio | total_trash_size | is_max_allowed_space_reached | max_allowed_space_reached_including_compactions, Value :: term(). sst_file_manager_info(_SstFileManager, _Item) -> ?nif_stub. %% @doc Returns a list of all SST files being tracked and their sizes. %% Each element is a tuple of {FilePath, Size} where FilePath is a binary %% and Size is the file size in bytes. -spec sst_file_manager_tracked_files(SstFileManager) -> [{binary(), non_neg_integer()}] when SstFileManager :: sst_file_manager(). sst_file_manager_tracked_files(_SstFileManager) -> ?nif_stub. %% =================================================================== %% SstFileWriter functions %% @doc Open a new SST file for writing. %% %% Creates an SST file writer that can be used to build SST files externally. %% Keys must be added in sorted order (according to the comparator). %% Once finished, the SST file can be ingested into the database using %% `ingest_external_file/3,4'. %% %% Options are the same as database options (compression, block_size, etc.) -spec sst_file_writer_open(Options, FilePath) -> Result when Options :: db_options() | cf_options(), FilePath :: file:filename_all(), Result :: {ok, sst_file_writer()} | {error, any()}. sst_file_writer_open(_Options, _FilePath) -> ?nif_stub. %% @doc Add a key-value pair to the SST file. %% %% IMPORTANT: Keys must be added in sorted order according to the comparator. %% Adding a key that is not greater than the previous key will result in an error. -spec sst_file_writer_put(SstFileWriter, Key, Value) -> Result when SstFileWriter :: sst_file_writer(), Key :: binary(), Value :: binary(), Result :: ok | {error, any()}. sst_file_writer_put(_SstFileWriter, _Key, _Value) -> ?nif_stub. %% @doc Add a wide-column entity to the SST file. %% %% IMPORTANT: Keys must be added in sorted order according to the comparator. -spec sst_file_writer_put_entity(SstFileWriter, Key, Columns) -> Result when SstFileWriter :: sst_file_writer(), Key :: binary(), Columns :: [{ColumnName :: binary(), ColumnValue :: binary()}], Result :: ok | {error, any()}. sst_file_writer_put_entity(_SstFileWriter, _Key, _Columns) -> ?nif_stub. %% @doc Add a merge operation to the SST file. %% %% IMPORTANT: Keys must be added in sorted order according to the comparator. -spec sst_file_writer_merge(SstFileWriter, Key, Value) -> Result when SstFileWriter :: sst_file_writer(), Key :: binary(), Value :: binary(), Result :: ok | {error, any()}. sst_file_writer_merge(_SstFileWriter, _Key, _Value) -> ?nif_stub. %% @doc Add a delete tombstone to the SST file. %% %% IMPORTANT: Keys must be added in sorted order according to the comparator. -spec sst_file_writer_delete(SstFileWriter, Key) -> Result when SstFileWriter :: sst_file_writer(), Key :: binary(), Result :: ok | {error, any()}. sst_file_writer_delete(_SstFileWriter, _Key) -> ?nif_stub. %% @doc Add a range delete tombstone to the SST file. %% %% Deletes all keys in the range [BeginKey, EndKey). %% Range deletions can be added in any order. -spec sst_file_writer_delete_range(SstFileWriter, BeginKey, EndKey) -> Result when SstFileWriter :: sst_file_writer(), BeginKey :: binary(), EndKey :: binary(), Result :: ok | {error, any()}. sst_file_writer_delete_range(_SstFileWriter, _BeginKey, _EndKey) -> ?nif_stub. %% @doc Finalize writing to the SST file and close it. %% %% After this call, the SST file is ready to be ingested into the database. -spec sst_file_writer_finish(SstFileWriter) -> Result when SstFileWriter :: sst_file_writer(), Result :: ok | {error, any()}. sst_file_writer_finish(_SstFileWriter) -> ?nif_stub. %% @doc Finalize writing to the SST file and return file info. %% %% Returns a map with file metadata including: %% - file_path: Path to the created SST file %% - smallest_key: Smallest key in the file %% - largest_key: Largest key in the file %% - file_size: Size of the file in bytes %% - num_entries: Number of entries in the file %% - sequence_number: Sequence number assigned to keys -spec sst_file_writer_finish(SstFileWriter, with_file_info) -> Result when SstFileWriter :: sst_file_writer(), Result :: {ok, sst_file_info()} | {error, any()}. sst_file_writer_finish(_SstFileWriter, with_file_info) -> ?nif_stub. %% @doc Get the current file size during writing. -spec sst_file_writer_file_size(SstFileWriter) -> Size when SstFileWriter :: sst_file_writer(), Size :: non_neg_integer(). sst_file_writer_file_size(_SstFileWriter) -> ?nif_stub. %% @doc Release the SST file writer resource. %% %% Note: If finish/1,2 was not called, the partially written file may remain. -spec release_sst_file_writer(SstFileWriter) -> ok when SstFileWriter :: sst_file_writer(). release_sst_file_writer(_SstFileWriter) -> ?nif_stub. %% =================================================================== %% Ingest External File functions %% =================================================================== %% @doc Ingest external SST files into the database. %% %% This function loads one or more external SST files created by sst_file_writer %% into the database. The files are ingested at the appropriate level in the %% LSM tree based on their key ranges. %% %% Options: %% - move_files: Move files instead of copying (default: false) %% - failed_move_fall_back_to_copy: Fall back to copy if move fails (default: true) %% - snapshot_consistency: Check snapshot consistency (default: true) %% - allow_global_seqno: Allow assigning global sequence numbers (default: true) %% - allow_blocking_flush: Allow blocking flush (default: true) %% - ingest_behind: Ingest files to bottommost level (default: false) %% - verify_checksums_before_ingest: Verify checksums before ingest (default: true) %% - verify_checksums_readahead_size: Readahead size for checksum verification (default: 0) %% - verify_file_checksum: Verify file checksum if present (default: true) %% - fail_if_not_bottommost_level: Fail if files don't go to bottommost level (default: false) %% - allow_db_generated_files: Allow files generated by this DB (default: false) %% - fill_cache: Fill block cache on ingest (default: true) -spec ingest_external_file(DbHandle, Files, Options) -> Result when DbHandle :: db_handle(), Files :: [file:filename_all()], Options :: [ingest_external_file_option()], Result :: ok | {error, any()}. ingest_external_file(_DbHandle, _Files, _Options) -> ?nif_stub. %% @doc Ingest external SST files into a specific column family. %% %% Same as ingest_external_file/3 but allows specifying a column family. -spec ingest_external_file(DbHandle, CfHandle, Files, Options) -> Result when DbHandle :: db_handle(), CfHandle :: cf_handle(), Files :: [file:filename_all()], Options :: [ingest_external_file_option()], Result :: ok | {error, any()}. ingest_external_file(_DbHandle, _CfHandle, _Files, _Options) -> ?nif_stub. %% =================================================================== %% SstFileReader functions %% =================================================================== %% @doc Open an SST file for reading. %% %% Creates an SST file reader that allows inspecting the contents of an SST file %% without loading it into a database. This is useful for offline verification, %% debugging, or extracting data from SST files. %% %% Options are the same as database options (compression, block_size, etc.) -spec sst_file_reader_open(Options, FilePath) -> Result when Options :: db_options() | cf_options(), FilePath :: file:filename_all(), Result :: {ok, sst_file_reader()} | {error, any()}. sst_file_reader_open(_Options, _FilePath) -> ?nif_stub. %% @doc Create an iterator for reading the contents of the SST file. %% %% Returns an iterator that can be used to scan through all key-value pairs %% in the SST file. The iterator supports the same movement operations as %% regular database iterators. %% %% Options: %% - verify_checksums: Verify block checksums during iteration (default: false) %% - fill_cache: Fill block cache during iteration (default: true) -spec sst_file_reader_iterator(SstFileReader, Options) -> Result when SstFileReader :: sst_file_reader(), Options :: read_options(), Result :: {ok, sst_file_reader_itr()} | {error, any()}. sst_file_reader_iterator(_SstFileReader, _Options) -> ?nif_stub. %% @doc Get the table properties of the SST file. %% %% Returns a map containing metadata about the SST file including: %% - data_size: Size of data blocks in bytes %% - index_size: Size of index blocks in bytes %% - filter_size: Size of filter block (if any) %% - num_entries: Number of key-value entries %% - num_deletions: Number of delete tombstones %% - compression_name: Name of compression algorithm used %% - creation_time: Unix timestamp when file was created %% And many more properties. -spec sst_file_reader_get_table_properties(SstFileReader) -> Result when SstFileReader :: sst_file_reader(), Result :: {ok, table_properties()} | {error, any()}. sst_file_reader_get_table_properties(_SstFileReader) -> ?nif_stub. %% @doc Verify the checksums of all blocks in the SST file. %% %% Reads through all data blocks and verifies their checksums. %% Returns ok if all checksums are valid, or an error if any are corrupted. -spec sst_file_reader_verify_checksum(SstFileReader) -> Result when SstFileReader :: sst_file_reader(), Result :: ok | {error, any()}. sst_file_reader_verify_checksum(_SstFileReader) -> ?nif_stub. %% @doc Verify the checksums of all blocks in the SST file. %% %% Same as verify_checksum/1 but with read options. -spec sst_file_reader_verify_checksum(SstFileReader, Options) -> Result when SstFileReader :: sst_file_reader(), Options :: read_options(), Result :: ok | {error, any()}. sst_file_reader_verify_checksum(_SstFileReader, _Options) -> ?nif_stub. %% @doc Move the SST file reader iterator to a new position. %% %% Supported actions: %% - first: Move to the first entry %% - last: Move to the last entry %% - next: Move to the next entry %% - prev: Move to the previous entry %% - {seek, Key}: Seek to the entry at or after Key %% - {seek_for_prev, Key}: Seek to the entry at or before Key %% %% Returns {ok, Key, Value} if the iterator is valid, or {error, Reason} if not. -spec sst_file_reader_iterator_move(Iterator, Action) -> Result when Iterator :: sst_file_reader_itr(), Action :: first | last | next | prev | {seek, binary()} | {seek_for_prev, binary()}, Result :: {ok, Key :: binary(), Value :: binary()} | {error, any()}. sst_file_reader_iterator_move(_Iterator, _Action) -> ?nif_stub. %% @doc Close an SST file reader iterator. %% %% Releases resources associated with the iterator. -spec sst_file_reader_iterator_close(Iterator) -> ok when Iterator :: sst_file_reader_itr(). sst_file_reader_iterator_close(_Iterator) -> ?nif_stub. %% @doc Release the SST file reader resource. %% %% Closes the SST file and releases all associated resources. %% Any iterators created from this reader will become invalid. -spec release_sst_file_reader(SstFileReader) -> ok when SstFileReader :: sst_file_reader(). release_sst_file_reader(_SstFileReader) -> ?nif_stub. %% =================================================================== %% WriteBufferManager functions %% @doc create a new WriteBufferManager. -spec new_write_buffer_manager(BufferSize::non_neg_integer()) -> {ok, write_buffer_manager()}. new_write_buffer_manager(_BufferSize) -> ?nif_stub. %% @doc create a new WriteBufferManager. a WriteBufferManager is for managing memory %% allocation for one or more MemTables. %% %% The memory usage of memtable will report to this object. The same object %% can be passed into multiple DBs and it will track the sum of size of all %% the DBs. If the total size of all live memtables of all the DBs exceeds %% a limit, a flush will be triggered in the next DB to which the next write %% is issued. %% %% If the object is only passed to on DB, the behavior is the same as %% db_write_buffer_size. When write_buffer_manager is set, the value set will %% override db_write_buffer_size. -spec new_write_buffer_manager(BufferSize::non_neg_integer(), Cache::cache_handle()) -> {ok, write_buffer_manager()}. new_write_buffer_manager(_BufferSize, _Cache) -> ?nif_stub. -spec release_write_buffer_manager(write_buffer_manager()) -> ok. release_write_buffer_manager(_WriteBufferManager) -> ?nif_stub. %% @doc return informations of a Write Buffer Manager as a list of tuples. -spec write_buffer_manager_info(WriteBufferManager) -> InfoList when WriteBufferManager :: write_buffer_manager(), InfoList :: [InfoTuple], InfoTuple :: {memory_usage, non_neg_integer()} | {mutable_memtable_memory_usage, non_neg_integer()} | {buffer_size, non_neg_integer()} | {enabled, boolean()}. write_buffer_manager_info(_WriteBufferManager) -> ?nif_stub. %% @doc return the information associated with Item for a Write Buffer Manager. -spec write_buffer_manager_info(WriteBufferManager, Item) -> Value when WriteBufferManager :: write_buffer_manager(), Item :: memory_usage | mutable_memtable_memory_usage | buffer_size | enabled, Value :: term(). write_buffer_manager_info(_WriteBufferManager, _Item) -> ?nif_stub. %% =================================================================== %% Statistics API -spec new_statistics() -> {ok, statistics_handle()}. new_statistics() -> ?nif_stub. -spec set_stats_level(statistics_handle(), stats_level()) -> ok. set_stats_level(_StatisticsHandle, _StatsLevel) -> ?nif_stub. -spec statistics_info(Statistics) -> InfoList when Statistics :: statistics_handle(), InfoList :: [InfoTuple], InfoTuple :: {stats_level, stats_level()}. statistics_info(_Statistics) -> ?nif_stub. %% @doc Get the count for a specific statistics ticker. %% Returns the count for tickers such as blob_db_num_put, block_cache_hit, %% number_keys_written, compact_read_bytes, etc. -spec statistics_ticker(statistics_handle(), blob_db_ticker() | compaction_ticker() | db_operation_ticker() | block_cache_ticker() | memtable_stall_ticker() | transaction_ticker()) -> {ok, non_neg_integer()}. statistics_ticker(_Statistics, _Ticker) -> ?nif_stub. %% @doc Get histogram data for a specific statistics histogram. %% Returns histogram information including median, percentiles, average, etc. %% For integrated BlobDB, relevant histograms are blob_db_blob_file_write_micros, %% blob_db_blob_file_read_micros, blob_db_compression_micros, etc. -spec statistics_histogram(statistics_handle(), blob_db_histogram() | core_operation_histogram() | io_sync_histogram() | transaction_histogram()) -> {ok, histogram_info()}. statistics_histogram(_Statistics, _Histogram) -> ?nif_stub. %% @doc release the Statistics Handle -spec release_statistics(statistics_handle()) -> ok. release_statistics(_Statistics) -> ?nif_stub. %% =================================================================== %% Compaction Filter %% =================================================================== %% @doc Reply to a compaction filter callback request. %% This function is called by the Erlang handler process when it has %% processed a batch of keys sent by the compaction filter. %% %% BatchRef is the reference received in the {compaction_filter, BatchRef, Keys} message. %% Decisions is a list of filter_decision() values corresponding to each key: %% - keep: Keep the key-value pair %% - remove: Delete the key-value pair %% - {change_value, NewBinary}: Keep the key but replace the value %% %% Example handler: %% ``` %% filter_handler() -> %% receive %% {compaction_filter, BatchRef, Keys} -> %% Decisions = [decide(K, V) || {_Level, K, V} <- Keys], %% rocksdb:compaction_filter_reply(BatchRef, Decisions), %% filter_handler() %% end. %% %% decide(<<"tmp_", _/binary>>, _Value) -> remove; %% decide(_Key, <<>>) -> remove; %% decide(_Key, Value) when byte_size(Value) > 1000 -> %% {change_value, binary:part(Value, 0, 1000)}; %% decide(_, _) -> keep. %% ''' -spec compaction_filter_reply(reference(), [filter_decision()]) -> ok. compaction_filter_reply(_BatchRef, _Decisions) -> ?nif_stub. %% =================================================================== %% Posting List API %% =================================================================== %% %% Posting lists are used for inverted indexes, search engines, and document %% tagging systems. Each posting list is a binary containing a sequence of %% entries with format: <> %% %% Where Flag is 0 for normal entries and non-zero for tombstones. %% %% Use with {merge_operator, posting_list_merge_operator} and optionally %% {compaction_filter, #{rules => [{posting_list_tombstones}]}} to clean up %% tombstones during compaction. %% =================================================================== -type posting_entry() :: {Key :: binary(), IsTombstone :: boolean()}. %% @doc Decode a posting list binary to a list of entries. %% Returns all entries including tombstones, in order of appearance. -spec posting_list_decode(binary()) -> [posting_entry()]. posting_list_decode(<>) -> IsTombstone = Flag =/= 0, [{Key, IsTombstone} | posting_list_decode(Rest)]; posting_list_decode(<<>>) -> []. %% @doc Fold over all entries in a posting list (including tombstones). -spec posting_list_fold(Fun, Acc, binary()) -> Acc when Fun :: fun((Key :: binary(), IsTombstone :: boolean(), Acc) -> Acc), Acc :: term(). posting_list_fold(Fun, Acc, Bin) -> lists:foldl(fun({K, T}, A) -> Fun(K, T, A) end, Acc, posting_list_decode(Bin)). %% @doc Get list of active keys (deduplicated, tombstones filtered out). %% This is a NIF function for efficiency. -spec posting_list_keys(binary()) -> [binary()]. posting_list_keys(_Bin) -> ?nif_stub. %% @doc Check if a key is active (exists and not tombstoned). %% This is a NIF function for efficiency. -spec posting_list_contains(binary(), binary()) -> boolean(). posting_list_contains(_Bin, _Key) -> ?nif_stub. %% @doc Find a key in the posting list. %% Returns {ok, IsTombstone} if found, or not_found if not present. %% This is a NIF function for efficiency. -spec posting_list_find(binary(), binary()) -> {ok, boolean()} | not_found. posting_list_find(_Bin, _Key) -> ?nif_stub. %% @doc Count the number of active keys (not tombstoned). %% This is a NIF function for efficiency. -spec posting_list_count(binary()) -> non_neg_integer(). posting_list_count(_Bin) -> ?nif_stub. %% @doc Convert posting list to a map of key => active | tombstone. %% This is a NIF function for efficiency. -spec posting_list_to_map(binary()) -> #{binary() => active | tombstone}. posting_list_to_map(_Bin) -> ?nif_stub. %% @doc Get the format version of a posting list binary. %% Returns 1 for V1 (legacy) format, 2 for V2 (sorted with roaring bitmap). -spec posting_list_version(binary()) -> 1 | 2. posting_list_version(_Bin) -> ?nif_stub. %% @doc Compute intersection of two posting lists. %% Returns a new V2 posting list containing only keys present in both inputs. -spec posting_list_intersection(binary(), binary()) -> binary(). posting_list_intersection(_Bin1, _Bin2) -> ?nif_stub. %% @doc Compute union of two posting lists. %% Returns a new V2 posting list containing all keys from both inputs. -spec posting_list_union(binary(), binary()) -> binary(). posting_list_union(_Bin1, _Bin2) -> ?nif_stub. %% @doc Compute difference of two posting lists (Bin1 - Bin2). %% Returns keys that are in Bin1 but not in Bin2. -spec posting_list_difference(binary(), binary()) -> binary(). posting_list_difference(_Bin1, _Bin2) -> ?nif_stub. %% @doc Fast intersection count using roaring bitmap when available. %% For V2 posting lists, uses bitmap cardinality for O(1) performance. -spec posting_list_intersection_count(binary(), binary()) -> non_neg_integer(). posting_list_intersection_count(_Bin1, _Bin2) -> ?nif_stub. %% @doc Fast bitmap-based contains check. %% Uses hash lookup for V2 format - may have rare false positives. %% Use posting_list_contains/2 for exact checks. -spec posting_list_bitmap_contains(binary(), binary()) -> boolean(). posting_list_bitmap_contains(_Bin, _Key) -> ?nif_stub. %% @doc Intersect multiple posting lists efficiently. %% Processes lists from smallest to largest for optimal performance. -spec posting_list_intersect_all([binary()]) -> binary(). posting_list_intersect_all([]) -> %% Empty intersection - return empty V2 posting list <<2, 0, 0, 0, 0, 0, 0, 0, 0>>; posting_list_intersect_all([Single]) -> Single; posting_list_intersect_all(Lists) -> %% Sort by size (smallest first) for optimal intersection Sorted = lists:sort(fun(A, B) -> byte_size(A) =< byte_size(B) end, Lists), lists:foldl(fun posting_list_intersection/2, hd(Sorted), tl(Sorted)). %% @doc Open/parse posting list binary into a resource for fast repeated lookups. %% Use this when you need to perform multiple contains checks on the same posting list. %% The resource holds parsed keys and bitmap for fast lookups. %% @end -spec postings_open(binary()) -> {ok, reference()} | {error, term()}. postings_open(_Bin) -> ?nif_stub. %% @doc Check if key exists in postings resource (exact match). %% O(log n) lookup using sorted set. -spec postings_contains(reference(), binary()) -> boolean(). postings_contains(_Postings, _Key) -> ?nif_stub. %% @doc Check if key exists in postings resource (bitmap hash lookup). %% O(1) lookup but may have rare false positives due to hash collisions. -spec postings_bitmap_contains(reference(), binary()) -> boolean(). postings_bitmap_contains(_Postings, _Key) -> ?nif_stub. %% @doc Get count of keys in postings resource. -spec postings_count(reference()) -> non_neg_integer(). postings_count(_Postings) -> ?nif_stub. %% @doc Get all keys from postings resource (sorted). -spec postings_keys(reference()) -> [binary()]. postings_keys(_Postings) -> ?nif_stub. %% @doc Intersect two postings (AND). %% Accepts binary or resource, returns resource. -spec postings_intersection(binary() | reference(), binary() | reference()) -> {ok, reference()} | {error, term()}. postings_intersection(A, B) -> BinA = to_posting_binary(A), BinB = to_posting_binary(B), postings_open(posting_list_intersection(BinA, BinB)). %% @doc Union two postings (OR). %% Accepts binary or resource, returns resource. -spec postings_union(binary() | reference(), binary() | reference()) -> {ok, reference()} | {error, term()}. postings_union(A, B) -> BinA = to_posting_binary(A), BinB = to_posting_binary(B), postings_open(posting_list_union(BinA, BinB)). %% @doc Difference of two postings (A - B). %% Accepts binary or resource, returns resource. -spec postings_difference(binary() | reference(), binary() | reference()) -> {ok, reference()} | {error, term()}. postings_difference(A, B) -> BinA = to_posting_binary(A), BinB = to_posting_binary(B), postings_open(posting_list_difference(BinA, BinB)). %% @doc Fast intersection count using bitmap. -spec postings_intersection_count(binary() | reference(), binary() | reference()) -> non_neg_integer(). postings_intersection_count(A, B) -> BinA = to_posting_binary(A), BinB = to_posting_binary(B), posting_list_intersection_count(BinA, BinB). %% @doc Intersect multiple postings efficiently. -spec postings_intersect_all([binary() | reference()]) -> {ok, reference()} | {error, term()}. postings_intersect_all([]) -> postings_open(<<2, 0, 0, 0, 0, 0, 0, 0, 0>>); postings_intersect_all([Single]) when is_reference(Single) -> {ok, Single}; postings_intersect_all([Single]) -> postings_open(Single); postings_intersect_all(List) -> Bins = [to_posting_binary(X) || X <- List], postings_open(posting_list_intersect_all(Bins)). %% =================================================================== %% Internal functions %% =================================================================== %% Convert postings (binary or resource) to binary to_posting_binary(Bin) when is_binary(Bin) -> Bin; to_posting_binary(Ref) when is_reference(Ref) -> postings_to_binary(Ref). %% @doc Convert postings resource back to binary (V2 format). -spec postings_to_binary(reference()) -> binary(). postings_to_binary(_Postings) -> ?nif_stub.