Finish C API code generation (continues #14572) (#14868)

Summary:
This continues and finishes **https://github.com/facebook/rocksdb/issues/14572** ("Add semi-automated code generation for RocksDB C API bindings") by xingbowang. The original author is unavailable to finish it, so I've taken it over. **All 13 of the original commits are preserved** (this branch was created from the PR head and builds on top of it — `git log` shows the original `Xingbo Wang` authorship intact); my follow-up work is in the commits prefixed `C API codegen:`.

The underlying design is unchanged and is the original author's: hand-written source templates (`tools/c_api_gen/c_base.h` / `c_base.cc`) plus two generators (auto-discovery from the C++ headers + a spec-driven generator) are inlined into a single, self-contained, `generated` `include/rocksdb/c.h` and `db/c.cc`. This grows the public C API by **668 functions** while keeping `c.h` a single includable header with no `-I` requirement (so `bindgen` and other FFI tools keep working unchanged).

This branch reconciles the PR with ~4 months of `main` and addresses the outstanding review feedback (clang-tidy bot, the automated code review, the `c.h` self-containedness discussion, and pdillinger's points about `include/rocksdb` hygiene and `generated` marking).

## What changed on top of the original PR

### Reconciled with current `main`
- Merged current `main` (conflicts were confined to the generated/test files) and regenerated. Reconciled the 14 C API functions `main` added since the merge-base (e.g. `rocksdb_set_db_options`, the backup-engine rate limiters, `memtable_batch_lookup_optimization`, `optimize_multiget_for_io`, …) and restored 5 enum constants that upstream had added by hand (`rocksdb_txndb_write_policy_*`, `..._index_block_search_type_auto`, `rocksdb_blob_cache_read_byte`).

### Maintainer feedback (pdillinger)
- **No non-user-includable files in `include/rocksdb`.** Moved the hand-written templates out of `include/rocksdb/` and `db/` to `tools/c_api_gen/c_base.{h,cc}`. They were `#include`-ing generated fragments, which broke `make check-headers` and was shipped by `make install`. `include/rocksdb/` now contains only the user-facing, self-contained, `generated` `c.h`.
- `c.h` / `c.cc` carry the `// generated` marker.

### Backward compatibility (zero ABI break)
- The generator derived each wrapper's C type purely from the C++ field, which had silently changed **5 already-shipped signatures** (e.g. `rocksdb_writeoptions_disable_WAL` `int` → `unsigned char`). Added an ABI type-pinning layer (`tools/c_api_gen/abi_type_overrides.json`) so already-shipped functions keep their historical C signature (the body still casts to the real field type). A repo-wide diff against the merge-base now reports **0 ABI drift**.
- New `check_api_compatibility.py` gate (wired into CI + `make`) fails on any removed/changed public function **or** removed enum/typedef symbol, vs a reference revision. Intentional changes go in an allowlist with a reason.

### Correctness (from the automated review)
- Restored 5 option setters that were declared in `c.h` but **defined nowhere** (link failure for downstream bindings such as `rust-rocksdb`). Added `check_api_completeness.py` (dependency-free; runs in CI + `make`) asserting every declared function has exactly one definition — this is the gate that would have caught it.
- `CopyStringVector` now null-checks `malloc`; the WAL filter `std::move`s the `WriteBatch`; the backup exclude-files callback captures by value instead of the wrapper pointer.

### Build / CI robustness
- Removed the dead `C_API_CODEGEN_STAMP` Makefile prerequisite (it was a silent no-op).
- The `make check` staleness check is now opt-out-able (behind `SKIP_FORMAT_BUCK_CHECKS`) and skips gracefully when `clang++` is unavailable, so `make check` works without the codegen toolchain. CI remains the authoritative gate.
- Pinned `clang-format` consistently through `regen_all.py` / `verify_generated_up_to_date.py` (CI uses clang-format-21) so regeneration is byte-reproducible across environments.
- Cleared all 20 `clang-tidy` warnings the bot reported on `db/c.cc` changed lines (fixed in the `c_base.cc` template, not the generated output).
- Updated the internal Buck `c_test_bin` wrapper to expose generated `c_api_gen/*.inc` fragments as headers, so sandboxed Buck builds can compile `db/c_test.c` after the generated round-trip tests are included.

### Test coverage
- Added `gen_roundtrip_tests.py`, which derives **462 set→get→assert round-trip checks across 25 option objects** from the same generated fragments and wires them into `db/c_test.c`. Coverage now tracks the generated surface automatically.

### Docs
- Added the `unreleased_history/public_api_changes` note and fixed `claude_md/add_public_api.md`, which still told contributors to hand-edit the now-`generated` `c.h`/`c.cc`.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/14868

Test Plan:
- `make c_test && ./c_test` — **passes**, including the 462 generated round-trip assertions (a successful link also confirms the API is complete).
- `python3 tools/c_api_gen/check_api_completeness.py` — all 1737 declared functions defined exactly once.
- `python3 tools/c_api_gen/check_api_compatibility.py --ref <release>` — 1070 reference functions + 229 enum/typedef symbols preserved, 0 removed/changed.
- `python3 tools/c_api_gen/verify_generated_up_to_date.py` — generated output is stable.
- `include/rocksdb/c.h` confirmed self-contained (only `<stdbool.h>`, `<stddef.h>`, `<stdint.h>`).

cc xingbowang

- `buck2 build --flagfile fbcode//mode/dev fbcode//internal_repo_rocksdb/repo:c_test_bin` — passes.
- `buck2 build --flagfile fbcode//mode/dev --config fbcode.arch=aarch64 fbcode//internal_repo_rocksdb/repo:c_test_bin` — passes.

Reviewed By: pdillinger

Differential Revision: D109149150

Pulled By: xingbowang

fbshipit-source-id: 3417375345f360a4c78bdfe27e9850b89d0a226a
This commit is contained in:
zaidoon
2026-06-24 10:45:42 -07:00
committed by meta-codesync[bot]
parent 30295a4b92
commit 1cec28d82d
57 changed files with 39867 additions and 2409 deletions
+17
View File
@@ -314,6 +314,23 @@ jobs:
- run: CC=clang-21 CXX=clang++-21 USE_CLANG=1 make -j32 all microbench
- run: make clean
- run: CC=clang-21 CXX=clang++-21 USE_CLANG=1 DEBUG_LEVEL=0 make -j32 release
- name: Install clang-format-21 for C API gen checks
run: apt-get update && apt-get install -y clang-format-21
- name: Check C API codegen (link-complete, backward-compatible, up to date)
# Run the make target in STRICT mode so this core CI job HARD-FAILS rather
# than silently skipping if a prerequisite (clang++, clang-format, or the
# compat baseline ref) is ever missing. See `make check-c-api-gen`.
run: |
# The container checkout is owned by a different user, so git refuses to
# operate on it ("dubious ownership") -- mark it safe for the `git fetch`
# and the `git show` the compat checker runs.
git config --global --add safe.directory "$GITHUB_WORKSPACE"
git config --global --add safe.directory '*'
git fetch --no-tags --depth=1 origin main
CXX=clang++-21 make check-c-api-gen \
CHECK_C_API_GEN_STRICT=1 \
API_COMPAT_REF=FETCH_HEAD \
CLANG_FORMAT_BINARY=clang-format-21
- uses: "./.github/actions/teardown-ccache"
if: always()
- uses: "./.github/actions/post-steps"
+2
View File
@@ -88,6 +88,8 @@ fbcode/
fbcode
buckifier/*.pyc
buckifier/__pycache__
tools/__pycache__/
tools/c_api_gen/__pycache__/
.arcconfig
compile_commands.json
+83 -2
View File
@@ -764,7 +764,6 @@ util/build_version.cc: $(filter-out $(OBJ_DIR)/util/build_version.o, $(LIB_OBJEC
$(AM_V_at)$(gen_build_version) > $@
endif
CLEAN_FILES += util/build_version.cc
default: all
#-----------------------------------------------
@@ -809,7 +808,8 @@ endif # PLATFORM_SHARED_EXT
.PHONY: check clean coverage ldb_tests package dbg gen-pc build_size \
release tags tags0 valgrind_check format static_lib shared_lib all \
rocksdbjavastatic rocksdbjava install install-static install-shared \
uninstall analyze tools tools_lib check-headers checkout_folly clang-tidy
uninstall analyze tools tools_lib check-headers checkout_folly clang-tidy \
check-c-api-c_test
# Auto-configure git hooks on first build so developers do not need to run
# "make install-hooks" manually. This is a no-op if already set.
@@ -1127,8 +1127,89 @@ ifndef SKIP_FORMAT_BUCK_CHECKS
$(MAKE) check-buck-targets
$(MAKE) check-sources
$(MAKE) check-workflow-yaml
$(MAKE) check-c-api-gen
endif
# Check that the auto-generated C API files are up to date. It regenerates the
# fragments and the inlined c.h/c.cc and compares them against a snapshot of the
# checked-in copies (no net change when everything is up to date). It requires
# clang++ (libclang, used to parse the C++ headers) and clang-format. When those
# are unavailable the staleness/compat sub-checks are SKIPPED with a message so
# `make check` still works without the codegen toolchain; the link-completeness
# sub-check always runs (it needs no toolchain).
#
# Pin the formatter to match CI by setting CLANG_FORMAT_BINARY, e.g.:
# make check-c-api-gen CLANG_FORMAT_BINARY=clang-format-21
# This target is part of `make check` and is skipped by SKIP_FORMAT_BUCK_CHECKS.
#
# Set CHECK_C_API_GEN_STRICT=1 to turn every "skip" below into a hard error, so a
# core CI job that runs this target cannot silently regress to a no-op if a
# prerequisite (clang++, or the compat baseline ref) goes missing. The dedicated
# build-linux-clang-21-no_test_run CI job runs this target with the flag set.
# Any non-empty value other than 0/no/false enables strict mode.
CLANG_FORMAT_BINARY ?=
# Backward-compatibility baseline for the C API (signature-level) check. CI
# overrides this with the PR's merge target; locally it falls back to main /
# origin/main and is skipped if neither resolves.
API_COMPAT_REF ?= main
CHECK_C_API_GEN_STRICT ?=
check-c-api-gen:
# Link-completeness is a property of the checked-in c.h/c.cc and needs no
# clang toolchain, so it always runs: every declared public C API function
# must have exactly one definition (guards against dropped wrappers that
# would break downstream language bindings at link time).
$(PYTHON) tools/c_api_gen/check_api_completeness.py
# Backward-compatibility: no public C function may be removed or have its
# signature changed vs the baseline. Skipped if the baseline ref is not
# resolvable locally (CI passes an explicit ref), unless CHECK_C_API_GEN_STRICT.
@strict=""; case "$(CHECK_C_API_GEN_STRICT)" in ""|0|no|NO|false|FALSE) ;; *) strict=1 ;; esac; \
ref=""; \
if git rev-parse --verify --quiet "$(API_COMPAT_REF)^{commit}" >/dev/null; then ref="$(API_COMPAT_REF)"; \
elif git rev-parse --verify --quiet "origin/$(API_COMPAT_REF)^{commit}" >/dev/null; then ref="origin/$(API_COMPAT_REF)"; fi; \
if [ -n "$$ref" ]; then \
$(PYTHON) tools/c_api_gen/check_api_compatibility.py --ref "$$ref"; \
elif [ -n "$$strict" ]; then \
echo "ERROR: C API compat baseline '$(API_COMPAT_REF)' not resolvable and CHECK_C_API_GEN_STRICT is set" >&2; exit 1; \
else \
echo "Skipping C API backward-compatibility check ($(API_COMPAT_REF) not found; set API_COMPAT_REF)"; \
fi
# Staleness: regenerate and confirm the checked-in output is current. Needs a
# clang++ (the generator parses C++ ASTs); detect one the way the generator
# does (a clang in $(CXX) -- which may be ccache-prefixed/versioned -- else a
# bare/versioned clang++ on PATH) rather than testing $(CXX) verbatim.
@strict=""; case "$(CHECK_C_API_GEN_STRICT)" in ""|0|no|NO|false|FALSE) ;; *) strict=1 ;; esac; \
cf_arg=""; \
if [ -n "$(CLANG_FORMAT_BINARY)" ]; then cf_arg="--clang-format $(CLANG_FORMAT_BINARY)"; fi; \
have_clang=""; \
for c in $$(printf '%s\n' $(CXX) | grep -i clang) clang++ clang++-21 clang++-20 clang++-19 clang++-18 clang++-17 clang++-16 clang++-15 clang++-14 clang++-13; do \
if command -v "$$c" >/dev/null 2>&1; then have_clang=1; break; fi; \
done; \
if [ -n "$$have_clang" ]; then \
$(PYTHON) tools/c_api_gen/verify_generated_up_to_date.py $$cf_arg; \
elif [ -n "$$strict" ]; then \
echo "ERROR: no clang++ found and CHECK_C_API_GEN_STRICT is set; cannot run the C API staleness check" >&2; exit 1; \
else \
echo "Skipping C API codegen staleness check (no clang++ found; install clang++ or set CXX to a clang to enable)"; \
fi
# Quick local validation for C API generation plus the focused C API test.
# This verifies the checked-in generated fragments as well as the inlined
# include/rocksdb/c.h and db/c.cc outputs, then runs c_test in an isolated
# TEST_TMPDIR to avoid stale-state failures.
check-c-api-c_test:
$(PYTHON) tools/c_api_gen/verify_generated_up_to_date.py
$(MAKE) c_test
@tmpdir=$$(mktemp -d); \
trap 'rm -rf "$$tmpdir"' EXIT; \
echo "===== Running c_test with TEST_TMPDIR=$$tmpdir"; \
if command -v timeout >/dev/null 2>&1; then \
TEST_TMPDIR="$$tmpdir" timeout 60 ./c_test; \
elif command -v gtimeout >/dev/null 2>&1; then \
TEST_TMPDIR="$$tmpdir" gtimeout 60 ./c_test; \
else \
TEST_TMPDIR="$$tmpdir" ./c_test; \
fi
# TODO add ldb_tests
check_some: $(ROCKSDBTESTS_SUBSET)
for t in $(ROCKSDBTESTS_SUBSET); do echo "===== Running $$t (`date`)"; ./$$t || exit 1; done
+6
View File
@@ -118,6 +118,12 @@ class TARGETSBuilder:
self.total_bin = self.total_bin + 1
def add_c_test(self):
# The actual c_test_bin target is defined by add_c_test_wrapper in the
# internal //rocks/buckifier:defs.bzl (not in this OSS repo). db/c_test.c
# #includes the generated c_api_gen/*.inc fragments, so under Buck's
# hermetic sandbox that wrapper must expose them as headers, e.g.
# headers = native.glob(["c_api_gen/**/*.inc"])
# (Make/CMake resolve the include via -I. / PROJECT_SOURCE_DIR.)
with open(self.path, "ab") as targets_file:
targets_file.write(
b"""
@@ -0,0 +1,39 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/generate_c_api.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Source: tools/c_api_gen/spec.json
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/generate_c_api.py
// --spec tools/c_api_gen/spec.json --section 'BlockBasedOptions simple'
// --header-out
// c_api_gen/c_generated_block_based_options_subset.h.inc
// --source-out
// c_api_gen/c_generated_block_based_options_subset.cc.inc
/* BlockBasedOptions simple */
void rocksdb_block_based_options_set_data_block_hash_ratio(
rocksdb_block_based_table_options_t* options, double v) {
options->rep.data_block_hash_table_util_ratio = v;
}
void rocksdb_block_based_options_set_top_level_index_pinning_tier(
rocksdb_block_based_table_options_t* options, int v) {
options->rep.metadata_cache_options.top_level_index_pinning =
static_cast<ROCKSDB_NAMESPACE::PinningTier>(v);
}
void rocksdb_block_based_options_set_partition_pinning_tier(
rocksdb_block_based_table_options_t* options, int v) {
options->rep.metadata_cache_options.partition_pinning =
static_cast<ROCKSDB_NAMESPACE::PinningTier>(v);
}
void rocksdb_block_based_options_set_unpartitioned_pinning_tier(
rocksdb_block_based_table_options_t* options, int v) {
options->rep.metadata_cache_options.unpartitioned_pinning =
static_cast<ROCKSDB_NAMESPACE::PinningTier>(v);
}
@@ -0,0 +1,32 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/generate_c_api.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Source: tools/c_api_gen/spec.json
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/generate_c_api.py
// --spec tools/c_api_gen/spec.json --section 'BlockBasedOptions simple'
// --header-out
// c_api_gen/c_generated_block_based_options_subset.h.inc
// --source-out
// c_api_gen/c_generated_block_based_options_subset.cc.inc
/* BlockBasedOptions simple */
extern ROCKSDB_LIBRARY_API void
rocksdb_block_based_options_set_data_block_hash_ratio(
rocksdb_block_based_table_options_t* options, double v);
extern ROCKSDB_LIBRARY_API void
rocksdb_block_based_options_set_top_level_index_pinning_tier(
rocksdb_block_based_table_options_t* options, int v);
extern ROCKSDB_LIBRARY_API void
rocksdb_block_based_options_set_partition_pinning_tier(
rocksdb_block_based_table_options_t* options, int v);
extern ROCKSDB_LIBRARY_API void
rocksdb_block_based_options_set_unpartitioned_pinning_tier(
rocksdb_block_based_table_options_t* options, int v);
@@ -0,0 +1,21 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/generate_c_api.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Source: tools/c_api_gen/spec.json
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/generate_c_api.py
// --spec tools/c_api_gen/spec.json --section 'CuckooOptions simple'
// --header-out
// c_api_gen/c_generated_cuckoo_options_subset.h.inc
// --source-out
// c_api_gen/c_generated_cuckoo_options_subset.cc.inc
/* CuckooOptions simple */
void rocksdb_cuckoo_options_set_hash_ratio(
rocksdb_cuckoo_table_options_t* options, double v) {
options->rep.hash_table_ratio = v;
}
@@ -0,0 +1,19 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/generate_c_api.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Source: tools/c_api_gen/spec.json
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/generate_c_api.py
// --spec tools/c_api_gen/spec.json --section 'CuckooOptions simple'
// --header-out
// c_api_gen/c_generated_cuckoo_options_subset.h.inc
// --source-out
// c_api_gen/c_generated_cuckoo_options_subset.cc.inc
/* CuckooOptions simple */
extern ROCKSDB_LIBRARY_API void rocksdb_cuckoo_options_set_hash_ratio(
rocksdb_cuckoo_table_options_t* options, double v);
@@ -0,0 +1,189 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/generate_c_api.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Source: tools/c_api_gen/spec.json
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/generate_c_api.py
// --spec tools/c_api_gen/spec.json --section 'DB data operations'
// --header-out
// c_api_gen/c_generated_db_simple_subset.h.inc
// --source-out
// c_api_gen/c_generated_db_simple_subset.cc.inc
/* DB data operations */
void rocksdb_put(rocksdb_t* db, const rocksdb_writeoptions_t* options,
const char* key, size_t keylen, const char* val, size_t vallen,
char** errptr) {
SaveError(errptr,
db->rep->Put(options->rep, Slice(key, keylen), Slice(val, vallen)));
}
void rocksdb_put_cf(rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family,
const char* key, size_t keylen, const char* val,
size_t vallen, char** errptr) {
SaveError(errptr, db->rep->Put(options->rep, column_family->rep,
Slice(key, keylen), Slice(val, vallen)));
}
void rocksdb_delete(rocksdb_t* db, const rocksdb_writeoptions_t* options,
const char* key, size_t keylen, char** errptr) {
SaveError(errptr, db->rep->Delete(options->rep, Slice(key, keylen)));
}
void rocksdb_delete_cf(rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family,
const char* key, size_t keylen, char** errptr) {
SaveError(errptr, db->rep->Delete(options->rep, column_family->rep,
Slice(key, keylen)));
}
void rocksdb_merge(rocksdb_t* db, const rocksdb_writeoptions_t* options,
const char* key, size_t keylen, const char* val,
size_t vallen, char** errptr) {
SaveError(errptr, db->rep->Merge(options->rep, Slice(key, keylen),
Slice(val, vallen)));
}
void rocksdb_merge_cf(rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family,
const char* key, size_t keylen, const char* val,
size_t vallen, char** errptr) {
SaveError(errptr, db->rep->Merge(options->rep, column_family->rep,
Slice(key, keylen), Slice(val, vallen)));
}
void rocksdb_write(rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_writebatch_t* batch, char** errptr) {
SaveError(errptr, db->rep->Write(options->rep, &batch->rep));
}
void rocksdb_put_with_ts(rocksdb_t* db, const rocksdb_writeoptions_t* options,
const char* key, size_t keylen, const char* ts,
size_t tslen, const char* val, size_t vallen,
char** errptr) {
SaveError(errptr, db->rep->Put(options->rep, Slice(key, keylen),
Slice(ts, tslen), Slice(val, vallen)));
}
void rocksdb_put_cf_with_ts(rocksdb_t* db,
const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family,
const char* key, size_t keylen, const char* ts,
size_t tslen, const char* val, size_t vallen,
char** errptr) {
SaveError(errptr,
db->rep->Put(options->rep, column_family->rep, Slice(key, keylen),
Slice(ts, tslen), Slice(val, vallen)));
}
void rocksdb_delete_with_ts(rocksdb_t* db,
const rocksdb_writeoptions_t* options,
const char* key, size_t keylen, const char* ts,
size_t tslen, char** errptr) {
SaveError(errptr, db->rep->Delete(options->rep, Slice(key, keylen),
Slice(ts, tslen)));
}
void rocksdb_delete_cf_with_ts(rocksdb_t* db,
const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family,
const char* key, size_t keylen, const char* ts,
size_t tslen, char** errptr) {
SaveError(errptr, db->rep->Delete(options->rep, column_family->rep,
Slice(key, keylen), Slice(ts, tslen)));
}
void rocksdb_singledelete(rocksdb_t* db, const rocksdb_writeoptions_t* options,
const char* key, size_t keylen, char** errptr) {
SaveError(errptr, db->rep->SingleDelete(options->rep, Slice(key, keylen)));
}
void rocksdb_singledelete_cf(rocksdb_t* db,
const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family,
const char* key, size_t keylen, char** errptr) {
SaveError(errptr, db->rep->SingleDelete(options->rep, column_family->rep,
Slice(key, keylen)));
}
void rocksdb_singledelete_with_ts(rocksdb_t* db,
const rocksdb_writeoptions_t* options,
const char* key, size_t keylen,
const char* ts, size_t tslen, char** errptr) {
SaveError(errptr, db->rep->SingleDelete(options->rep, Slice(key, keylen),
Slice(ts, tslen)));
}
void rocksdb_singledelete_cf_with_ts(
rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, const char* ts, size_t tslen, char** errptr) {
SaveError(errptr,
db->rep->SingleDelete(options->rep, column_family->rep,
Slice(key, keylen), Slice(ts, tslen)));
}
void rocksdb_delete_range_cf(rocksdb_t* db,
const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family,
const char* start_key, size_t start_key_len,
const char* end_key, size_t end_key_len,
char** errptr) {
SaveError(errptr, db->rep->DeleteRange(options->rep, column_family->rep,
Slice(start_key, start_key_len),
Slice(end_key, end_key_len)));
}
void rocksdb_flush(rocksdb_t* db, const rocksdb_flushoptions_t* options,
char** errptr) {
SaveError(errptr, db->rep->Flush(options->rep));
}
void rocksdb_flush_cf(rocksdb_t* db, const rocksdb_flushoptions_t* options,
rocksdb_column_family_handle_t* column_family,
char** errptr) {
SaveError(errptr, db->rep->Flush(options->rep, column_family->rep));
}
void rocksdb_flush_wal(rocksdb_t* db, unsigned char sync, char** errptr) {
SaveError(errptr, db->rep->FlushWAL(sync));
}
void rocksdb_pause_background_work(rocksdb_t* db, char** errptr) {
SaveError(errptr, db->rep->PauseBackgroundWork());
}
void rocksdb_continue_background_work(rocksdb_t* db, char** errptr) {
SaveError(errptr, db->rep->ContinueBackgroundWork());
}
void rocksdb_disable_file_deletions(rocksdb_t* db, char** errptr) {
SaveError(errptr, db->rep->DisableFileDeletions());
}
void rocksdb_enable_file_deletions(rocksdb_t* db, char** errptr) {
SaveError(errptr, db->rep->EnableFileDeletions());
}
void rocksdb_verify_checksum(rocksdb_t* db, char** errptr) {
SaveError(errptr, db->rep->VerifyChecksum());
}
void rocksdb_verify_file_checksums(rocksdb_t* db, char** errptr) {
SaveError(errptr, db->rep->VerifyFileChecksums(ReadOptions()));
}
void rocksdb_destroy_db(const rocksdb_options_t* options, const char* name,
char** errptr) {
SaveError(errptr, DestroyDB(name, options->rep));
}
void rocksdb_repair_db(const rocksdb_options_t* options, const char* name,
char** errptr) {
SaveError(errptr, RepairDB(name, options->rep));
}
@@ -0,0 +1,126 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/generate_c_api.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Source: tools/c_api_gen/spec.json
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/generate_c_api.py
// --spec tools/c_api_gen/spec.json --section 'DB data operations'
// --header-out
// c_api_gen/c_generated_db_simple_subset.h.inc
// --source-out
// c_api_gen/c_generated_db_simple_subset.cc.inc
/* DB data operations */
extern ROCKSDB_LIBRARY_API void rocksdb_put(
rocksdb_t* db, const rocksdb_writeoptions_t* options, const char* key,
size_t keylen, const char* val, size_t vallen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_put_cf(
rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, const char* val, size_t vallen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_delete(
rocksdb_t* db, const rocksdb_writeoptions_t* options, const char* key,
size_t keylen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_delete_cf(
rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_merge(
rocksdb_t* db, const rocksdb_writeoptions_t* options, const char* key,
size_t keylen, const char* val, size_t vallen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_merge_cf(
rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, const char* val, size_t vallen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_write(
rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_writebatch_t* batch, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_put_with_ts(
rocksdb_t* db, const rocksdb_writeoptions_t* options, const char* key,
size_t keylen, const char* ts, size_t tslen, const char* val, size_t vallen,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_put_cf_with_ts(
rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, const char* ts, size_t tslen, const char* val, size_t vallen,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_delete_with_ts(
rocksdb_t* db, const rocksdb_writeoptions_t* options, const char* key,
size_t keylen, const char* ts, size_t tslen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_delete_cf_with_ts(
rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, const char* ts, size_t tslen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_singledelete(
rocksdb_t* db, const rocksdb_writeoptions_t* options, const char* key,
size_t keylen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_singledelete_cf(
rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_singledelete_with_ts(
rocksdb_t* db, const rocksdb_writeoptions_t* options, const char* key,
size_t keylen, const char* ts, size_t tslen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_singledelete_cf_with_ts(
rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, const char* ts, size_t tslen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_delete_range_cf(
rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* start_key,
size_t start_key_len, const char* end_key, size_t end_key_len,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_flush(
rocksdb_t* db, const rocksdb_flushoptions_t* options, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_flush_cf(
rocksdb_t* db, const rocksdb_flushoptions_t* options,
rocksdb_column_family_handle_t* column_family, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_flush_wal(rocksdb_t* db,
unsigned char sync,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_pause_background_work(rocksdb_t* db,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_continue_background_work(rocksdb_t* db,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_disable_file_deletions(rocksdb_t* db,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_enable_file_deletions(rocksdb_t* db,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_verify_checksum(rocksdb_t* db,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_verify_file_checksums(rocksdb_t* db,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_destroy_db(
const rocksdb_options_t* options, const char* name, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_repair_db(
const rocksdb_options_t* options, const char* name, char** errptr);
+255
View File
@@ -0,0 +1,255 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/auto_simple_bindings.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Sources:
// - include/rocksdb/listener.h
// - tools/c_api_gen/auto_simple_bindings_blocklist.json
// - include/rocksdb/c.h
// - tools/c_api_gen/c_base.cc
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/auto_simple_bindings.py
// Output group: Auto-discovered JobInfo metadata simple
/* FlushJobInfo */
uint32_t rocksdb_flushjobinfo_cf_id(const rocksdb_flushjobinfo_t* info) {
return info->rep.cf_id;
}
const char* rocksdb_flushjobinfo_cf_name(const rocksdb_flushjobinfo_t* info,
size_t* size) {
*size = info->rep.cf_name.size();
return info->rep.cf_name.data();
}
const char* rocksdb_flushjobinfo_file_path(const rocksdb_flushjobinfo_t* info,
size_t* size) {
*size = info->rep.file_path.size();
return info->rep.file_path.data();
}
uint64_t rocksdb_flushjobinfo_file_number(const rocksdb_flushjobinfo_t* info) {
return info->rep.file_number;
}
uint64_t rocksdb_flushjobinfo_oldest_blob_file_number(
const rocksdb_flushjobinfo_t* info) {
return info->rep.oldest_blob_file_number;
}
uint64_t rocksdb_flushjobinfo_thread_id(const rocksdb_flushjobinfo_t* info) {
return info->rep.thread_id;
}
int rocksdb_flushjobinfo_job_id(const rocksdb_flushjobinfo_t* info) {
return info->rep.job_id;
}
unsigned char rocksdb_flushjobinfo_triggered_writes_slowdown(
const rocksdb_flushjobinfo_t* info) {
return info->rep.triggered_writes_slowdown;
}
unsigned char rocksdb_flushjobinfo_triggered_writes_stop(
const rocksdb_flushjobinfo_t* info) {
return info->rep.triggered_writes_stop;
}
uint64_t rocksdb_flushjobinfo_smallest_seqno(
const rocksdb_flushjobinfo_t* info) {
return info->rep.smallest_seqno;
}
uint64_t rocksdb_flushjobinfo_largest_seqno(
const rocksdb_flushjobinfo_t* info) {
return info->rep.largest_seqno;
}
uint32_t rocksdb_flushjobinfo_flush_reason(const rocksdb_flushjobinfo_t* info) {
return static_cast<uint32_t>(info->rep.flush_reason);
}
uint32_t rocksdb_flushjobinfo_blob_compression_type(
const rocksdb_flushjobinfo_t* info) {
return static_cast<uint32_t>(info->rep.blob_compression_type);
}
/* CompactionJobInfo */
uint32_t rocksdb_compactionjobinfo_cf_id(
const rocksdb_compactionjobinfo_t* info) {
return info->rep.cf_id;
}
const char* rocksdb_compactionjobinfo_cf_name(
const rocksdb_compactionjobinfo_t* info, size_t* size) {
*size = info->rep.cf_name.size();
return info->rep.cf_name.data();
}
void rocksdb_compactionjobinfo_status(const rocksdb_compactionjobinfo_t* info,
char** errptr) {
SaveError(errptr, info->rep.status);
}
uint64_t rocksdb_compactionjobinfo_thread_id(
const rocksdb_compactionjobinfo_t* info) {
return info->rep.thread_id;
}
int rocksdb_compactionjobinfo_job_id(const rocksdb_compactionjobinfo_t* info) {
return info->rep.job_id;
}
int rocksdb_compactionjobinfo_num_l0_files(
const rocksdb_compactionjobinfo_t* info) {
return info->rep.num_l0_files;
}
int rocksdb_compactionjobinfo_base_input_level(
const rocksdb_compactionjobinfo_t* info) {
return info->rep.base_input_level;
}
int rocksdb_compactionjobinfo_output_level(
const rocksdb_compactionjobinfo_t* info) {
return info->rep.output_level;
}
uint32_t rocksdb_compactionjobinfo_compaction_reason(
const rocksdb_compactionjobinfo_t* info) {
return static_cast<uint32_t>(info->rep.compaction_reason);
}
uint32_t rocksdb_compactionjobinfo_compression(
const rocksdb_compactionjobinfo_t* info) {
return static_cast<uint32_t>(info->rep.compression);
}
uint32_t rocksdb_compactionjobinfo_blob_compression_type(
const rocksdb_compactionjobinfo_t* info) {
return static_cast<uint32_t>(info->rep.blob_compression_type);
}
unsigned char rocksdb_compactionjobinfo_aborted(
const rocksdb_compactionjobinfo_t* info) {
return info->rep.aborted;
}
/* SubcompactionJobInfo */
uint32_t rocksdb_subcompactionjobinfo_cf_id(
const rocksdb_subcompactionjobinfo_t* info) {
return info->rep.cf_id;
}
const char* rocksdb_subcompactionjobinfo_cf_name(
const rocksdb_subcompactionjobinfo_t* info, size_t* size) {
*size = info->rep.cf_name.size();
return info->rep.cf_name.data();
}
void rocksdb_subcompactionjobinfo_status(
const rocksdb_subcompactionjobinfo_t* info, char** errptr) {
SaveError(errptr, info->rep.status);
}
uint64_t rocksdb_subcompactionjobinfo_thread_id(
const rocksdb_subcompactionjobinfo_t* info) {
return info->rep.thread_id;
}
int rocksdb_subcompactionjobinfo_job_id(
const rocksdb_subcompactionjobinfo_t* info) {
return info->rep.job_id;
}
int rocksdb_subcompactionjobinfo_subcompaction_job_id(
const rocksdb_subcompactionjobinfo_t* info) {
return info->rep.subcompaction_job_id;
}
int rocksdb_subcompactionjobinfo_base_input_level(
const rocksdb_subcompactionjobinfo_t* info) {
return info->rep.base_input_level;
}
int rocksdb_subcompactionjobinfo_output_level(
const rocksdb_subcompactionjobinfo_t* info) {
return info->rep.output_level;
}
uint32_t rocksdb_subcompactionjobinfo_compaction_reason(
const rocksdb_subcompactionjobinfo_t* info) {
return static_cast<uint32_t>(info->rep.compaction_reason);
}
uint32_t rocksdb_subcompactionjobinfo_compression(
const rocksdb_subcompactionjobinfo_t* info) {
return static_cast<uint32_t>(info->rep.compression);
}
uint32_t rocksdb_subcompactionjobinfo_blob_compression_type(
const rocksdb_subcompactionjobinfo_t* info) {
return static_cast<uint32_t>(info->rep.blob_compression_type);
}
/* ExternalFileIngestionInfo */
const char* rocksdb_externalfileingestioninfo_cf_name(
const rocksdb_externalfileingestioninfo_t* info, size_t* size) {
*size = info->rep.cf_name.size();
return info->rep.cf_name.data();
}
const char* rocksdb_externalfileingestioninfo_external_file_path(
const rocksdb_externalfileingestioninfo_t* info, size_t* size) {
*size = info->rep.external_file_path.size();
return info->rep.external_file_path.data();
}
const char* rocksdb_externalfileingestioninfo_internal_file_path(
const rocksdb_externalfileingestioninfo_t* info, size_t* size) {
*size = info->rep.internal_file_path.size();
return info->rep.internal_file_path.data();
}
uint64_t rocksdb_externalfileingestioninfo_global_seqno(
const rocksdb_externalfileingestioninfo_t* info) {
return info->rep.global_seqno;
}
/* MemTableInfo */
const char* rocksdb_memtableinfo_cf_name(const rocksdb_memtableinfo_t* info,
size_t* size) {
*size = info->rep.cf_name.size();
return info->rep.cf_name.data();
}
uint64_t rocksdb_memtableinfo_first_seqno(const rocksdb_memtableinfo_t* info) {
return info->rep.first_seqno;
}
uint64_t rocksdb_memtableinfo_earliest_seqno(
const rocksdb_memtableinfo_t* info) {
return info->rep.earliest_seqno;
}
uint64_t rocksdb_memtableinfo_num_entries(const rocksdb_memtableinfo_t* info) {
return info->rep.num_entries;
}
uint64_t rocksdb_memtableinfo_num_deletes(const rocksdb_memtableinfo_t* info) {
return info->rep.num_deletes;
}
const char* rocksdb_memtableinfo_newest_udt(const rocksdb_memtableinfo_t* info,
size_t* size) {
*size = info->rep.newest_udt.size();
return info->rep.newest_udt.data();
}
+173
View File
@@ -0,0 +1,173 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/auto_simple_bindings.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Sources:
// - include/rocksdb/listener.h
// - tools/c_api_gen/auto_simple_bindings_blocklist.json
// - include/rocksdb/c.h
// - tools/c_api_gen/c_base.cc
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/auto_simple_bindings.py
// Output group: Auto-discovered JobInfo metadata simple
/* FlushJobInfo */
extern ROCKSDB_LIBRARY_API uint32_t
rocksdb_flushjobinfo_cf_id(const rocksdb_flushjobinfo_t* info);
extern ROCKSDB_LIBRARY_API const char* rocksdb_flushjobinfo_cf_name(
const rocksdb_flushjobinfo_t* info, size_t* size);
extern ROCKSDB_LIBRARY_API const char* rocksdb_flushjobinfo_file_path(
const rocksdb_flushjobinfo_t* info, size_t* size);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_flushjobinfo_file_number(const rocksdb_flushjobinfo_t* info);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_flushjobinfo_oldest_blob_file_number(
const rocksdb_flushjobinfo_t* info);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_flushjobinfo_thread_id(const rocksdb_flushjobinfo_t* info);
extern ROCKSDB_LIBRARY_API int rocksdb_flushjobinfo_job_id(
const rocksdb_flushjobinfo_t* info);
extern ROCKSDB_LIBRARY_API unsigned char
rocksdb_flushjobinfo_triggered_writes_slowdown(
const rocksdb_flushjobinfo_t* info);
extern ROCKSDB_LIBRARY_API unsigned char
rocksdb_flushjobinfo_triggered_writes_stop(const rocksdb_flushjobinfo_t* info);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_flushjobinfo_smallest_seqno(const rocksdb_flushjobinfo_t* info);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_flushjobinfo_largest_seqno(const rocksdb_flushjobinfo_t* info);
extern ROCKSDB_LIBRARY_API uint32_t
rocksdb_flushjobinfo_flush_reason(const rocksdb_flushjobinfo_t* info);
extern ROCKSDB_LIBRARY_API uint32_t
rocksdb_flushjobinfo_blob_compression_type(const rocksdb_flushjobinfo_t* info);
/* CompactionJobInfo */
extern ROCKSDB_LIBRARY_API uint32_t
rocksdb_compactionjobinfo_cf_id(const rocksdb_compactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API const char* rocksdb_compactionjobinfo_cf_name(
const rocksdb_compactionjobinfo_t* info, size_t* size);
extern ROCKSDB_LIBRARY_API void rocksdb_compactionjobinfo_status(
const rocksdb_compactionjobinfo_t* info, char** errptr);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compactionjobinfo_thread_id(const rocksdb_compactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API int rocksdb_compactionjobinfo_job_id(
const rocksdb_compactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API int rocksdb_compactionjobinfo_num_l0_files(
const rocksdb_compactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API int rocksdb_compactionjobinfo_base_input_level(
const rocksdb_compactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API int rocksdb_compactionjobinfo_output_level(
const rocksdb_compactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API uint32_t rocksdb_compactionjobinfo_compaction_reason(
const rocksdb_compactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API uint32_t
rocksdb_compactionjobinfo_compression(const rocksdb_compactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API uint32_t
rocksdb_compactionjobinfo_blob_compression_type(
const rocksdb_compactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API unsigned char rocksdb_compactionjobinfo_aborted(
const rocksdb_compactionjobinfo_t* info);
/* SubcompactionJobInfo */
extern ROCKSDB_LIBRARY_API uint32_t
rocksdb_subcompactionjobinfo_cf_id(const rocksdb_subcompactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API const char* rocksdb_subcompactionjobinfo_cf_name(
const rocksdb_subcompactionjobinfo_t* info, size_t* size);
extern ROCKSDB_LIBRARY_API void rocksdb_subcompactionjobinfo_status(
const rocksdb_subcompactionjobinfo_t* info, char** errptr);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_subcompactionjobinfo_thread_id(
const rocksdb_subcompactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API int rocksdb_subcompactionjobinfo_job_id(
const rocksdb_subcompactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API int
rocksdb_subcompactionjobinfo_subcompaction_job_id(
const rocksdb_subcompactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API int rocksdb_subcompactionjobinfo_base_input_level(
const rocksdb_subcompactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API int rocksdb_subcompactionjobinfo_output_level(
const rocksdb_subcompactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API uint32_t
rocksdb_subcompactionjobinfo_compaction_reason(
const rocksdb_subcompactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API uint32_t rocksdb_subcompactionjobinfo_compression(
const rocksdb_subcompactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API uint32_t
rocksdb_subcompactionjobinfo_blob_compression_type(
const rocksdb_subcompactionjobinfo_t* info);
/* ExternalFileIngestionInfo */
extern ROCKSDB_LIBRARY_API const char*
rocksdb_externalfileingestioninfo_cf_name(
const rocksdb_externalfileingestioninfo_t* info, size_t* size);
extern ROCKSDB_LIBRARY_API const char*
rocksdb_externalfileingestioninfo_external_file_path(
const rocksdb_externalfileingestioninfo_t* info, size_t* size);
extern ROCKSDB_LIBRARY_API const char*
rocksdb_externalfileingestioninfo_internal_file_path(
const rocksdb_externalfileingestioninfo_t* info, size_t* size);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_externalfileingestioninfo_global_seqno(
const rocksdb_externalfileingestioninfo_t* info);
/* MemTableInfo */
extern ROCKSDB_LIBRARY_API const char* rocksdb_memtableinfo_cf_name(
const rocksdb_memtableinfo_t* info, size_t* size);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_memtableinfo_first_seqno(const rocksdb_memtableinfo_t* info);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_memtableinfo_earliest_seqno(const rocksdb_memtableinfo_t* info);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_memtableinfo_num_entries(const rocksdb_memtableinfo_t* info);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_memtableinfo_num_deletes(const rocksdb_memtableinfo_t* info);
extern ROCKSDB_LIBRARY_API const char* rocksdb_memtableinfo_newest_udt(
const rocksdb_memtableinfo_t* info, size_t* size);
@@ -0,0 +1,84 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/generate_c_api.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Source: tools/c_api_gen/spec.json
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/generate_c_api.py
// --spec tools/c_api_gen/spec.json --section 'JobInfo metadata simple'
// --header-out
// c_api_gen/c_generated_jobinfo_metadata_subset.h.inc
// --source-out
// c_api_gen/c_generated_jobinfo_metadata_subset.cc.inc
/* JobInfo metadata simple */
size_t rocksdb_compactionjobinfo_input_files_count(
const rocksdb_compactionjobinfo_t* info) {
return info->rep.input_files.size();
}
size_t rocksdb_compactionjobinfo_output_files_count(
const rocksdb_compactionjobinfo_t* info) {
return info->rep.output_files.size();
}
uint64_t rocksdb_compactionjobinfo_elapsed_micros(
const rocksdb_compactionjobinfo_t* info) {
return info->rep.stats.elapsed_micros;
}
uint64_t rocksdb_compactionjobinfo_num_corrupt_keys(
const rocksdb_compactionjobinfo_t* info) {
return info->rep.stats.num_corrupt_keys;
}
uint64_t rocksdb_compactionjobinfo_input_records(
const rocksdb_compactionjobinfo_t* info) {
return info->rep.stats.num_input_records;
}
uint64_t rocksdb_compactionjobinfo_output_records(
const rocksdb_compactionjobinfo_t* info) {
return info->rep.stats.num_output_records;
}
uint64_t rocksdb_compactionjobinfo_total_input_bytes(
const rocksdb_compactionjobinfo_t* info) {
return info->rep.stats.total_input_bytes;
}
uint64_t rocksdb_compactionjobinfo_total_output_bytes(
const rocksdb_compactionjobinfo_t* info) {
return info->rep.stats.total_output_bytes;
}
size_t rocksdb_compactionjobinfo_num_input_files(
const rocksdb_compactionjobinfo_t* info) {
return info->rep.stats.num_input_files;
}
size_t rocksdb_compactionjobinfo_num_input_files_at_output_level(
const rocksdb_compactionjobinfo_t* info) {
return info->rep.stats.num_input_files_at_output_level;
}
const char* rocksdb_writestallinfo_cf_name(const rocksdb_writestallinfo_t* info,
size_t* size) {
*size = info->rep.cf_name.size();
return info->rep.cf_name.data();
}
const rocksdb_writestallcondition_t* rocksdb_writestallinfo_cur(
const rocksdb_writestallinfo_t* info) {
return reinterpret_cast<const rocksdb_writestallcondition_t*>(
&info->rep.condition.cur);
}
const rocksdb_writestallcondition_t* rocksdb_writestallinfo_prev(
const rocksdb_writestallinfo_t* info) {
return reinterpret_cast<const rocksdb_writestallcondition_t*>(
&info->rep.condition.prev);
}
@@ -0,0 +1,57 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/generate_c_api.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Source: tools/c_api_gen/spec.json
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/generate_c_api.py
// --spec tools/c_api_gen/spec.json --section 'JobInfo metadata simple'
// --header-out
// c_api_gen/c_generated_jobinfo_metadata_subset.h.inc
// --source-out
// c_api_gen/c_generated_jobinfo_metadata_subset.cc.inc
/* JobInfo metadata simple */
extern ROCKSDB_LIBRARY_API size_t rocksdb_compactionjobinfo_input_files_count(
const rocksdb_compactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API size_t rocksdb_compactionjobinfo_output_files_count(
const rocksdb_compactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_compactionjobinfo_elapsed_micros(
const rocksdb_compactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_compactionjobinfo_num_corrupt_keys(
const rocksdb_compactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_compactionjobinfo_input_records(
const rocksdb_compactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_compactionjobinfo_output_records(
const rocksdb_compactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_compactionjobinfo_total_input_bytes(
const rocksdb_compactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compactionjobinfo_total_output_bytes(
const rocksdb_compactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API size_t rocksdb_compactionjobinfo_num_input_files(
const rocksdb_compactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API size_t
rocksdb_compactionjobinfo_num_input_files_at_output_level(
const rocksdb_compactionjobinfo_t* info);
extern ROCKSDB_LIBRARY_API const char* rocksdb_writestallinfo_cf_name(
const rocksdb_writestallinfo_t* info, size_t* size);
extern ROCKSDB_LIBRARY_API const rocksdb_writestallcondition_t*
rocksdb_writestallinfo_cur(const rocksdb_writestallinfo_t* info);
extern ROCKSDB_LIBRARY_API const rocksdb_writestallcondition_t*
rocksdb_writestallinfo_prev(const rocksdb_writestallinfo_t* info);
@@ -0,0 +1,501 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/auto_simple_bindings.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Sources:
// - include/rocksdb/compaction_job_stats.h
// - include/rocksdb/listener.h
// - include/rocksdb/table_properties.h
// - tools/c_api_gen/auto_simple_bindings_blocklist.json
// - include/rocksdb/c.h
// - tools/c_api_gen/c_base.cc
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/auto_simple_bindings.py
// Output group: Auto-discovered metadata view structs simple
/* TableProperties */
uint64_t rocksdb_table_properties_orig_file_number(
const rocksdb_table_properties_t* props) {
return props->rep.orig_file_number;
}
uint64_t rocksdb_table_properties_data_size(
const rocksdb_table_properties_t* props) {
return props->rep.data_size;
}
uint64_t rocksdb_table_properties_uncompressed_data_size(
const rocksdb_table_properties_t* props) {
return props->rep.uncompressed_data_size;
}
uint64_t rocksdb_table_properties_index_size(
const rocksdb_table_properties_t* props) {
return props->rep.index_size;
}
uint64_t rocksdb_table_properties_index_partitions(
const rocksdb_table_properties_t* props) {
return props->rep.index_partitions;
}
uint64_t rocksdb_table_properties_top_level_index_size(
const rocksdb_table_properties_t* props) {
return props->rep.top_level_index_size;
}
uint64_t rocksdb_table_properties_index_key_is_user_key(
const rocksdb_table_properties_t* props) {
return props->rep.index_key_is_user_key;
}
uint64_t rocksdb_table_properties_index_value_is_delta_encoded(
const rocksdb_table_properties_t* props) {
return props->rep.index_value_is_delta_encoded;
}
uint64_t rocksdb_table_properties_udi_is_primary_index(
const rocksdb_table_properties_t* props) {
return props->rep.udi_is_primary_index;
}
uint64_t rocksdb_table_properties_filter_size(
const rocksdb_table_properties_t* props) {
return props->rep.filter_size;
}
uint64_t rocksdb_table_properties_raw_key_size(
const rocksdb_table_properties_t* props) {
return props->rep.raw_key_size;
}
uint64_t rocksdb_table_properties_raw_value_size(
const rocksdb_table_properties_t* props) {
return props->rep.raw_value_size;
}
uint64_t rocksdb_table_properties_num_data_blocks(
const rocksdb_table_properties_t* props) {
return props->rep.num_data_blocks;
}
uint64_t rocksdb_table_properties_num_data_blocks_compression_rejected(
const rocksdb_table_properties_t* props) {
return props->rep.num_data_blocks_compression_rejected;
}
uint64_t rocksdb_table_properties_num_data_blocks_compression_bypassed(
const rocksdb_table_properties_t* props) {
return props->rep.num_data_blocks_compression_bypassed;
}
uint64_t rocksdb_table_properties_num_uniform_blocks(
const rocksdb_table_properties_t* props) {
return props->rep.num_uniform_blocks;
}
uint64_t rocksdb_table_properties_num_entries(
const rocksdb_table_properties_t* props) {
return props->rep.num_entries;
}
uint64_t rocksdb_table_properties_num_filter_entries(
const rocksdb_table_properties_t* props) {
return props->rep.num_filter_entries;
}
uint64_t rocksdb_table_properties_num_deletions(
const rocksdb_table_properties_t* props) {
return props->rep.num_deletions;
}
uint64_t rocksdb_table_properties_num_merge_operands(
const rocksdb_table_properties_t* props) {
return props->rep.num_merge_operands;
}
uint64_t rocksdb_table_properties_num_range_deletions(
const rocksdb_table_properties_t* props) {
return props->rep.num_range_deletions;
}
uint64_t rocksdb_table_properties_format_version(
const rocksdb_table_properties_t* props) {
return props->rep.format_version;
}
uint64_t rocksdb_table_properties_fixed_key_len(
const rocksdb_table_properties_t* props) {
return props->rep.fixed_key_len;
}
uint64_t rocksdb_table_properties_column_family_id(
const rocksdb_table_properties_t* props) {
return props->rep.column_family_id;
}
uint64_t rocksdb_table_properties_creation_time(
const rocksdb_table_properties_t* props) {
return props->rep.creation_time;
}
uint64_t rocksdb_table_properties_oldest_key_time(
const rocksdb_table_properties_t* props) {
return props->rep.oldest_key_time;
}
uint64_t rocksdb_table_properties_newest_key_time(
const rocksdb_table_properties_t* props) {
return props->rep.newest_key_time;
}
uint64_t rocksdb_table_properties_file_creation_time(
const rocksdb_table_properties_t* props) {
return props->rep.file_creation_time;
}
uint64_t rocksdb_table_properties_slow_compression_estimated_data_size(
const rocksdb_table_properties_t* props) {
return props->rep.slow_compression_estimated_data_size;
}
uint64_t rocksdb_table_properties_fast_compression_estimated_data_size(
const rocksdb_table_properties_t* props) {
return props->rep.fast_compression_estimated_data_size;
}
uint64_t rocksdb_table_properties_external_sst_file_global_seqno_offset(
const rocksdb_table_properties_t* props) {
return props->rep.external_sst_file_global_seqno_offset;
}
uint64_t rocksdb_table_properties_tail_start_offset(
const rocksdb_table_properties_t* props) {
return props->rep.tail_start_offset;
}
uint64_t rocksdb_table_properties_user_defined_timestamps_persisted(
const rocksdb_table_properties_t* props) {
return props->rep.user_defined_timestamps_persisted;
}
uint64_t rocksdb_table_properties_key_largest_seqno(
const rocksdb_table_properties_t* props) {
return props->rep.key_largest_seqno;
}
uint64_t rocksdb_table_properties_key_smallest_seqno(
const rocksdb_table_properties_t* props) {
return props->rep.key_smallest_seqno;
}
uint64_t rocksdb_table_properties_data_block_restart_interval(
const rocksdb_table_properties_t* props) {
return props->rep.data_block_restart_interval;
}
uint64_t rocksdb_table_properties_index_block_restart_interval(
const rocksdb_table_properties_t* props) {
return props->rep.index_block_restart_interval;
}
uint64_t rocksdb_table_properties_separate_key_value_in_data_block(
const rocksdb_table_properties_t* props) {
return props->rep.separate_key_value_in_data_block;
}
const char* rocksdb_table_properties_db_id(
const rocksdb_table_properties_t* props, size_t* size) {
*size = props->rep.db_id.size();
return props->rep.db_id.data();
}
const char* rocksdb_table_properties_db_session_id(
const rocksdb_table_properties_t* props, size_t* size) {
*size = props->rep.db_session_id.size();
return props->rep.db_session_id.data();
}
const char* rocksdb_table_properties_db_host_id(
const rocksdb_table_properties_t* props, size_t* size) {
*size = props->rep.db_host_id.size();
return props->rep.db_host_id.data();
}
const char* rocksdb_table_properties_column_family_name(
const rocksdb_table_properties_t* props, size_t* size) {
*size = props->rep.column_family_name.size();
return props->rep.column_family_name.data();
}
const char* rocksdb_table_properties_filter_policy_name(
const rocksdb_table_properties_t* props, size_t* size) {
*size = props->rep.filter_policy_name.size();
return props->rep.filter_policy_name.data();
}
const char* rocksdb_table_properties_comparator_name(
const rocksdb_table_properties_t* props, size_t* size) {
*size = props->rep.comparator_name.size();
return props->rep.comparator_name.data();
}
const char* rocksdb_table_properties_merge_operator_name(
const rocksdb_table_properties_t* props, size_t* size) {
*size = props->rep.merge_operator_name.size();
return props->rep.merge_operator_name.data();
}
const char* rocksdb_table_properties_prefix_extractor_name(
const rocksdb_table_properties_t* props, size_t* size) {
*size = props->rep.prefix_extractor_name.size();
return props->rep.prefix_extractor_name.data();
}
const char* rocksdb_table_properties_property_collectors_names(
const rocksdb_table_properties_t* props, size_t* size) {
*size = props->rep.property_collectors_names.size();
return props->rep.property_collectors_names.data();
}
const char* rocksdb_table_properties_compression_name(
const rocksdb_table_properties_t* props, size_t* size) {
*size = props->rep.compression_name.size();
return props->rep.compression_name.data();
}
const char* rocksdb_table_properties_compression_options(
const rocksdb_table_properties_t* props, size_t* size) {
*size = props->rep.compression_options.size();
return props->rep.compression_options.data();
}
const char* rocksdb_table_properties_seqno_to_time_mapping(
const rocksdb_table_properties_t* props, size_t* size) {
*size = props->rep.seqno_to_time_mapping.size();
return props->rep.seqno_to_time_mapping.data();
}
/* CompactionJobStats */
uint64_t rocksdb_compaction_job_stats_elapsed_micros(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.elapsed_micros;
}
uint64_t rocksdb_compaction_job_stats_cpu_micros(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.cpu_micros;
}
unsigned char rocksdb_compaction_job_stats_has_accurate_num_input_records(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.has_accurate_num_input_records;
}
uint64_t rocksdb_compaction_job_stats_num_input_records(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.num_input_records;
}
uint64_t rocksdb_compaction_job_stats_num_blobs_read(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.num_blobs_read;
}
size_t rocksdb_compaction_job_stats_num_input_files(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.num_input_files;
}
size_t rocksdb_compaction_job_stats_num_input_files_trivially_moved(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.num_input_files_trivially_moved;
}
size_t rocksdb_compaction_job_stats_num_input_files_at_output_level(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.num_input_files_at_output_level;
}
size_t rocksdb_compaction_job_stats_num_filtered_input_files(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.num_filtered_input_files;
}
size_t rocksdb_compaction_job_stats_num_filtered_input_files_at_output_level(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.num_filtered_input_files_at_output_level;
}
uint64_t rocksdb_compaction_job_stats_num_output_records(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.num_output_records;
}
size_t rocksdb_compaction_job_stats_num_output_files(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.num_output_files;
}
size_t rocksdb_compaction_job_stats_num_output_files_blob(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.num_output_files_blob;
}
unsigned char rocksdb_compaction_job_stats_is_full_compaction(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.is_full_compaction;
}
unsigned char rocksdb_compaction_job_stats_is_manual_compaction(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.is_manual_compaction;
}
unsigned char rocksdb_compaction_job_stats_is_remote_compaction(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.is_remote_compaction;
}
uint64_t rocksdb_compaction_job_stats_total_input_bytes(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.total_input_bytes;
}
uint64_t rocksdb_compaction_job_stats_total_blob_bytes_read(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.total_blob_bytes_read;
}
uint64_t rocksdb_compaction_job_stats_total_output_bytes(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.total_output_bytes;
}
uint64_t rocksdb_compaction_job_stats_total_output_bytes_blob(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.total_output_bytes_blob;
}
uint64_t rocksdb_compaction_job_stats_total_skipped_input_bytes(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.total_skipped_input_bytes;
}
uint64_t rocksdb_compaction_job_stats_num_records_replaced(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.num_records_replaced;
}
uint64_t rocksdb_compaction_job_stats_total_input_raw_key_bytes(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.total_input_raw_key_bytes;
}
uint64_t rocksdb_compaction_job_stats_total_input_raw_value_bytes(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.total_input_raw_value_bytes;
}
uint64_t rocksdb_compaction_job_stats_num_input_deletion_records(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.num_input_deletion_records;
}
uint64_t rocksdb_compaction_job_stats_num_expired_deletion_records(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.num_expired_deletion_records;
}
uint64_t rocksdb_compaction_job_stats_num_corrupt_keys(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.num_corrupt_keys;
}
uint64_t rocksdb_compaction_job_stats_file_write_nanos(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.file_write_nanos;
}
uint64_t rocksdb_compaction_job_stats_file_range_sync_nanos(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.file_range_sync_nanos;
}
uint64_t rocksdb_compaction_job_stats_file_fsync_nanos(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.file_fsync_nanos;
}
uint64_t rocksdb_compaction_job_stats_file_prepare_write_nanos(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.file_prepare_write_nanos;
}
const char* rocksdb_compaction_job_stats_smallest_output_key_prefix(
const rocksdb_compaction_job_stats_t* stats, size_t* size) {
*size = stats->rep.smallest_output_key_prefix.size();
return stats->rep.smallest_output_key_prefix.data();
}
const char* rocksdb_compaction_job_stats_largest_output_key_prefix(
const rocksdb_compaction_job_stats_t* stats, size_t* size) {
*size = stats->rep.largest_output_key_prefix.size();
return stats->rep.largest_output_key_prefix.data();
}
uint64_t rocksdb_compaction_job_stats_num_single_del_fallthru(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.num_single_del_fallthru;
}
uint64_t rocksdb_compaction_job_stats_num_single_del_mismatch(
const rocksdb_compaction_job_stats_t* stats) {
return stats->rep.num_single_del_mismatch;
}
/* CompactionFileInfo */
int rocksdb_compaction_file_info_level(
const rocksdb_compaction_file_info_t* info) {
return info->rep.level;
}
uint64_t rocksdb_compaction_file_info_file_number(
const rocksdb_compaction_file_info_t* info) {
return info->rep.file_number;
}
uint64_t rocksdb_compaction_file_info_oldest_blob_file_number(
const rocksdb_compaction_file_info_t* info) {
return info->rep.oldest_blob_file_number;
}
/* BlobFileAdditionInfo */
uint64_t rocksdb_blob_file_addition_info_total_blob_count(
const rocksdb_blob_file_addition_info_t* info) {
return info->rep.total_blob_count;
}
uint64_t rocksdb_blob_file_addition_info_total_blob_bytes(
const rocksdb_blob_file_addition_info_t* info) {
return info->rep.total_blob_bytes;
}
/* BlobFileGarbageInfo */
uint64_t rocksdb_blob_file_garbage_info_garbage_blob_count(
const rocksdb_blob_file_garbage_info_t* info) {
return info->rep.garbage_blob_count;
}
uint64_t rocksdb_blob_file_garbage_info_garbage_blob_bytes(
const rocksdb_blob_file_garbage_info_t* info) {
return info->rep.garbage_blob_bytes;
}
@@ -0,0 +1,361 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/auto_simple_bindings.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Sources:
// - include/rocksdb/compaction_job_stats.h
// - include/rocksdb/listener.h
// - include/rocksdb/table_properties.h
// - tools/c_api_gen/auto_simple_bindings_blocklist.json
// - include/rocksdb/c.h
// - tools/c_api_gen/c_base.cc
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/auto_simple_bindings.py
// Output group: Auto-discovered metadata view structs simple
/* TableProperties */
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_table_properties_orig_file_number(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_data_size(const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_uncompressed_data_size(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_index_size(const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_table_properties_index_partitions(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_top_level_index_size(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_index_key_is_user_key(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_index_value_is_delta_encoded(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_udi_is_primary_index(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_filter_size(const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_raw_key_size(const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_table_properties_raw_value_size(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_table_properties_num_data_blocks(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_num_data_blocks_compression_rejected(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_num_data_blocks_compression_bypassed(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_table_properties_num_uniform_blocks(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_num_entries(const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_table_properties_num_filter_entries(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_num_deletions(const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_table_properties_num_merge_operands(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_num_range_deletions(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_table_properties_format_version(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_fixed_key_len(const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_table_properties_column_family_id(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_creation_time(const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_table_properties_oldest_key_time(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_table_properties_newest_key_time(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_table_properties_file_creation_time(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_slow_compression_estimated_data_size(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_fast_compression_estimated_data_size(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_external_sst_file_global_seqno_offset(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_table_properties_tail_start_offset(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_user_defined_timestamps_persisted(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_table_properties_key_largest_seqno(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_table_properties_key_smallest_seqno(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_data_block_restart_interval(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_index_block_restart_interval(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_table_properties_separate_key_value_in_data_block(
const rocksdb_table_properties_t* props);
extern ROCKSDB_LIBRARY_API const char* rocksdb_table_properties_db_id(
const rocksdb_table_properties_t* props, size_t* size);
extern ROCKSDB_LIBRARY_API const char* rocksdb_table_properties_db_session_id(
const rocksdb_table_properties_t* props, size_t* size);
extern ROCKSDB_LIBRARY_API const char* rocksdb_table_properties_db_host_id(
const rocksdb_table_properties_t* props, size_t* size);
extern ROCKSDB_LIBRARY_API const char*
rocksdb_table_properties_column_family_name(
const rocksdb_table_properties_t* props, size_t* size);
extern ROCKSDB_LIBRARY_API const char*
rocksdb_table_properties_filter_policy_name(
const rocksdb_table_properties_t* props, size_t* size);
extern ROCKSDB_LIBRARY_API const char* rocksdb_table_properties_comparator_name(
const rocksdb_table_properties_t* props, size_t* size);
extern ROCKSDB_LIBRARY_API const char*
rocksdb_table_properties_merge_operator_name(
const rocksdb_table_properties_t* props, size_t* size);
extern ROCKSDB_LIBRARY_API const char*
rocksdb_table_properties_prefix_extractor_name(
const rocksdb_table_properties_t* props, size_t* size);
extern ROCKSDB_LIBRARY_API const char*
rocksdb_table_properties_property_collectors_names(
const rocksdb_table_properties_t* props, size_t* size);
extern ROCKSDB_LIBRARY_API const char*
rocksdb_table_properties_compression_name(
const rocksdb_table_properties_t* props, size_t* size);
extern ROCKSDB_LIBRARY_API const char*
rocksdb_table_properties_compression_options(
const rocksdb_table_properties_t* props, size_t* size);
extern ROCKSDB_LIBRARY_API const char*
rocksdb_table_properties_seqno_to_time_mapping(
const rocksdb_table_properties_t* props, size_t* size);
/* CompactionJobStats */
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_compaction_job_stats_elapsed_micros(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_compaction_job_stats_cpu_micros(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API unsigned char
rocksdb_compaction_job_stats_has_accurate_num_input_records(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compaction_job_stats_num_input_records(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_compaction_job_stats_num_blobs_read(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API size_t rocksdb_compaction_job_stats_num_input_files(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API size_t
rocksdb_compaction_job_stats_num_input_files_trivially_moved(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API size_t
rocksdb_compaction_job_stats_num_input_files_at_output_level(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API size_t
rocksdb_compaction_job_stats_num_filtered_input_files(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API size_t
rocksdb_compaction_job_stats_num_filtered_input_files_at_output_level(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compaction_job_stats_num_output_records(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API size_t rocksdb_compaction_job_stats_num_output_files(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API size_t
rocksdb_compaction_job_stats_num_output_files_blob(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API unsigned char
rocksdb_compaction_job_stats_is_full_compaction(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API unsigned char
rocksdb_compaction_job_stats_is_manual_compaction(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API unsigned char
rocksdb_compaction_job_stats_is_remote_compaction(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compaction_job_stats_total_input_bytes(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compaction_job_stats_total_blob_bytes_read(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compaction_job_stats_total_output_bytes(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compaction_job_stats_total_output_bytes_blob(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compaction_job_stats_total_skipped_input_bytes(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compaction_job_stats_num_records_replaced(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compaction_job_stats_total_input_raw_key_bytes(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compaction_job_stats_total_input_raw_value_bytes(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compaction_job_stats_num_input_deletion_records(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compaction_job_stats_num_expired_deletion_records(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compaction_job_stats_num_corrupt_keys(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compaction_job_stats_file_write_nanos(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compaction_job_stats_file_range_sync_nanos(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compaction_job_stats_file_fsync_nanos(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compaction_job_stats_file_prepare_write_nanos(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API const char*
rocksdb_compaction_job_stats_smallest_output_key_prefix(
const rocksdb_compaction_job_stats_t* stats, size_t* size);
extern ROCKSDB_LIBRARY_API const char*
rocksdb_compaction_job_stats_largest_output_key_prefix(
const rocksdb_compaction_job_stats_t* stats, size_t* size);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compaction_job_stats_num_single_del_fallthru(
const rocksdb_compaction_job_stats_t* stats);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compaction_job_stats_num_single_del_mismatch(
const rocksdb_compaction_job_stats_t* stats);
/* CompactionFileInfo */
extern ROCKSDB_LIBRARY_API int rocksdb_compaction_file_info_level(
const rocksdb_compaction_file_info_t* info);
extern ROCKSDB_LIBRARY_API uint64_t rocksdb_compaction_file_info_file_number(
const rocksdb_compaction_file_info_t* info);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_compaction_file_info_oldest_blob_file_number(
const rocksdb_compaction_file_info_t* info);
/* BlobFileAdditionInfo */
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_blob_file_addition_info_total_blob_count(
const rocksdb_blob_file_addition_info_t* info);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_blob_file_addition_info_total_blob_bytes(
const rocksdb_blob_file_addition_info_t* info);
/* BlobFileGarbageInfo */
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_blob_file_garbage_info_garbage_blob_count(
const rocksdb_blob_file_garbage_info_t* info);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_blob_file_garbage_info_garbage_blob_bytes(
const rocksdb_blob_file_garbage_info_t* info);
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,84 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/generate_c_api.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Source: tools/c_api_gen/spec.json
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/generate_c_api.py
// --spec tools/c_api_gen/spec.json --section 'Options simple'
// --header-out
// c_api_gen/c_generated_options_subset.h.inc
// --source-out
// c_api_gen/c_generated_options_subset.cc.inc
/* Options simple */
void rocksdb_options_set_compression_options_zstd_max_train_bytes(
rocksdb_options_t* opt, int zstd_max_train_bytes) {
opt->rep.compression_opts.zstd_max_train_bytes = zstd_max_train_bytes;
}
int rocksdb_options_get_compression_options_zstd_max_train_bytes(
rocksdb_options_t* opt) {
return opt->rep.compression_opts.zstd_max_train_bytes;
}
void rocksdb_options_set_compression_options_use_zstd_dict_trainer(
rocksdb_options_t* opt, unsigned char use_zstd_dict_trainer) {
opt->rep.compression_opts.use_zstd_dict_trainer = use_zstd_dict_trainer;
}
unsigned char rocksdb_options_get_compression_options_use_zstd_dict_trainer(
rocksdb_options_t* opt) {
return opt->rep.compression_opts.use_zstd_dict_trainer;
}
void rocksdb_options_set_compression_options_parallel_threads(
rocksdb_options_t* opt, int value) {
opt->rep.compression_opts.parallel_threads = value;
}
int rocksdb_options_get_compression_options_parallel_threads(
rocksdb_options_t* opt) {
return opt->rep.compression_opts.parallel_threads;
}
void rocksdb_options_set_compression_options_max_dict_buffer_bytes(
rocksdb_options_t* opt, uint64_t max_dict_buffer_bytes) {
opt->rep.compression_opts.max_dict_buffer_bytes = max_dict_buffer_bytes;
}
uint64_t rocksdb_options_get_compression_options_max_dict_buffer_bytes(
rocksdb_options_t* opt) {
return opt->rep.compression_opts.max_dict_buffer_bytes;
}
unsigned char
rocksdb_options_get_bottommost_compression_options_use_zstd_dict_trainer(
rocksdb_options_t* opt) {
return opt->rep.bottommost_compression_opts.use_zstd_dict_trainer;
}
void rocksdb_options_set_use_fsync(rocksdb_options_t* opt, int use_fsync) {
opt->rep.use_fsync = use_fsync;
}
int rocksdb_options_get_use_fsync(rocksdb_options_t* opt) {
return opt->rep.use_fsync;
}
void rocksdb_options_set_disable_auto_compactions(rocksdb_options_t* opt,
int disable) {
opt->rep.disable_auto_compactions = disable;
}
void rocksdb_options_set_optimize_filters_for_hits(rocksdb_options_t* opt,
int v) {
opt->rep.optimize_filters_for_hits = v;
}
void rocksdb_options_set_report_bg_io_stats(rocksdb_options_t* opt, int v) {
opt->rep.report_bg_io_stats = v;
}
@@ -0,0 +1,67 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/generate_c_api.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Source: tools/c_api_gen/spec.json
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/generate_c_api.py
// --spec tools/c_api_gen/spec.json --section 'Options simple'
// --header-out
// c_api_gen/c_generated_options_subset.h.inc
// --source-out
// c_api_gen/c_generated_options_subset.cc.inc
/* Options simple */
extern ROCKSDB_LIBRARY_API void
rocksdb_options_set_compression_options_zstd_max_train_bytes(
rocksdb_options_t* opt, int zstd_max_train_bytes);
extern ROCKSDB_LIBRARY_API int
rocksdb_options_get_compression_options_zstd_max_train_bytes(
rocksdb_options_t* opt);
extern ROCKSDB_LIBRARY_API void
rocksdb_options_set_compression_options_use_zstd_dict_trainer(
rocksdb_options_t* opt, unsigned char use_zstd_dict_trainer);
extern ROCKSDB_LIBRARY_API unsigned char
rocksdb_options_get_compression_options_use_zstd_dict_trainer(
rocksdb_options_t* opt);
extern ROCKSDB_LIBRARY_API void
rocksdb_options_set_compression_options_parallel_threads(rocksdb_options_t* opt,
int value);
extern ROCKSDB_LIBRARY_API int
rocksdb_options_get_compression_options_parallel_threads(
rocksdb_options_t* opt);
extern ROCKSDB_LIBRARY_API void
rocksdb_options_set_compression_options_max_dict_buffer_bytes(
rocksdb_options_t* opt, uint64_t max_dict_buffer_bytes);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_options_get_compression_options_max_dict_buffer_bytes(
rocksdb_options_t* opt);
extern ROCKSDB_LIBRARY_API unsigned char
rocksdb_options_get_bottommost_compression_options_use_zstd_dict_trainer(
rocksdb_options_t* opt);
extern ROCKSDB_LIBRARY_API void rocksdb_options_set_use_fsync(
rocksdb_options_t* opt, int use_fsync);
extern ROCKSDB_LIBRARY_API int rocksdb_options_get_use_fsync(
rocksdb_options_t* opt);
extern ROCKSDB_LIBRARY_API void rocksdb_options_set_disable_auto_compactions(
rocksdb_options_t* opt, int disable);
extern ROCKSDB_LIBRARY_API void rocksdb_options_set_optimize_filters_for_hits(
rocksdb_options_t* opt, int v);
extern ROCKSDB_LIBRARY_API void rocksdb_options_set_report_bg_io_stats(
rocksdb_options_t* opt, int v);
@@ -0,0 +1,236 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/auto_simple_bindings.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Sources:
// - include/rocksdb/options.h
// - tools/c_api_gen/auto_simple_bindings_blocklist.json
// - include/rocksdb/c.h
// - tools/c_api_gen/c_base.cc
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/auto_simple_bindings.py
// Output group: Auto-discovered ReadOptions simple
/* ReadOptions */
void rocksdb_readoptions_set_deadline(rocksdb_readoptions_t* opt,
uint64_t microseconds) {
opt->rep.deadline = std::chrono::microseconds(microseconds);
}
uint64_t rocksdb_readoptions_get_deadline(rocksdb_readoptions_t* opt) {
return opt->rep.deadline.count();
}
void rocksdb_readoptions_set_io_timeout(rocksdb_readoptions_t* opt,
uint64_t microseconds) {
opt->rep.io_timeout = std::chrono::microseconds(microseconds);
}
uint64_t rocksdb_readoptions_get_io_timeout(rocksdb_readoptions_t* opt) {
return opt->rep.io_timeout.count();
}
void rocksdb_readoptions_set_read_tier(rocksdb_readoptions_t* opt, int v) {
opt->rep.read_tier = static_cast<decltype(opt->rep.read_tier)>(v);
}
int rocksdb_readoptions_get_read_tier(rocksdb_readoptions_t* opt) {
return static_cast<int>(opt->rep.read_tier);
}
void rocksdb_readoptions_set_rate_limiter_priority(rocksdb_readoptions_t* opt,
int v) {
opt->rep.rate_limiter_priority =
static_cast<decltype(opt->rep.rate_limiter_priority)>(v);
}
int rocksdb_readoptions_get_rate_limiter_priority(rocksdb_readoptions_t* opt) {
return static_cast<int>(opt->rep.rate_limiter_priority);
}
void rocksdb_readoptions_set_value_size_soft_limit(rocksdb_readoptions_t* opt,
uint64_t v) {
opt->rep.value_size_soft_limit = v;
}
uint64_t rocksdb_readoptions_get_value_size_soft_limit(
rocksdb_readoptions_t* opt) {
return opt->rep.value_size_soft_limit;
}
void rocksdb_readoptions_set_verify_checksums(rocksdb_readoptions_t* opt,
unsigned char v) {
opt->rep.verify_checksums = v;
}
unsigned char rocksdb_readoptions_get_verify_checksums(
rocksdb_readoptions_t* opt) {
return opt->rep.verify_checksums;
}
void rocksdb_readoptions_set_fill_cache(rocksdb_readoptions_t* opt,
unsigned char v) {
opt->rep.fill_cache = v;
}
unsigned char rocksdb_readoptions_get_fill_cache(rocksdb_readoptions_t* opt) {
return opt->rep.fill_cache;
}
void rocksdb_readoptions_set_ignore_range_deletions(rocksdb_readoptions_t* opt,
unsigned char v) {
opt->rep.ignore_range_deletions = v;
}
unsigned char rocksdb_readoptions_get_ignore_range_deletions(
rocksdb_readoptions_t* opt) {
return opt->rep.ignore_range_deletions;
}
void rocksdb_readoptions_set_async_io(rocksdb_readoptions_t* opt,
unsigned char v) {
opt->rep.async_io = v;
}
unsigned char rocksdb_readoptions_get_async_io(rocksdb_readoptions_t* opt) {
return opt->rep.async_io;
}
void rocksdb_readoptions_set_optimize_multiget_for_io(
rocksdb_readoptions_t* opt, unsigned char v) {
opt->rep.optimize_multiget_for_io = v;
}
unsigned char rocksdb_readoptions_get_optimize_multiget_for_io(
rocksdb_readoptions_t* opt) {
return opt->rep.optimize_multiget_for_io;
}
void rocksdb_readoptions_set_readahead_size(rocksdb_readoptions_t* opt,
size_t v) {
opt->rep.readahead_size = v;
}
size_t rocksdb_readoptions_get_readahead_size(rocksdb_readoptions_t* opt) {
return opt->rep.readahead_size;
}
void rocksdb_readoptions_set_max_skippable_internal_keys(
rocksdb_readoptions_t* opt, uint64_t v) {
opt->rep.max_skippable_internal_keys = v;
}
uint64_t rocksdb_readoptions_get_max_skippable_internal_keys(
rocksdb_readoptions_t* opt) {
return opt->rep.max_skippable_internal_keys;
}
void rocksdb_readoptions_set_tailing(rocksdb_readoptions_t* opt,
unsigned char v) {
opt->rep.tailing = v;
}
unsigned char rocksdb_readoptions_get_tailing(rocksdb_readoptions_t* opt) {
return opt->rep.tailing;
}
void rocksdb_readoptions_set_total_order_seek(rocksdb_readoptions_t* opt,
unsigned char v) {
opt->rep.total_order_seek = v;
}
unsigned char rocksdb_readoptions_get_total_order_seek(
rocksdb_readoptions_t* opt) {
return opt->rep.total_order_seek;
}
void rocksdb_readoptions_set_auto_prefix_mode(rocksdb_readoptions_t* opt,
unsigned char v) {
opt->rep.auto_prefix_mode = v;
}
unsigned char rocksdb_readoptions_get_auto_prefix_mode(
rocksdb_readoptions_t* opt) {
return opt->rep.auto_prefix_mode;
}
void rocksdb_readoptions_set_prefix_same_as_start(rocksdb_readoptions_t* opt,
unsigned char v) {
opt->rep.prefix_same_as_start = v;
}
unsigned char rocksdb_readoptions_get_prefix_same_as_start(
rocksdb_readoptions_t* opt) {
return opt->rep.prefix_same_as_start;
}
void rocksdb_readoptions_set_pin_data(rocksdb_readoptions_t* opt,
unsigned char v) {
opt->rep.pin_data = v;
}
unsigned char rocksdb_readoptions_get_pin_data(rocksdb_readoptions_t* opt) {
return opt->rep.pin_data;
}
void rocksdb_readoptions_set_adaptive_readahead(rocksdb_readoptions_t* opt,
unsigned char v) {
opt->rep.adaptive_readahead = v;
}
unsigned char rocksdb_readoptions_get_adaptive_readahead(
rocksdb_readoptions_t* opt) {
return opt->rep.adaptive_readahead;
}
void rocksdb_readoptions_set_background_purge_on_iterator_cleanup(
rocksdb_readoptions_t* opt, unsigned char v) {
opt->rep.background_purge_on_iterator_cleanup = v;
}
unsigned char rocksdb_readoptions_get_background_purge_on_iterator_cleanup(
rocksdb_readoptions_t* opt) {
return opt->rep.background_purge_on_iterator_cleanup;
}
void rocksdb_readoptions_set_auto_readahead_size(rocksdb_readoptions_t* opt,
unsigned char v) {
opt->rep.auto_readahead_size = v;
}
unsigned char rocksdb_readoptions_get_auto_readahead_size(
rocksdb_readoptions_t* opt) {
return opt->rep.auto_readahead_size;
}
void rocksdb_readoptions_set_allow_unprepared_value(rocksdb_readoptions_t* opt,
unsigned char v) {
opt->rep.allow_unprepared_value = v;
}
unsigned char rocksdb_readoptions_get_allow_unprepared_value(
rocksdb_readoptions_t* opt) {
return opt->rep.allow_unprepared_value;
}
void rocksdb_readoptions_set_auto_refresh_iterator_with_snapshot(
rocksdb_readoptions_t* opt, unsigned char v) {
opt->rep.auto_refresh_iterator_with_snapshot = v;
}
unsigned char rocksdb_readoptions_get_auto_refresh_iterator_with_snapshot(
rocksdb_readoptions_t* opt) {
return opt->rep.auto_refresh_iterator_with_snapshot;
}
void rocksdb_readoptions_set_io_activity(rocksdb_readoptions_t* opt, int v) {
opt->rep.io_activity = static_cast<decltype(opt->rep.io_activity)>(v);
}
int rocksdb_readoptions_get_io_activity(rocksdb_readoptions_t* opt) {
return static_cast<int>(opt->rep.io_activity);
}
@@ -0,0 +1,161 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/auto_simple_bindings.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Sources:
// - include/rocksdb/options.h
// - tools/c_api_gen/auto_simple_bindings_blocklist.json
// - include/rocksdb/c.h
// - tools/c_api_gen/c_base.cc
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/auto_simple_bindings.py
// Output group: Auto-discovered ReadOptions simple
/* ReadOptions */
extern ROCKSDB_LIBRARY_API void rocksdb_readoptions_set_deadline(
rocksdb_readoptions_t* opt, uint64_t microseconds);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_readoptions_get_deadline(rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void rocksdb_readoptions_set_io_timeout(
rocksdb_readoptions_t* opt, uint64_t microseconds);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_readoptions_get_io_timeout(rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void rocksdb_readoptions_set_read_tier(
rocksdb_readoptions_t* opt, int v);
extern ROCKSDB_LIBRARY_API int rocksdb_readoptions_get_read_tier(
rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void rocksdb_readoptions_set_rate_limiter_priority(
rocksdb_readoptions_t* opt, int v);
extern ROCKSDB_LIBRARY_API int rocksdb_readoptions_get_rate_limiter_priority(
rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void rocksdb_readoptions_set_value_size_soft_limit(
rocksdb_readoptions_t* opt, uint64_t v);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_readoptions_get_value_size_soft_limit(rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void rocksdb_readoptions_set_verify_checksums(
rocksdb_readoptions_t* opt, unsigned char v);
extern ROCKSDB_LIBRARY_API unsigned char
rocksdb_readoptions_get_verify_checksums(rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void rocksdb_readoptions_set_fill_cache(
rocksdb_readoptions_t* opt, unsigned char v);
extern ROCKSDB_LIBRARY_API unsigned char rocksdb_readoptions_get_fill_cache(
rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void rocksdb_readoptions_set_ignore_range_deletions(
rocksdb_readoptions_t* opt, unsigned char v);
extern ROCKSDB_LIBRARY_API unsigned char
rocksdb_readoptions_get_ignore_range_deletions(rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void rocksdb_readoptions_set_async_io(
rocksdb_readoptions_t* opt, unsigned char v);
extern ROCKSDB_LIBRARY_API unsigned char rocksdb_readoptions_get_async_io(
rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void
rocksdb_readoptions_set_optimize_multiget_for_io(rocksdb_readoptions_t* opt,
unsigned char v);
extern ROCKSDB_LIBRARY_API unsigned char
rocksdb_readoptions_get_optimize_multiget_for_io(rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void rocksdb_readoptions_set_readahead_size(
rocksdb_readoptions_t* opt, size_t v);
extern ROCKSDB_LIBRARY_API size_t
rocksdb_readoptions_get_readahead_size(rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void
rocksdb_readoptions_set_max_skippable_internal_keys(rocksdb_readoptions_t* opt,
uint64_t v);
extern ROCKSDB_LIBRARY_API uint64_t
rocksdb_readoptions_get_max_skippable_internal_keys(rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void rocksdb_readoptions_set_tailing(
rocksdb_readoptions_t* opt, unsigned char v);
extern ROCKSDB_LIBRARY_API unsigned char rocksdb_readoptions_get_tailing(
rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void rocksdb_readoptions_set_total_order_seek(
rocksdb_readoptions_t* opt, unsigned char v);
extern ROCKSDB_LIBRARY_API unsigned char
rocksdb_readoptions_get_total_order_seek(rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void rocksdb_readoptions_set_auto_prefix_mode(
rocksdb_readoptions_t* opt, unsigned char v);
extern ROCKSDB_LIBRARY_API unsigned char
rocksdb_readoptions_get_auto_prefix_mode(rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void rocksdb_readoptions_set_prefix_same_as_start(
rocksdb_readoptions_t* opt, unsigned char v);
extern ROCKSDB_LIBRARY_API unsigned char
rocksdb_readoptions_get_prefix_same_as_start(rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void rocksdb_readoptions_set_pin_data(
rocksdb_readoptions_t* opt, unsigned char v);
extern ROCKSDB_LIBRARY_API unsigned char rocksdb_readoptions_get_pin_data(
rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void rocksdb_readoptions_set_adaptive_readahead(
rocksdb_readoptions_t* opt, unsigned char v);
extern ROCKSDB_LIBRARY_API unsigned char
rocksdb_readoptions_get_adaptive_readahead(rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void
rocksdb_readoptions_set_background_purge_on_iterator_cleanup(
rocksdb_readoptions_t* opt, unsigned char v);
extern ROCKSDB_LIBRARY_API unsigned char
rocksdb_readoptions_get_background_purge_on_iterator_cleanup(
rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void rocksdb_readoptions_set_auto_readahead_size(
rocksdb_readoptions_t* opt, unsigned char v);
extern ROCKSDB_LIBRARY_API unsigned char
rocksdb_readoptions_get_auto_readahead_size(rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void rocksdb_readoptions_set_allow_unprepared_value(
rocksdb_readoptions_t* opt, unsigned char v);
extern ROCKSDB_LIBRARY_API unsigned char
rocksdb_readoptions_get_allow_unprepared_value(rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void
rocksdb_readoptions_set_auto_refresh_iterator_with_snapshot(
rocksdb_readoptions_t* opt, unsigned char v);
extern ROCKSDB_LIBRARY_API unsigned char
rocksdb_readoptions_get_auto_refresh_iterator_with_snapshot(
rocksdb_readoptions_t* opt);
extern ROCKSDB_LIBRARY_API void rocksdb_readoptions_set_io_activity(
rocksdb_readoptions_t* opt, int v);
extern ROCKSDB_LIBRARY_API int rocksdb_readoptions_get_io_activity(
rocksdb_readoptions_t* opt);
File diff suppressed because it is too large Load Diff
+371
View File
@@ -0,0 +1,371 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/generate_c_api.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Source: tools/c_api_gen/spec.json
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/generate_c_api.py
// --spec tools/c_api_gen/spec.json --section 'DB data operations'
// --section 'WriteBatch' --section 'Transaction'
// --section 'TransactionDB simple'
// --header-out
// c_api_gen/c_generated_subset.h.inc
// --source-out
// c_api_gen/c_generated_subset.cc.inc
/* DB data operations */
void rocksdb_put(rocksdb_t* db, const rocksdb_writeoptions_t* options,
const char* key, size_t keylen, const char* val, size_t vallen,
char** errptr) {
SaveError(errptr,
db->rep->Put(options->rep, Slice(key, keylen), Slice(val, vallen)));
}
void rocksdb_put_cf(rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family,
const char* key, size_t keylen, const char* val,
size_t vallen, char** errptr) {
SaveError(errptr, db->rep->Put(options->rep, column_family->rep,
Slice(key, keylen), Slice(val, vallen)));
}
void rocksdb_delete(rocksdb_t* db, const rocksdb_writeoptions_t* options,
const char* key, size_t keylen, char** errptr) {
SaveError(errptr, db->rep->Delete(options->rep, Slice(key, keylen)));
}
void rocksdb_delete_cf(rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family,
const char* key, size_t keylen, char** errptr) {
SaveError(errptr, db->rep->Delete(options->rep, column_family->rep,
Slice(key, keylen)));
}
void rocksdb_merge(rocksdb_t* db, const rocksdb_writeoptions_t* options,
const char* key, size_t keylen, const char* val,
size_t vallen, char** errptr) {
SaveError(errptr, db->rep->Merge(options->rep, Slice(key, keylen),
Slice(val, vallen)));
}
void rocksdb_merge_cf(rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family,
const char* key, size_t keylen, const char* val,
size_t vallen, char** errptr) {
SaveError(errptr, db->rep->Merge(options->rep, column_family->rep,
Slice(key, keylen), Slice(val, vallen)));
}
void rocksdb_write(rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_writebatch_t* batch, char** errptr) {
SaveError(errptr, db->rep->Write(options->rep, &batch->rep));
}
void rocksdb_put_with_ts(rocksdb_t* db, const rocksdb_writeoptions_t* options,
const char* key, size_t keylen, const char* ts,
size_t tslen, const char* val, size_t vallen,
char** errptr) {
SaveError(errptr, db->rep->Put(options->rep, Slice(key, keylen),
Slice(ts, tslen), Slice(val, vallen)));
}
void rocksdb_put_cf_with_ts(rocksdb_t* db,
const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family,
const char* key, size_t keylen, const char* ts,
size_t tslen, const char* val, size_t vallen,
char** errptr) {
SaveError(errptr,
db->rep->Put(options->rep, column_family->rep, Slice(key, keylen),
Slice(ts, tslen), Slice(val, vallen)));
}
void rocksdb_delete_with_ts(rocksdb_t* db,
const rocksdb_writeoptions_t* options,
const char* key, size_t keylen, const char* ts,
size_t tslen, char** errptr) {
SaveError(errptr, db->rep->Delete(options->rep, Slice(key, keylen),
Slice(ts, tslen)));
}
void rocksdb_delete_cf_with_ts(rocksdb_t* db,
const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family,
const char* key, size_t keylen, const char* ts,
size_t tslen, char** errptr) {
SaveError(errptr, db->rep->Delete(options->rep, column_family->rep,
Slice(key, keylen), Slice(ts, tslen)));
}
void rocksdb_singledelete(rocksdb_t* db, const rocksdb_writeoptions_t* options,
const char* key, size_t keylen, char** errptr) {
SaveError(errptr, db->rep->SingleDelete(options->rep, Slice(key, keylen)));
}
void rocksdb_singledelete_cf(rocksdb_t* db,
const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family,
const char* key, size_t keylen, char** errptr) {
SaveError(errptr, db->rep->SingleDelete(options->rep, column_family->rep,
Slice(key, keylen)));
}
void rocksdb_singledelete_with_ts(rocksdb_t* db,
const rocksdb_writeoptions_t* options,
const char* key, size_t keylen,
const char* ts, size_t tslen, char** errptr) {
SaveError(errptr, db->rep->SingleDelete(options->rep, Slice(key, keylen),
Slice(ts, tslen)));
}
void rocksdb_singledelete_cf_with_ts(
rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, const char* ts, size_t tslen, char** errptr) {
SaveError(errptr,
db->rep->SingleDelete(options->rep, column_family->rep,
Slice(key, keylen), Slice(ts, tslen)));
}
void rocksdb_delete_range_cf(rocksdb_t* db,
const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family,
const char* start_key, size_t start_key_len,
const char* end_key, size_t end_key_len,
char** errptr) {
SaveError(errptr, db->rep->DeleteRange(options->rep, column_family->rep,
Slice(start_key, start_key_len),
Slice(end_key, end_key_len)));
}
void rocksdb_flush(rocksdb_t* db, const rocksdb_flushoptions_t* options,
char** errptr) {
SaveError(errptr, db->rep->Flush(options->rep));
}
void rocksdb_flush_cf(rocksdb_t* db, const rocksdb_flushoptions_t* options,
rocksdb_column_family_handle_t* column_family,
char** errptr) {
SaveError(errptr, db->rep->Flush(options->rep, column_family->rep));
}
void rocksdb_flush_wal(rocksdb_t* db, unsigned char sync, char** errptr) {
SaveError(errptr, db->rep->FlushWAL(sync));
}
void rocksdb_pause_background_work(rocksdb_t* db, char** errptr) {
SaveError(errptr, db->rep->PauseBackgroundWork());
}
void rocksdb_continue_background_work(rocksdb_t* db, char** errptr) {
SaveError(errptr, db->rep->ContinueBackgroundWork());
}
void rocksdb_disable_file_deletions(rocksdb_t* db, char** errptr) {
SaveError(errptr, db->rep->DisableFileDeletions());
}
void rocksdb_enable_file_deletions(rocksdb_t* db, char** errptr) {
SaveError(errptr, db->rep->EnableFileDeletions());
}
void rocksdb_verify_checksum(rocksdb_t* db, char** errptr) {
SaveError(errptr, db->rep->VerifyChecksum());
}
void rocksdb_verify_file_checksums(rocksdb_t* db, char** errptr) {
SaveError(errptr, db->rep->VerifyFileChecksums(ReadOptions()));
}
void rocksdb_destroy_db(const rocksdb_options_t* options, const char* name,
char** errptr) {
SaveError(errptr, DestroyDB(name, options->rep));
}
void rocksdb_repair_db(const rocksdb_options_t* options, const char* name,
char** errptr) {
SaveError(errptr, RepairDB(name, options->rep));
}
/* WriteBatch */
void rocksdb_writebatch_clear(rocksdb_writebatch_t* b) { b->rep.Clear(); }
void rocksdb_writebatch_put(rocksdb_writebatch_t* b, const char* key,
size_t klen, const char* val, size_t vlen) {
b->rep.Put(Slice(key, klen), Slice(val, vlen));
}
void rocksdb_writebatch_put_cf(rocksdb_writebatch_t* b,
rocksdb_column_family_handle_t* column_family,
const char* key, size_t klen, const char* val,
size_t vlen) {
b->rep.Put(column_family->rep, Slice(key, klen), Slice(val, vlen));
}
void rocksdb_writebatch_delete(rocksdb_writebatch_t* b, const char* key,
size_t klen) {
b->rep.Delete(Slice(key, klen));
}
void rocksdb_writebatch_put_log_data(rocksdb_writebatch_t* b, const char* blob,
size_t len) {
b->rep.PutLogData(Slice(blob, len));
}
void rocksdb_writebatch_set_save_point(rocksdb_writebatch_t* b) {
b->rep.SetSavePoint();
}
void rocksdb_writebatch_rollback_to_save_point(rocksdb_writebatch_t* b,
char** errptr) {
SaveError(errptr, b->rep.RollbackToSavePoint());
}
void rocksdb_writebatch_pop_save_point(rocksdb_writebatch_t* b, char** errptr) {
SaveError(errptr, b->rep.PopSavePoint());
}
void rocksdb_writebatch_verify_checksum(rocksdb_writebatch_t* b,
char** errptr) {
SaveError(errptr, b->rep.VerifyChecksum());
}
/* Transaction */
void rocksdb_transaction_put(rocksdb_transaction_t* txn, const char* key,
size_t klen, const char* val, size_t vlen,
char** errptr) {
SaveError(errptr, txn->rep->Put(Slice(key, klen), Slice(val, vlen)));
}
void rocksdb_transaction_put_cf(rocksdb_transaction_t* txn,
rocksdb_column_family_handle_t* column_family,
const char* key, size_t klen, const char* val,
size_t vlen, char** errptr) {
SaveError(errptr, txn->rep->Put(column_family->rep, Slice(key, klen),
Slice(val, vlen)));
}
void rocksdb_transaction_merge(rocksdb_transaction_t* txn, const char* key,
size_t klen, const char* val, size_t vlen,
char** errptr) {
SaveError(errptr, txn->rep->Merge(Slice(key, klen), Slice(val, vlen)));
}
void rocksdb_transaction_merge_cf(rocksdb_transaction_t* txn,
rocksdb_column_family_handle_t* column_family,
const char* key, size_t klen, const char* val,
size_t vlen, char** errptr) {
SaveError(errptr, txn->rep->Merge(column_family->rep, Slice(key, klen),
Slice(val, vlen)));
}
void rocksdb_transaction_delete(rocksdb_transaction_t* txn, const char* key,
size_t klen, char** errptr) {
SaveError(errptr, txn->rep->Delete(Slice(key, klen)));
}
void rocksdb_transaction_delete_cf(
rocksdb_transaction_t* txn, rocksdb_column_family_handle_t* column_family,
const char* key, size_t klen, char** errptr) {
SaveError(errptr, txn->rep->Delete(column_family->rep, Slice(key, klen)));
}
void rocksdb_transaction_commit(rocksdb_transaction_t* txn, char** errptr) {
SaveError(errptr, txn->rep->Commit());
}
void rocksdb_transaction_rollback(rocksdb_transaction_t* txn, char** errptr) {
SaveError(errptr, txn->rep->Rollback());
}
void rocksdb_transaction_put_log_data(rocksdb_transaction_t* txn,
const char* blob, size_t len) {
txn->rep->PutLogData(Slice(blob, len));
}
void rocksdb_transaction_set_savepoint(rocksdb_transaction_t* txn) {
txn->rep->SetSavePoint();
}
void rocksdb_transaction_rollback_to_savepoint(rocksdb_transaction_t* txn,
char** errptr) {
SaveError(errptr, txn->rep->RollbackToSavePoint());
}
/* TransactionDB simple */
void rocksdb_transactiondb_put(rocksdb_transactiondb_t* txn_db,
const rocksdb_writeoptions_t* options,
const char* key, size_t klen, const char* val,
size_t vlen, char** errptr) {
SaveError(errptr,
txn_db->rep->Put(options->rep, Slice(key, klen), Slice(val, vlen)));
}
void rocksdb_transactiondb_put_cf(rocksdb_transactiondb_t* txn_db,
const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family,
const char* key, size_t keylen,
const char* val, size_t vallen,
char** errptr) {
SaveError(errptr, txn_db->rep->Put(options->rep, column_family->rep,
Slice(key, keylen), Slice(val, vallen)));
}
void rocksdb_transactiondb_write(rocksdb_transactiondb_t* db,
const rocksdb_writeoptions_t* options,
rocksdb_writebatch_t* batch, char** errptr) {
SaveError(errptr, db->rep->Write(options->rep, &batch->rep));
}
void rocksdb_transactiondb_merge(rocksdb_transactiondb_t* txn_db,
const rocksdb_writeoptions_t* options,
const char* key, size_t klen, const char* val,
size_t vlen, char** errptr) {
SaveError(errptr, txn_db->rep->Merge(options->rep, Slice(key, klen),
Slice(val, vlen)));
}
void rocksdb_transactiondb_merge_cf(
rocksdb_transactiondb_t* txn_db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key, size_t klen,
const char* val, size_t vlen, char** errptr) {
SaveError(errptr, txn_db->rep->Merge(options->rep, column_family->rep,
Slice(key, klen), Slice(val, vlen)));
}
void rocksdb_transactiondb_delete(rocksdb_transactiondb_t* txn_db,
const rocksdb_writeoptions_t* options,
const char* key, size_t klen, char** errptr) {
SaveError(errptr, txn_db->rep->Delete(options->rep, Slice(key, klen)));
}
void rocksdb_transactiondb_delete_cf(
rocksdb_transactiondb_t* txn_db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, char** errptr) {
SaveError(errptr, txn_db->rep->Delete(options->rep, column_family->rep,
Slice(key, keylen)));
}
void rocksdb_transactiondb_flush_wal(rocksdb_transactiondb_t* txn_db,
unsigned char sync, char** errptr) {
SaveError(errptr, txn_db->rep->FlushWAL(sync));
}
void rocksdb_transactiondb_flush(rocksdb_transactiondb_t* txn_db,
const rocksdb_flushoptions_t* options,
char** errptr) {
SaveError(errptr, txn_db->rep->Flush(options->rep));
}
void rocksdb_transactiondb_flush_cf(
rocksdb_transactiondb_t* txn_db, const rocksdb_flushoptions_t* options,
rocksdb_column_family_handle_t* column_family, char** errptr) {
SaveError(errptr, txn_db->rep->Flush(options->rep, column_family->rep));
}
+245
View File
@@ -0,0 +1,245 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/generate_c_api.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Source: tools/c_api_gen/spec.json
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/generate_c_api.py
// --spec tools/c_api_gen/spec.json --section 'DB data operations'
// --section 'WriteBatch' --section 'Transaction'
// --section 'TransactionDB simple'
// --header-out
// c_api_gen/c_generated_subset.h.inc
// --source-out
// c_api_gen/c_generated_subset.cc.inc
/* DB data operations */
extern ROCKSDB_LIBRARY_API void rocksdb_put(
rocksdb_t* db, const rocksdb_writeoptions_t* options, const char* key,
size_t keylen, const char* val, size_t vallen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_put_cf(
rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, const char* val, size_t vallen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_delete(
rocksdb_t* db, const rocksdb_writeoptions_t* options, const char* key,
size_t keylen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_delete_cf(
rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_merge(
rocksdb_t* db, const rocksdb_writeoptions_t* options, const char* key,
size_t keylen, const char* val, size_t vallen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_merge_cf(
rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, const char* val, size_t vallen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_write(
rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_writebatch_t* batch, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_put_with_ts(
rocksdb_t* db, const rocksdb_writeoptions_t* options, const char* key,
size_t keylen, const char* ts, size_t tslen, const char* val, size_t vallen,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_put_cf_with_ts(
rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, const char* ts, size_t tslen, const char* val, size_t vallen,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_delete_with_ts(
rocksdb_t* db, const rocksdb_writeoptions_t* options, const char* key,
size_t keylen, const char* ts, size_t tslen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_delete_cf_with_ts(
rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, const char* ts, size_t tslen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_singledelete(
rocksdb_t* db, const rocksdb_writeoptions_t* options, const char* key,
size_t keylen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_singledelete_cf(
rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_singledelete_with_ts(
rocksdb_t* db, const rocksdb_writeoptions_t* options, const char* key,
size_t keylen, const char* ts, size_t tslen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_singledelete_cf_with_ts(
rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, const char* ts, size_t tslen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_delete_range_cf(
rocksdb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* start_key,
size_t start_key_len, const char* end_key, size_t end_key_len,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_flush(
rocksdb_t* db, const rocksdb_flushoptions_t* options, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_flush_cf(
rocksdb_t* db, const rocksdb_flushoptions_t* options,
rocksdb_column_family_handle_t* column_family, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_flush_wal(rocksdb_t* db,
unsigned char sync,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_pause_background_work(rocksdb_t* db,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_continue_background_work(rocksdb_t* db,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_disable_file_deletions(rocksdb_t* db,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_enable_file_deletions(rocksdb_t* db,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_verify_checksum(rocksdb_t* db,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_verify_file_checksums(rocksdb_t* db,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_destroy_db(
const rocksdb_options_t* options, const char* name, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_repair_db(
const rocksdb_options_t* options, const char* name, char** errptr);
/* WriteBatch */
extern ROCKSDB_LIBRARY_API void rocksdb_writebatch_clear(
rocksdb_writebatch_t* b);
extern ROCKSDB_LIBRARY_API void rocksdb_writebatch_put(rocksdb_writebatch_t* b,
const char* key,
size_t klen,
const char* val,
size_t vlen);
extern ROCKSDB_LIBRARY_API void rocksdb_writebatch_put_cf(
rocksdb_writebatch_t* b, rocksdb_column_family_handle_t* column_family,
const char* key, size_t klen, const char* val, size_t vlen);
extern ROCKSDB_LIBRARY_API void rocksdb_writebatch_delete(
rocksdb_writebatch_t* b, const char* key, size_t klen);
extern ROCKSDB_LIBRARY_API void rocksdb_writebatch_put_log_data(
rocksdb_writebatch_t* b, const char* blob, size_t len);
extern ROCKSDB_LIBRARY_API void rocksdb_writebatch_set_save_point(
rocksdb_writebatch_t* b);
extern ROCKSDB_LIBRARY_API void rocksdb_writebatch_rollback_to_save_point(
rocksdb_writebatch_t* b, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_writebatch_pop_save_point(
rocksdb_writebatch_t* b, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_writebatch_verify_checksum(
rocksdb_writebatch_t* b, char** errptr);
/* Transaction */
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_put(
rocksdb_transaction_t* txn, const char* key, size_t klen, const char* val,
size_t vlen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_put_cf(
rocksdb_transaction_t* txn, rocksdb_column_family_handle_t* column_family,
const char* key, size_t klen, const char* val, size_t vlen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_merge(
rocksdb_transaction_t* txn, const char* key, size_t klen, const char* val,
size_t vlen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_merge_cf(
rocksdb_transaction_t* txn, rocksdb_column_family_handle_t* column_family,
const char* key, size_t klen, const char* val, size_t vlen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_delete(
rocksdb_transaction_t* txn, const char* key, size_t klen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_delete_cf(
rocksdb_transaction_t* txn, rocksdb_column_family_handle_t* column_family,
const char* key, size_t klen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_commit(
rocksdb_transaction_t* txn, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_rollback(
rocksdb_transaction_t* txn, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_put_log_data(
rocksdb_transaction_t* txn, const char* blob, size_t len);
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_set_savepoint(
rocksdb_transaction_t* txn);
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_rollback_to_savepoint(
rocksdb_transaction_t* txn, char** errptr);
/* TransactionDB simple */
extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_put(
rocksdb_transactiondb_t* txn_db, const rocksdb_writeoptions_t* options,
const char* key, size_t klen, const char* val, size_t vlen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_put_cf(
rocksdb_transactiondb_t* txn_db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, const char* val, size_t vallen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_write(
rocksdb_transactiondb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_writebatch_t* batch, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_merge(
rocksdb_transactiondb_t* txn_db, const rocksdb_writeoptions_t* options,
const char* key, size_t klen, const char* val, size_t vlen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_merge_cf(
rocksdb_transactiondb_t* txn_db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key, size_t klen,
const char* val, size_t vlen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_delete(
rocksdb_transactiondb_t* txn_db, const rocksdb_writeoptions_t* options,
const char* key, size_t klen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_delete_cf(
rocksdb_transactiondb_t* txn_db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_flush_wal(
rocksdb_transactiondb_t* txn_db, unsigned char sync, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_flush(
rocksdb_transactiondb_t* txn_db, const rocksdb_flushoptions_t* options,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_flush_cf(
rocksdb_transactiondb_t* txn_db, const rocksdb_flushoptions_t* options,
rocksdb_column_family_handle_t* column_family, char** errptr);
@@ -0,0 +1,77 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/generate_c_api.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Source: tools/c_api_gen/spec.json
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/generate_c_api.py
// --spec tools/c_api_gen/spec.json --section 'Transaction'
// --header-out
// c_api_gen/c_generated_transaction_subset.h.inc
// --source-out
// c_api_gen/c_generated_transaction_subset.cc.inc
/* Transaction */
void rocksdb_transaction_put(rocksdb_transaction_t* txn, const char* key,
size_t klen, const char* val, size_t vlen,
char** errptr) {
SaveError(errptr, txn->rep->Put(Slice(key, klen), Slice(val, vlen)));
}
void rocksdb_transaction_put_cf(rocksdb_transaction_t* txn,
rocksdb_column_family_handle_t* column_family,
const char* key, size_t klen, const char* val,
size_t vlen, char** errptr) {
SaveError(errptr, txn->rep->Put(column_family->rep, Slice(key, klen),
Slice(val, vlen)));
}
void rocksdb_transaction_merge(rocksdb_transaction_t* txn, const char* key,
size_t klen, const char* val, size_t vlen,
char** errptr) {
SaveError(errptr, txn->rep->Merge(Slice(key, klen), Slice(val, vlen)));
}
void rocksdb_transaction_merge_cf(rocksdb_transaction_t* txn,
rocksdb_column_family_handle_t* column_family,
const char* key, size_t klen, const char* val,
size_t vlen, char** errptr) {
SaveError(errptr, txn->rep->Merge(column_family->rep, Slice(key, klen),
Slice(val, vlen)));
}
void rocksdb_transaction_delete(rocksdb_transaction_t* txn, const char* key,
size_t klen, char** errptr) {
SaveError(errptr, txn->rep->Delete(Slice(key, klen)));
}
void rocksdb_transaction_delete_cf(
rocksdb_transaction_t* txn, rocksdb_column_family_handle_t* column_family,
const char* key, size_t klen, char** errptr) {
SaveError(errptr, txn->rep->Delete(column_family->rep, Slice(key, klen)));
}
void rocksdb_transaction_commit(rocksdb_transaction_t* txn, char** errptr) {
SaveError(errptr, txn->rep->Commit());
}
void rocksdb_transaction_rollback(rocksdb_transaction_t* txn, char** errptr) {
SaveError(errptr, txn->rep->Rollback());
}
void rocksdb_transaction_put_log_data(rocksdb_transaction_t* txn,
const char* blob, size_t len) {
txn->rep->PutLogData(Slice(blob, len));
}
void rocksdb_transaction_set_savepoint(rocksdb_transaction_t* txn) {
txn->rep->SetSavePoint();
}
void rocksdb_transaction_rollback_to_savepoint(rocksdb_transaction_t* txn,
char** errptr) {
SaveError(errptr, txn->rep->RollbackToSavePoint());
}
@@ -0,0 +1,54 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/generate_c_api.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Source: tools/c_api_gen/spec.json
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/generate_c_api.py
// --spec tools/c_api_gen/spec.json --section 'Transaction'
// --header-out
// c_api_gen/c_generated_transaction_subset.h.inc
// --source-out
// c_api_gen/c_generated_transaction_subset.cc.inc
/* Transaction */
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_put(
rocksdb_transaction_t* txn, const char* key, size_t klen, const char* val,
size_t vlen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_put_cf(
rocksdb_transaction_t* txn, rocksdb_column_family_handle_t* column_family,
const char* key, size_t klen, const char* val, size_t vlen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_merge(
rocksdb_transaction_t* txn, const char* key, size_t klen, const char* val,
size_t vlen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_merge_cf(
rocksdb_transaction_t* txn, rocksdb_column_family_handle_t* column_family,
const char* key, size_t klen, const char* val, size_t vlen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_delete(
rocksdb_transaction_t* txn, const char* key, size_t klen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_delete_cf(
rocksdb_transaction_t* txn, rocksdb_column_family_handle_t* column_family,
const char* key, size_t klen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_commit(
rocksdb_transaction_t* txn, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_rollback(
rocksdb_transaction_t* txn, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_put_log_data(
rocksdb_transaction_t* txn, const char* blob, size_t len);
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_set_savepoint(
rocksdb_transaction_t* txn);
extern ROCKSDB_LIBRARY_API void rocksdb_transaction_rollback_to_savepoint(
rocksdb_transaction_t* txn, char** errptr);
@@ -0,0 +1,87 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/generate_c_api.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Source: tools/c_api_gen/spec.json
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/generate_c_api.py
// --spec tools/c_api_gen/spec.json --section 'TransactionDB simple'
// --header-out
// c_api_gen/c_generated_transactiondb_subset.h.inc
// --source-out
// c_api_gen/c_generated_transactiondb_subset.cc.inc
/* TransactionDB simple */
void rocksdb_transactiondb_put(rocksdb_transactiondb_t* txn_db,
const rocksdb_writeoptions_t* options,
const char* key, size_t klen, const char* val,
size_t vlen, char** errptr) {
SaveError(errptr,
txn_db->rep->Put(options->rep, Slice(key, klen), Slice(val, vlen)));
}
void rocksdb_transactiondb_put_cf(rocksdb_transactiondb_t* txn_db,
const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family,
const char* key, size_t keylen,
const char* val, size_t vallen,
char** errptr) {
SaveError(errptr, txn_db->rep->Put(options->rep, column_family->rep,
Slice(key, keylen), Slice(val, vallen)));
}
void rocksdb_transactiondb_write(rocksdb_transactiondb_t* db,
const rocksdb_writeoptions_t* options,
rocksdb_writebatch_t* batch, char** errptr) {
SaveError(errptr, db->rep->Write(options->rep, &batch->rep));
}
void rocksdb_transactiondb_merge(rocksdb_transactiondb_t* txn_db,
const rocksdb_writeoptions_t* options,
const char* key, size_t klen, const char* val,
size_t vlen, char** errptr) {
SaveError(errptr, txn_db->rep->Merge(options->rep, Slice(key, klen),
Slice(val, vlen)));
}
void rocksdb_transactiondb_merge_cf(
rocksdb_transactiondb_t* txn_db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key, size_t klen,
const char* val, size_t vlen, char** errptr) {
SaveError(errptr, txn_db->rep->Merge(options->rep, column_family->rep,
Slice(key, klen), Slice(val, vlen)));
}
void rocksdb_transactiondb_delete(rocksdb_transactiondb_t* txn_db,
const rocksdb_writeoptions_t* options,
const char* key, size_t klen, char** errptr) {
SaveError(errptr, txn_db->rep->Delete(options->rep, Slice(key, klen)));
}
void rocksdb_transactiondb_delete_cf(
rocksdb_transactiondb_t* txn_db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, char** errptr) {
SaveError(errptr, txn_db->rep->Delete(options->rep, column_family->rep,
Slice(key, keylen)));
}
void rocksdb_transactiondb_flush_wal(rocksdb_transactiondb_t* txn_db,
unsigned char sync, char** errptr) {
SaveError(errptr, txn_db->rep->FlushWAL(sync));
}
void rocksdb_transactiondb_flush(rocksdb_transactiondb_t* txn_db,
const rocksdb_flushoptions_t* options,
char** errptr) {
SaveError(errptr, txn_db->rep->Flush(options->rep));
}
void rocksdb_transactiondb_flush_cf(
rocksdb_transactiondb_t* txn_db, const rocksdb_flushoptions_t* options,
rocksdb_column_family_handle_t* column_family, char** errptr) {
SaveError(errptr, txn_db->rep->Flush(options->rep, column_family->rep));
}
@@ -0,0 +1,58 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/generate_c_api.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Source: tools/c_api_gen/spec.json
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/generate_c_api.py
// --spec tools/c_api_gen/spec.json --section 'TransactionDB simple'
// --header-out
// c_api_gen/c_generated_transactiondb_subset.h.inc
// --source-out
// c_api_gen/c_generated_transactiondb_subset.cc.inc
/* TransactionDB simple */
extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_put(
rocksdb_transactiondb_t* txn_db, const rocksdb_writeoptions_t* options,
const char* key, size_t klen, const char* val, size_t vlen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_put_cf(
rocksdb_transactiondb_t* txn_db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, const char* val, size_t vallen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_write(
rocksdb_transactiondb_t* db, const rocksdb_writeoptions_t* options,
rocksdb_writebatch_t* batch, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_merge(
rocksdb_transactiondb_t* txn_db, const rocksdb_writeoptions_t* options,
const char* key, size_t klen, const char* val, size_t vlen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_merge_cf(
rocksdb_transactiondb_t* txn_db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key, size_t klen,
const char* val, size_t vlen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_delete(
rocksdb_transactiondb_t* txn_db, const rocksdb_writeoptions_t* options,
const char* key, size_t klen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_delete_cf(
rocksdb_transactiondb_t* txn_db, const rocksdb_writeoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t keylen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_flush_wal(
rocksdb_transactiondb_t* txn_db, unsigned char sync, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_flush(
rocksdb_transactiondb_t* txn_db, const rocksdb_flushoptions_t* options,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_flush_cf(
rocksdb_transactiondb_t* txn_db, const rocksdb_flushoptions_t* options,
rocksdb_column_family_handle_t* column_family, char** errptr);
@@ -0,0 +1,58 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/generate_c_api.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Source: tools/c_api_gen/spec.json
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/generate_c_api.py
// --spec tools/c_api_gen/spec.json --section 'WriteBatch'
// --header-out
// c_api_gen/c_generated_writebatch_subset.h.inc
// --source-out
// c_api_gen/c_generated_writebatch_subset.cc.inc
/* WriteBatch */
void rocksdb_writebatch_clear(rocksdb_writebatch_t* b) { b->rep.Clear(); }
void rocksdb_writebatch_put(rocksdb_writebatch_t* b, const char* key,
size_t klen, const char* val, size_t vlen) {
b->rep.Put(Slice(key, klen), Slice(val, vlen));
}
void rocksdb_writebatch_put_cf(rocksdb_writebatch_t* b,
rocksdb_column_family_handle_t* column_family,
const char* key, size_t klen, const char* val,
size_t vlen) {
b->rep.Put(column_family->rep, Slice(key, klen), Slice(val, vlen));
}
void rocksdb_writebatch_delete(rocksdb_writebatch_t* b, const char* key,
size_t klen) {
b->rep.Delete(Slice(key, klen));
}
void rocksdb_writebatch_put_log_data(rocksdb_writebatch_t* b, const char* blob,
size_t len) {
b->rep.PutLogData(Slice(blob, len));
}
void rocksdb_writebatch_set_save_point(rocksdb_writebatch_t* b) {
b->rep.SetSavePoint();
}
void rocksdb_writebatch_rollback_to_save_point(rocksdb_writebatch_t* b,
char** errptr) {
SaveError(errptr, b->rep.RollbackToSavePoint());
}
void rocksdb_writebatch_pop_save_point(rocksdb_writebatch_t* b, char** errptr) {
SaveError(errptr, b->rep.PopSavePoint());
}
void rocksdb_writebatch_verify_checksum(rocksdb_writebatch_t* b,
char** errptr) {
SaveError(errptr, b->rep.VerifyChecksum());
}
@@ -0,0 +1,47 @@
// @generated
// -----------------------------------------------------------------------------
// Auto-generated by tools/c_api_gen/generate_c_api.py.
// DO NOT EDIT THIS FILE DIRECTLY.
// Source: tools/c_api_gen/spec.json
// -----------------------------------------------------------------------------
// To regenerate this file:
// python3 tools/c_api_gen/generate_c_api.py
// --spec tools/c_api_gen/spec.json --section 'WriteBatch'
// --header-out
// c_api_gen/c_generated_writebatch_subset.h.inc
// --source-out
// c_api_gen/c_generated_writebatch_subset.cc.inc
/* WriteBatch */
extern ROCKSDB_LIBRARY_API void rocksdb_writebatch_clear(
rocksdb_writebatch_t* b);
extern ROCKSDB_LIBRARY_API void rocksdb_writebatch_put(rocksdb_writebatch_t* b,
const char* key,
size_t klen,
const char* val,
size_t vlen);
extern ROCKSDB_LIBRARY_API void rocksdb_writebatch_put_cf(
rocksdb_writebatch_t* b, rocksdb_column_family_handle_t* column_family,
const char* key, size_t klen, const char* val, size_t vlen);
extern ROCKSDB_LIBRARY_API void rocksdb_writebatch_delete(
rocksdb_writebatch_t* b, const char* key, size_t klen);
extern ROCKSDB_LIBRARY_API void rocksdb_writebatch_put_log_data(
rocksdb_writebatch_t* b, const char* blob, size_t len);
extern ROCKSDB_LIBRARY_API void rocksdb_writebatch_set_save_point(
rocksdb_writebatch_t* b);
extern ROCKSDB_LIBRARY_API void rocksdb_writebatch_rollback_to_save_point(
rocksdb_writebatch_t* b, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_writebatch_pop_save_point(
rocksdb_writebatch_t* b, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_writebatch_verify_checksum(
rocksdb_writebatch_t* b, char** errptr);
+24 -1
View File
@@ -421,6 +421,30 @@ Example reference: commit `429b36c22d76403d275dd0e6877b08d4cea2bc90` (block_alig
If an option already exists but needs C API support:
**First decide whether the option is auto-managed.**
Many simple option fields are no longer maintained by hand in
`include/rocksdb/c.h` and `db/c.cc`. Before adding a manual wrapper:
- Check whether the option belongs to a family handled by
`tools/c_api_gen/auto_simple_bindings.py`.
- If it is a simple scalar/enum/string field in an auto-managed family, run
`python3 tools/c_api_gen/regen_all.py` and let the generator add the C API.
- After regenerating, run
`python3 tools/c_api_gen/verify_generated_up_to_date.py` to confirm the
checked-in generated fragments stay stable.
- Do not edit generated `.inc` files under `c_api_gen/` by hand.
- If the new field is not ready for C API support yet, add an entry to
`tools/c_api_gen/auto_simple_bindings_blocklist.json` with
`"policy": "deferred"` and a concrete reason so the build stays intentional
rather than silently drifting.
- If the field needs custom ownership, callback, vector, or nested-struct
marshalling, keep it manual or move it into `tools/c_api_gen/spec.json`
depending on the API shape.
If the option is not auto-managed, or the C API really is a custom/manual case,
the traditional hand-written pattern still applies:
**File: `db/c.cc`**
```cpp
@@ -509,4 +533,3 @@ Common option types used in serialization:
- [ ] unreleased_history markdown file
- [ ] Java API (for BlockBasedTableOptions)
- [ ] C API (if needed)
+46 -5
View File
@@ -168,9 +168,18 @@ Status YourNewAPI(const YourAPIOptions& /*options*/,
### Step 5: Add C API Bindings
**Header:** `include/rocksdb/c.h`
> **Important:** `include/rocksdb/c.h` and `db/c.cc` are `@generated` and must
> NOT be edited by hand — your changes would be overwritten on the next
> regeneration. Choose the right path first (see "Before writing C API code by
> hand" below). For hand-written (manual) wrappers, edit the source templates
> `tools/c_api_gen/c_base.h` (declarations) and `tools/c_api_gen/c_base.cc`
> (implementations), then run `python3 tools/c_api_gen/regen_all.py` to produce
> `c.h` / `c.cc`. The snippets below show the *declaration* and *implementation*
> you would add to those templates.
\`\`\`c
**Header (declaration → `tools/c_api_gen/c_base.h`):**
```c
// Basic version
extern ROCKSDB_LIBRARY_API void rocksdb_your_new_api(
rocksdb_t* db,
@@ -191,7 +200,7 @@ extern ROCKSDB_LIBRARY_API void rocksdb_your_new_api_opt(
char** errptr);
\`\`\`
**Implementation:** `db/c.cc`
**Implementation (→ `tools/c_api_gen/c_base.cc`):**
\`\`\`cpp
void rocksdb_your_new_api(rocksdb_t* db, const char* start_key,
@@ -217,6 +226,38 @@ void rocksdb_your_new_api_cf(rocksdb_t* db,
}
\`\`\`
**Before writing C API code by hand, choose the right path:**
- **Auto-managed simple struct fields:** If you added a new field to a managed
public struct such as `ReadOptions`, selected option structs, or managed
metadata structs, first check `tools/c_api_gen/auto_simple_bindings.py`.
Simple scalar/enum/string fields should be regenerated with
`python3 tools/c_api_gen/regen_all.py` rather than hand-editing
`include/rocksdb/c.h` / `db/c.cc`.
After regenerating, run
`python3 tools/c_api_gen/verify_generated_up_to_date.py` to confirm the
checked-in generated fragments are stable.
- **Spec-driven wrappers:** If the API is still mechanically generated but needs
an explicit C shape, naming, or `Status`/`char** errptr` policy, add it to
`tools/c_api_gen/spec.json`.
- **Fully manual wrappers:** If the API uses callbacks, ownership transfer,
vectors/maps, open flows, or otherwise irregular marshalling, keep the C API
hand-written.
**Temporary deferral for auto-managed families:**
If a new field lands in an auto-managed family but the C API shape is not ready
yet, add a checked-in entry to
`tools/c_api_gen/auto_simple_bindings_blocklist.json` with:
- `policy: "manual"` when the field is intentionally outside simple auto-gen
- `policy: "deferred"` when the field should be revisited later
- a concrete `reason`
- `tracking_issue` when available
If a field in an auto-managed family is not supported by the generator and is
not covered by the blocklist, regeneration should fail. That is intentional.
**If you have options, also add:**
\`\`\`cpp
@@ -482,8 +523,8 @@ public class YourAPIOptionsTest {
| StackableDB | `include/rocksdb/utilities/stackable_db.h` | ✓ |
| Secondary DB | `db/db_impl/db_impl_secondary.h` | If not supported |
| Compacted DB | `db/db_impl/compacted_db_impl.h` | If not supported |
| C API Header | `include/rocksdb/c.h` | ✓ |
| C API Implementation | `db/c.cc` | ✓ |
| C API Header (manual wrappers) | `tools/c_api_gen/c_base.h` → regen → `include/rocksdb/c.h` (`@generated`) | ✓ |
| C API Implementation (manual wrappers) | `tools/c_api_gen/c_base.cc` → regen → `db/c.cc` (`@generated`) | ✓ |
| Java API | `java/src/main/java/org/rocksdb/RocksDB.java` | ✓ |
| Java Options | `java/src/main/java/org/rocksdb/YourAPIOptions.java` | If needed |
| JNI Implementation | `java/rocksjni/rocksjni.cc` | ✓ |
+6505 -1872
View File
File diff suppressed because it is too large Load Diff
+1757 -4
View File
File diff suppressed because it is too large Load Diff
+3254 -521
View File
File diff suppressed because it is too large Load Diff
@@ -12,6 +12,7 @@
#include <cinttypes>
#include <cstdint>
#include <memory>
#include <mutex>
#include <string>
#include "cache/cache_entry_roles.h"
@@ -28,12 +29,14 @@
#include "rocksdb/table.h"
#include "rocksdb/user_defined_index.h"
#include "rocksdb/utilities/customizable_util.h"
#include "rocksdb/utilities/object_registry.h"
#include "rocksdb/utilities/options_type.h"
#include "table/block_based/block_based_table_builder.h"
#include "table/block_based/block_based_table_reader.h"
#include "table/format.h"
#include "util/mutexlock.h"
#include "util/string_util.h"
#include "utilities/trie_index/trie_index_factory.h"
namespace ROCKSDB_NAMESPACE {
@@ -1127,6 +1130,11 @@ TableFactory* NewBlockBasedTableFactory(
Status UserDefinedIndexFactory::CreateFromString(
const ConfigOptions& config_options, const std::string& value,
std::shared_ptr<UserDefinedIndexFactory>* factory) {
static std::once_flag once;
std::call_once(once, [&]() {
trie_index::RegisterBuiltinTrieIndexFactory(
*(ObjectLibrary::Default().get()), "");
});
return LoadSharedObject<UserDefinedIndexFactory>(config_options, value,
factory);
}
+350
View File
@@ -0,0 +1,350 @@
# RocksDB C API Code Generation Prototype
This directory contains a **prototype** for semi-automating parts of
RocksDB's C API based on the existing C++ public API and the current C API
conventions in `include/rocksdb/c.h` / `db/c.cc`.
The intent is **not** to automatically wrap arbitrary C++ APIs. Instead, the
goal is to reduce maintenance burden for the parts of the C API that are
already highly mechanical today.
## Why a semi-automated approach
RocksDB's C API follows stable conventions that downstream users rely on:
- opaque handle types like `rocksdb_t*`, `rocksdb_transaction_t*`
- `Status` translated to `char** errptr`
- `Slice` translated to `const char*` + `size_t`
- binary/string results copied into `malloc()`-owned buffers
- booleans represented as `unsigned char`
- `rocksdb_<object>_<verb>[_cf][_with_ts]` naming
These conventions are valuable and should remain the source of truth for the
generated code.
At the same time, the C++ public API includes features that are poor fits for
fully automatic wrapper generation:
- callback-backed polymorphic types (`Comparator`, `MergeOperator`, etc.)
- complex object construction/open flows
- ownership-transferring factory setters
- vector-heavy marshalling APIs like the `MultiGet` family
- virtual extension points and custom bridging logic
For those cases, hand-designed wrappers remain the right tool.
## Why the spec-driven generator still exists
The spec-driven generator is still needed for wrappers whose C shape cannot be
reliably inferred from the C++ declaration alone.
Yes, this means `spec.json` is manually maintained. That is intentional. The
goal is not to eliminate human decisions; the goal is to stop hand-writing the
same declaration/definition boilerplate once those decisions have been made.
For many wrappers, someone still has to decide:
- the C function name and parameter order
- whether a C++ `Status` becomes `char** errptr`
- whether default C++ objects should be synthesized, such as `ReadOptions()`
- how ownership and lifetime should work for pointers, factories, and callbacks
- how vectors, maps, and option collections should be flattened into C
- whether the C API should intentionally differ from the C++ API shape
Those are API design choices, not mechanical translations. The spec-driven
path keeps those choices explicit while still generating consistent boilerplate.
Backward compatibility with the existing hand-written C API is one input, but
it is not the primary reason this layer exists. Even for brand-new wrappers, we
still need an explicit policy layer for non-trivial C bindings.
## What this prototype focuses on
The generator currently targets representative examples from the easiest and
most repetitive wrapper families:
1. **Simple scalar field setters/getters**
- `rocksdb_options_set_create_if_missing`
- `rocksdb_options_get_create_if_missing`
- `rocksdb_readoptions_set_fill_cache`
- `rocksdb_writeoptions_set_sync`
- `rocksdb_block_based_options_set_block_size`
- `rocksdb_cuckoo_options_set_hash_ratio`
2. **Simple forwarding wrappers with no `Status`**
- `rocksdb_writebatch_clear`
- `rocksdb_writebatch_put`
- `rocksdb_writebatch_put_cf`
- `rocksdb_writebatch_delete`
- `rocksdb_writebatch_put_log_data`
- `rocksdb_writebatch_set_save_point`
- `rocksdb_transaction_set_savepoint`
3. **Simple forwarding wrappers with `Status` -> `char** errptr`**
- `rocksdb_put`, `rocksdb_put_cf`
- `rocksdb_delete`, `rocksdb_delete_cf`
- `rocksdb_merge`, `rocksdb_merge_cf`
- `rocksdb_write`
- `rocksdb_writebatch_rollback_to_save_point`
- `rocksdb_writebatch_pop_save_point`
- `rocksdb_transaction_put`, `rocksdb_transaction_put_cf`
- `rocksdb_transaction_merge`, `rocksdb_transaction_merge_cf`
- `rocksdb_transaction_delete`, `rocksdb_transaction_delete_cf`
- `rocksdb_transaction_commit`
- `rocksdb_transaction_rollback`
- `rocksdb_transaction_rollback_to_savepoint`
4. **Simple metadata accessors**
- `rocksdb_flushjobinfo_cf_name`
- `rocksdb_flushjobinfo_largest_seqno`
This is intentionally a constrained subset. The point is to demonstrate a
maintainable pattern and a spec format that can be extended gradually.
## What should remain manual
These families should stay hand-written unless a future design adds a much
richer generator:
- comparators / merge operators / compaction filters / event listeners
- compaction service wrappers
- openers and constructors that build vectors/maps of descriptors/options
- `MultiGet` / batched `MultiGet` families
- wrappers involving `std::shared_ptr` / `std::unique_ptr` ownership transfer
- C APIs whose behavior intentionally differs from the C++ API shape
## Design principles
### 1. Keep the current C API conventions
The code generator should not invent a new style. It should emit code that
looks like today's hand-written wrappers:
- `SaveError(errptr, ...)`
- `Slice(key, keylen)`
- direct field assignments for plain option setters
- same function names and signatures
### 2. Let auto-discovery handle the simple direct cases
For a small set of mechanically mappable public structs, the generator can
discover missing bindings directly from the C++ headers and emit the missing C
wrappers automatically. Existing handwritten wrappers still win when they
already exist.
Today this strict auto-discovery path is used for:
- simple `ReadOptions` scalar / enum fields
- simple scalar / enum fields across selected public option structs
- simple metadata fields on listener/job-info structs
- simple metadata view structs such as table-properties and compaction metadata
For those managed families, unsupported or intentionally deferred fields must
be explicitly recorded in `auto_simple_bindings_blocklist.json` rather than
being skipped silently. Anything outside those families remains hand-written.
### 3. Keep explicit spec for non-trivial wrappers
The spec-driven generator remains the right tool for method-style wrappers and
other APIs whose C surface requires an explicit design decision. In practice:
- auto-discovery owns simple direct field coverage for selected struct families
- `spec.json` owns wrappers that are still manual in design but repetitive in
implementation
- fully irregular ownership-heavy or callback-heavy APIs remain hand-written
### 4. Let C++ headers guide validation, not policy
Longer term, Clang/libTooling can help validate that a wrapper spec still
matches the underlying C++ method signature. But the C naming, ownership, and
error-handling policy should remain explicit in the spec.
## Files
Source templates (hand-written; NOT user-includable and NOT compiled directly):
- `c_base.h`
- hand-written template for `include/rocksdb/c.h`; the generated `.h.inc`
fragments are inlined into it to produce the self-contained public header
- `c_base.cc`
- hand-written template for `db/c.cc`; the generated `.cc.inc` fragments are
inlined into it to produce the compiled implementation
Generators and inputs:
- `spec.json`
- declarative input for the spec-driven generator
- `generate_c_api.py`
- emits header/source fragments from the spec
- `auto_simple_bindings.py`
- auto-discovers simple public field bindings and generates checked-in
`.inc` files for them
- `auto_simple_bindings_blocklist.json`
- checked-in exceptions for auto-managed fields that are intentionally manual
or temporarily deferred
- `abi_type_overrides.json`
- per-function C type pins so already-shipped wrappers keep their historical
C signature even when the C++ field type maps to a different C type
- `regen_all.py`
- orchestrates both generators and inlines the fragments into `c.h` / `c.cc`
Verification (run by `make check-c-api-gen` and in CI):
- `check_api_completeness.py`
- asserts every declared public C function has exactly one definition
(dependency-free; guards against link-time breakage of bindings)
- `check_api_compatibility.py` + `api_compatibility_allowlist.json`
- signature-level backward-compatibility gate against a reference revision;
the authoritative ABI/API-stability check
- `verify_generated_up_to_date.py`
- regenerates in a temp dir and confirms the checked-in output is current
- `validate_generated_equivalence.py` + `equivalence_allowlist.json`
- best-effort migration aid: compares generated wrapper *bodies* against a
PRE-migration hand-written revision. Body comparison is heuristic; for
backward-compatibility rely on `check_api_compatibility.py`.
## Toolchain requirements
Regeneration needs two external tools:
- **`clang++`** (libclang) — used to dump the C++ struct ASTs that drive
auto-discovery. Resolution order is `$CXX` (if it names a clang), then bare
`clang++`, then versioned fallbacks (`clang++-21``clang++-13`).
- **`clang-format`** — used to canonicalize the generated `.inc` fragments (and
therefore the inlined `c.h` / `c.cc`).
The checked-in generated output is byte-reproducible only for a **pinned
clang-format version**. CI uses **clang-format-21** (see
`.github/workflows/pr-jobs.yml`); pin the same version locally so your
regeneration matches CI:
```bash
python3 tools/c_api_gen/regen_all.py --clang-format clang-format-21
# or, when running the staleness check via make:
make check-c-api-gen CLANG_FORMAT_BINARY=clang-format-21
```
If `clang++` is not installed, `make check` skips the C API staleness check
with a message instead of failing, so it still works without the codegen
toolchain. CI is the authoritative gate.
The dedicated `build-linux-clang-21-no_test_run` CI job runs this target with
`CHECK_C_API_GEN_STRICT=1`, which turns every such "skip" (missing `clang++` or
clang-format, or an unresolvable compat baseline ref) into a hard error, so the
core CI coverage cannot silently regress to a no-op:
```bash
make check-c-api-gen CHECK_C_API_GEN_STRICT=1 CLANG_FORMAT_BINARY=clang-format-21
```
## Running the generators
From the repo root, to regenerate all checked-in fragments and the inlined
`c.h` / `c.cc`:
```bash
python3 tools/c_api_gen/regen_all.py
```
This regenerates:
- the spec-driven fragments from `spec.json`
- the auto-discovered fragments produced by `auto_simple_bindings.py`
- the round-trip tests produced by `gen_roundtrip_tests.py`
To preview only the spec-driven output for one section without touching the
checked-in fragments, run `generate_c_api.py` directly with `--header-out` /
`--source-out` pointing at a scratch path (e.g. under `/tmp`).
To verify the auto-discovered checked-in output is up to date:
```bash
python3 tools/c_api_gen/auto_simple_bindings.py --check
```
To verify the full checked-in generated set is stable without relying on Git
worktree metadata:
```bash
python3 tools/c_api_gen/verify_generated_up_to_date.py
```
## Maintaining Auto-Managed Families
When a new public field is added to an auto-managed family, use this decision
process:
1. If it is a simple scalar, enum, string, or supported chrono field and the
desired C API shape matches the existing conventions, do not hand-edit
`include/rocksdb/c.h` or `db/c.cc`. Run `python3 tools/c_api_gen/regen_all.py`
and let `auto_simple_bindings.py` generate the wrapper.
2. If the field needs an explicit C API design because of ownership, callbacks,
vectors, maps, nested structs, or intentionally different C naming/behavior,
keep it out of auto-generation by adding an entry to
`tools/c_api_gen/auto_simple_bindings_blocklist.json` with
`"policy": "manual"`.
3. If the field belongs to an auto-managed family but you intentionally want to
postpone C API coverage for a short time, add a blocklist entry with
`"policy": "deferred"` and a concrete reason. Include `tracking_issue` when
you have one.
4. If none of the above applies, the build should fail. Extend
`auto_simple_bindings.py`, add a spec-driven wrapper, or add a hand-written
wrapper and then update the blocklist policy accordingly.
The blocklist is intentionally strict:
- each entry must identify the managed family and field
- each entry must have a non-empty reason
- policy must be either `manual` or `deferred`
- stale entries fail regeneration if the field disappears or is renamed
Example deferred entry:
```json
{
"name": "ReadOptions",
"entries": [
{
"field": "future_slice_option",
"policy": "deferred",
"reason": "Needs an explicit C buffer ownership design before exposing it.",
"tracking_issue": "T123456789"
}
]
}
```
The blocklist only applies to the auto-managed families handled by
`auto_simple_bindings.py`. It is not a substitute for `spec.json`, which still
owns non-trivial method-style wrappers. It is also unrelated to
`equivalence_allowlist.json`, which only suppresses intentional diff mismatches
in the equivalence checker.
To refresh the full checked-in generated set and confirm nothing changes:
```bash
python3 tools/c_api_gen/verify_generated_up_to_date.py
```
To verify active generated wrappers are equivalent to the handwritten wrappers
from a reference revision:
```bash
python3 tools/c_api_gen/validate_generated_equivalence.py --ref HEAD
```
This checks the generated fragments currently included by
`include/rocksdb/c.h` and `db/c.cc` against `HEAD:include/rocksdb/c.h` and
`HEAD:db/c.cc`. Known historical inconsistencies can be documented in
`equivalence_allowlist.json` with a reason instead of being silently ignored.
## Suggested migration path
1. Start with generated preview fragments only.
2. Migrate a few low-risk existing wrappers to generated sections.
3. Keep manual and generated sections clearly separated.
4. Let auto-discovery pick up new simple public fields automatically.
5. Extend the spec or keep manual wrappers for complex/manual families.
This incremental approach minimizes downstream impact while still reducing
maintenance burden over time.
+60
View File
@@ -0,0 +1,60 @@
{
"schema_version": 1,
"description": [
"ABI-preserving C type overrides for auto-generated C API wrappers.",
"",
"RocksDB's C API has a strong backward-compatibility guarantee: the C",
"signature of a function that has already shipped must never change, even",
"when the underlying C++ field type would naturally map to a different C",
"type. The auto-generator derives the C type from the C++ field (e.g. bool",
"-> unsigned char, uint64_t -> uint64_t, an enum -> int). For a handful of",
"pre-existing functions the historical hand-written C type differs from",
"that natural mapping, so we pin it here. The generated body still casts to",
"the real C++ field type via static_cast<decltype(field)>(value), so the",
"behavior is identical -- only the public C parameter/return type is held",
"stable.",
"",
"Only add entries for functions that already shipped with a different type.",
"Brand-new functions should use the natural mapping. The equivalence",
"validator (validate_generated_equivalence.py) enforces that generated",
"signatures match the reference revision, so any unintended drift here will",
"fail CI."
],
"overrides": [
{
"function": "rocksdb_writeoptions_disable_WAL",
"role": "setter",
"c_type": "int",
"field_cxx_type": "bool",
"reason": "Shipped as `int disable` long before codegen; the field is bool but the C parameter type must stay `int` for ABI compatibility."
},
{
"function": "rocksdb_restore_options_set_keep_log_files",
"role": "setter",
"c_type": "int",
"field_cxx_type": "bool",
"reason": "Shipped as `int v`; the field is bool but the C parameter type must stay `int` for ABI compatibility."
},
{
"function": "rocksdb_block_based_options_set_checksum",
"role": "setter",
"c_type": "char",
"field_cxx_type": "ChecksumType",
"reason": "Shipped as `char`; the field is the ChecksumType enum but the C parameter type must stay `char` for ABI compatibility."
},
{
"function": "rocksdb_block_based_options_set_format_version",
"role": "setter",
"c_type": "int",
"field_cxx_type": "uint32_t",
"reason": "Shipped as `int`; the field is uint32_t but the C parameter type must stay `int` for ABI compatibility."
},
{
"function": "rocksdb_block_based_options_set_block_size",
"role": "setter",
"c_type": "size_t",
"field_cxx_type": "uint64_t",
"reason": "Shipped as `size_t block_size`; the field is uint64_t but the C parameter type must stay `size_t` for ABI compatibility."
}
]
}
@@ -0,0 +1,19 @@
{
"schema_version": 1,
"description": [
"Documented, intentional backward-incompatible changes to the public C API",
"(include/rocksdb/c.h), checked by check_api_compatibility.py.",
"",
"Each entry suppresses one otherwise-failing finding. 'kind' is 'removed'",
"(a function that existed in the baseline is gone) or 'changed' (its",
"signature changed). Only add entries for changes that are deliberate and",
"reviewed; every entry needs a reason."
],
"allow": [
{
"kind": "removed",
"function": "rocksdb_writebatch_wi_create_from",
"reason": "Declared in c.h but never implemented anywhere in RocksDB (WriteBatchWithIndex has no constructor from a serialized representation). The symbol never existed, so no consumer could have linked against it; the dead declaration was removed."
}
]
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,590 @@
{
"schema_version": 1,
"families": [
{
"name": "ReadOptions",
"entries": [
{
"field": "snapshot",
"policy": "manual",
"reason": "Needs pointer, slice, callback, or other non-trivial C binding policy that the simple generator cannot infer."
},
{
"field": "timestamp",
"policy": "manual",
"reason": "Needs pointer, slice, callback, or other non-trivial C binding policy that the simple generator cannot infer."
},
{
"field": "iter_start_ts",
"policy": "manual",
"reason": "Needs pointer, slice, callback, or other non-trivial C binding policy that the simple generator cannot infer."
},
{
"field": "merge_operand_count_threshold",
"policy": "manual",
"reason": "Needs pointer, slice, callback, or other non-trivial C binding policy that the simple generator cannot infer."
},
{
"field": "iterate_lower_bound",
"policy": "manual",
"reason": "Needs pointer, slice, callback, or other non-trivial C binding policy that the simple generator cannot infer."
},
{
"field": "iterate_upper_bound",
"policy": "manual",
"reason": "Needs pointer, slice, callback, or other non-trivial C binding policy that the simple generator cannot infer."
},
{
"field": "table_filter",
"policy": "manual",
"reason": "Needs pointer, slice, callback, or other non-trivial C binding policy that the simple generator cannot infer."
},
{
"field": "table_index_factory",
"policy": "manual",
"reason": "Needs pointer, slice, callback, or other non-trivial C binding policy that the simple generator cannot infer."
},
{
"field": "request_id",
"policy": "manual",
"reason": "Needs pointer, slice, callback, or other non-trivial C binding policy that the simple generator cannot infer."
},
{
"field": "read_scoped_block_buffer_provider",
"policy": "manual",
"reason": "Field type 'ReadScopedBlockBufferProvider *' is a pointer/owning handle to a complex type; needs an explicit C ownership and lifetime design rather than a simple scalar/enum/string wrapper."
}
]
},
{
"name": "DBOptions",
"entries": [
{
"field": "env",
"policy": "manual",
"reason": "Stores external objects, callback collections, or nested aggregates that need explicit C ownership and lifetime policy."
},
{
"field": "rate_limiter",
"policy": "manual",
"reason": "Stores external objects, callback collections, or nested aggregates that need explicit C ownership and lifetime policy."
},
{
"field": "sst_file_manager",
"policy": "manual",
"reason": "Stores external objects, callback collections, or nested aggregates that need explicit C ownership and lifetime policy."
},
{
"field": "info_log",
"policy": "manual",
"reason": "Stores external objects, callback collections, or nested aggregates that need explicit C ownership and lifetime policy."
},
{
"field": "statistics",
"policy": "manual",
"reason": "Stores external objects, callback collections, or nested aggregates that need explicit C ownership and lifetime policy."
},
{
"field": "db_paths",
"policy": "manual",
"reason": "Stores external objects, callback collections, or nested aggregates that need explicit C ownership and lifetime policy."
},
{
"field": "write_buffer_manager",
"policy": "manual",
"reason": "Stores external objects, callback collections, or nested aggregates that need explicit C ownership and lifetime policy."
},
{
"field": "listeners",
"policy": "manual",
"reason": "Stores external objects, callback collections, or nested aggregates that need explicit C ownership and lifetime policy."
},
{
"field": "row_cache",
"policy": "manual",
"reason": "Stores external objects, callback collections, or nested aggregates that need explicit C ownership and lifetime policy."
},
{
"field": "wal_filter",
"policy": "manual",
"reason": "Stores external objects, callback collections, or nested aggregates that need explicit C ownership and lifetime policy."
},
{
"field": "file_checksum_gen_factory",
"policy": "manual",
"reason": "Stores external objects, callback collections, or nested aggregates that need explicit C ownership and lifetime policy."
},
{
"field": "checksum_handoff_file_types",
"policy": "manual",
"reason": "Stores external objects, callback collections, or nested aggregates that need explicit C ownership and lifetime policy."
},
{
"field": "compaction_service",
"policy": "manual",
"reason": "Stores external objects, callback collections, or nested aggregates that need explicit C ownership and lifetime policy."
},
{
"field": "calculate_sst_write_lifetime_hint_set",
"policy": "manual",
"reason": "Stores external objects, callback collections, or nested aggregates that need explicit C ownership and lifetime policy."
},
{
"field": "max_manifest_file_size",
"policy": "manual",
"reason": "ABI type mismatch: legacy C API uses size_t but C++ field is uint64_t. Hand-written binding preserved for ABI compatibility."
},
{
"field": "writable_file_max_buffer_size",
"policy": "manual",
"reason": "ABI type mismatch: legacy C API uses uint64_t but C++ field is size_t. Hand-written binding preserved for ABI compatibility."
}
]
},
{
"name": "AdvancedColumnFamilyOptions",
"entries": [
{
"field": "inplace_callback",
"policy": "manual",
"reason": "Uses callbacks, factories, vectors, or nested option structs that need explicit C bridging."
},
{
"field": "memtable_insert_with_hint_prefix_extractor",
"policy": "manual",
"reason": "Uses callbacks, factories, vectors, or nested option structs that need explicit C bridging."
},
{
"field": "compression_per_level",
"policy": "manual",
"reason": "Uses callbacks, factories, vectors, or nested option structs that need explicit C bridging."
},
{
"field": "max_bytes_for_level_multiplier_additional",
"policy": "manual",
"reason": "Uses callbacks, factories, vectors, or nested option structs that need explicit C bridging."
},
{
"field": "compaction_options_universal",
"policy": "manual",
"reason": "Uses callbacks, factories, vectors, or nested option structs that need explicit C bridging."
},
{
"field": "compaction_options_fifo",
"policy": "manual",
"reason": "Uses callbacks, factories, vectors, or nested option structs that need explicit C bridging."
},
{
"field": "memtable_factory",
"policy": "manual",
"reason": "Uses callbacks, factories, vectors, or nested option structs that need explicit C bridging."
},
{
"field": "table_properties_collector_factories",
"policy": "manual",
"reason": "Uses callbacks, factories, vectors, or nested option structs that need explicit C bridging."
},
{
"field": "blob_cache",
"policy": "manual",
"reason": "Uses callbacks, factories, vectors, or nested option structs that need explicit C bridging."
},
{
"field": "blob_compression_opts",
"policy": "manual",
"reason": "CompressionOptions is a nested struct; needs explicit C bridging (matches existing compaction_options_universal/fifo pattern)."
},
{
"field": "blob_direct_write_partition_strategy",
"policy": "manual",
"reason": "std::shared_ptr<BlobFilePartitionStrategy> \u2014 factory/ownership-transfer type; needs explicit C bridging."
},
{
"field": "soft_pending_compaction_bytes_limit",
"policy": "manual",
"reason": "ABI type mismatch: legacy C API uses size_t but C++ field is uint64_t. Hand-written binding preserved for ABI compatibility."
},
{
"field": "hard_pending_compaction_bytes_limit",
"policy": "manual",
"reason": "ABI type mismatch: legacy C API uses size_t but C++ field is uint64_t. Hand-written binding preserved for ABI compatibility."
}
]
},
{
"name": "ColumnFamilyOptions",
"entries": [
{
"field": "comparator",
"policy": "manual",
"reason": "Uses custom components or nested option objects that need hand-designed C bridging."
},
{
"field": "merge_operator",
"policy": "manual",
"reason": "Uses custom components or nested option objects that need hand-designed C bridging."
},
{
"field": "compaction_filter",
"policy": "manual",
"reason": "Uses custom components or nested option objects that need hand-designed C bridging."
},
{
"field": "compaction_filter_factory",
"policy": "manual",
"reason": "Uses custom components or nested option objects that need hand-designed C bridging."
},
{
"field": "bottommost_compression_opts",
"policy": "manual",
"reason": "Uses custom components or nested option objects that need hand-designed C bridging."
},
{
"field": "compression_opts",
"policy": "manual",
"reason": "Uses custom components or nested option objects that need hand-designed C bridging."
},
{
"field": "compression_manager",
"policy": "manual",
"reason": "Uses custom components or nested option objects that need hand-designed C bridging."
},
{
"field": "prefix_extractor",
"policy": "manual",
"reason": "Uses custom components or nested option objects that need hand-designed C bridging."
},
{
"field": "table_factory",
"policy": "manual",
"reason": "Uses custom components or nested option objects that need hand-designed C bridging."
},
{
"field": "cf_paths",
"policy": "manual",
"reason": "Uses custom components or nested option objects that need hand-designed C bridging."
},
{
"field": "compaction_thread_limiter",
"policy": "manual",
"reason": "Uses custom components or nested option objects that need hand-designed C bridging."
},
{
"field": "sst_partitioner_factory",
"policy": "manual",
"reason": "Uses custom components or nested option objects that need hand-designed C bridging."
}
]
},
{
"name": "EnvOptions",
"entries": [
{
"field": "rate_limiter",
"policy": "manual",
"reason": "Stores an external object pointer that needs explicit ownership policy in the C API."
}
]
},
{
"name": "CompactionOptions",
"entries": [
{
"field": "canceled",
"policy": "manual",
"reason": "Uses caller-owned cancellation state that should not be exposed as a blind auto-generated field wrapper."
}
]
},
{
"name": "CompactRangeOptions",
"entries": [
{
"field": "full_history_ts_low",
"policy": "manual",
"reason": "Uses caller-owned cancellation or timestamp state that needs explicit C API policy."
},
{
"field": "canceled",
"policy": "manual",
"reason": "Uses caller-owned cancellation or timestamp state that needs explicit C API policy."
}
]
},
{
"name": "OpenAndCompactOptions",
"entries": [
{
"field": "canceled",
"policy": "manual",
"reason": "Uses caller-owned cancellation state that should not be exposed as a blind auto-generated field wrapper."
}
]
},
{
"name": "GetColumnFamilyMetaDataOptions",
"entries": [
{
"field": "range",
"policy": "manual",
"reason": "Uses a range object that needs dedicated marshalling rather than a simple scalar binding."
}
]
},
{
"name": "BlockBasedTableOptions",
"entries": [
{
"field": "flush_block_policy_factory",
"policy": "manual",
"reason": "Uses factories, caches, or nested option objects that need explicit ownership or non-scalar marshalling."
},
{
"field": "metadata_cache_options",
"policy": "manual",
"reason": "Uses factories, caches, or nested option objects that need explicit ownership or non-scalar marshalling."
},
{
"field": "block_cache",
"policy": "manual",
"reason": "Uses factories, caches, or nested option objects that need explicit ownership or non-scalar marshalling."
},
{
"field": "persistent_cache",
"policy": "manual",
"reason": "Uses factories, caches, or nested option objects that need explicit ownership or non-scalar marshalling."
},
{
"field": "cache_usage_options",
"policy": "manual",
"reason": "Uses factories, caches, or nested option objects that need explicit ownership or non-scalar marshalling."
},
{
"field": "filter_policy",
"policy": "manual",
"reason": "Uses factories, caches, or nested option objects that need explicit ownership or non-scalar marshalling."
},
{
"field": "user_defined_index_factory",
"policy": "manual",
"reason": "Uses factories, caches, or nested option objects that need explicit ownership or non-scalar marshalling."
}
]
},
{
"name": "CompactionOptionsFIFO",
"entries": [
{
"field": "file_temperature_age_thresholds",
"policy": "manual",
"reason": "Uses collection-style configuration that needs dedicated marshalling rather than a simple scalar binding."
}
]
},
{
"name": "BackupEngineOptions",
"entries": [
{
"field": "backup_env",
"policy": "manual",
"reason": "Stores external objects and rate limiters that need explicit C ownership and lifetime policy."
},
{
"field": "info_log",
"policy": "manual",
"reason": "Stores external objects and rate limiters that need explicit C ownership and lifetime policy."
},
{
"field": "backup_rate_limiter",
"policy": "manual",
"reason": "Stores external objects and rate limiters that need explicit C ownership and lifetime policy."
},
{
"field": "restore_rate_limiter",
"policy": "manual",
"reason": "Stores external objects and rate limiters that need explicit C ownership and lifetime policy."
}
]
},
{
"name": "CreateBackupOptions",
"entries": [
{
"field": "progress_callback",
"policy": "manual",
"reason": "Uses callback hooks that need dedicated C callback plumbing."
},
{
"field": "exclude_files_callback",
"policy": "manual",
"reason": "Uses callback hooks that need dedicated C callback plumbing."
}
]
},
{
"name": "RestoreOptions",
"entries": [
{
"field": "alternate_dirs",
"policy": "manual",
"reason": "Uses a collection of alternate directories that needs explicit marshalling."
}
]
},
{
"name": "TransactionDBOptions",
"entries": [
{
"field": "custom_mutex_factory",
"policy": "manual",
"reason": "Uses factories, handles, callbacks, or internal collections that need hand-designed C bridging."
},
{
"field": "lock_mgr_handle",
"policy": "manual",
"reason": "Uses factories, handles, callbacks, or internal collections that need hand-designed C bridging."
},
{
"field": "rollback_deletion_type_callback",
"policy": "manual",
"reason": "Uses factories, handles, callbacks, or internal collections that need hand-designed C bridging."
},
{
"field": "secondary_indices",
"policy": "manual",
"reason": "Uses factories, handles, callbacks, or internal collections that need hand-designed C bridging."
},
{
"field": "wp_snapshot_cache_bits",
"policy": "manual",
"reason": "Uses factories, handles, callbacks, or internal collections that need hand-designed C bridging."
},
{
"field": "wp_commit_cache_bits",
"policy": "manual",
"reason": "Uses factories, handles, callbacks, or internal collections that need hand-designed C bridging."
},
{
"field": "autogenerate_name",
"policy": "manual",
"reason": "Uses factories, handles, callbacks, or internal collections that need hand-designed C bridging."
}
]
},
{
"name": "OptimisticTransactionOptions",
"entries": [
{
"field": "cmp",
"policy": "manual",
"reason": "Stores a comparator-like object pointer that needs explicit ownership policy."
}
]
},
{
"name": "OptimisticTransactionDBOptions",
"entries": [
{
"field": "shared_lock_buckets",
"policy": "manual",
"reason": "Uses shared internal synchronization state that should not be exposed as a blind field wrapper."
}
]
},
{
"name": "FlushJobInfo",
"entries": [
{
"field": "table_properties",
"policy": "manual",
"reason": "Returns nested metadata objects that need dedicated accessors rather than a simple scalar getter."
},
{
"field": "blob_file_addition_infos",
"policy": "manual",
"reason": "Returns nested metadata objects that need dedicated accessors rather than a simple scalar getter."
}
]
},
{
"name": "CompactionJobInfo",
"entries": [
{
"field": "input_files",
"policy": "manual",
"reason": "Returns nested metadata objects or collections that need dedicated accessors rather than a simple scalar getter."
},
{
"field": "input_file_infos",
"policy": "manual",
"reason": "Returns nested metadata objects or collections that need dedicated accessors rather than a simple scalar getter."
},
{
"field": "output_files",
"policy": "manual",
"reason": "Returns nested metadata objects or collections that need dedicated accessors rather than a simple scalar getter."
},
{
"field": "output_file_infos",
"policy": "manual",
"reason": "Returns nested metadata objects or collections that need dedicated accessors rather than a simple scalar getter."
},
{
"field": "table_properties",
"policy": "manual",
"reason": "Returns nested metadata objects or collections that need dedicated accessors rather than a simple scalar getter."
},
{
"field": "stats",
"policy": "manual",
"reason": "Returns nested metadata objects or collections that need dedicated accessors rather than a simple scalar getter."
},
{
"field": "blob_file_addition_infos",
"policy": "manual",
"reason": "Returns nested metadata objects or collections that need dedicated accessors rather than a simple scalar getter."
},
{
"field": "blob_file_garbage_infos",
"policy": "manual",
"reason": "Returns nested metadata objects or collections that need dedicated accessors rather than a simple scalar getter."
}
]
},
{
"name": "SubcompactionJobInfo",
"entries": [
{
"field": "stats",
"policy": "manual",
"reason": "Returns nested metadata objects that need dedicated accessors rather than a simple scalar getter."
}
]
},
{
"name": "ExternalFileIngestionInfo",
"entries": [
{
"field": "table_properties",
"policy": "manual",
"reason": "Returns nested metadata objects that need dedicated accessors rather than a simple scalar getter."
}
]
},
{
"name": "TableProperties",
"entries": [
{
"field": "user_collected_properties",
"policy": "manual",
"reason": "Returns map-like metadata that needs dedicated marshalling rather than a simple scalar getter."
},
{
"field": "readable_properties",
"policy": "manual",
"reason": "Returns map-like metadata that needs dedicated marshalling rather than a simple scalar getter."
}
]
}
]
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+237
View File
@@ -0,0 +1,237 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
# This source code is licensed under both the GPLv2 (found in the COPYING file in the root directory)
# and the Apache 2.0 License (found in the Apache file in the root directory).
#!/usr/bin/env python3
"""Check the public C API for backward-incompatible changes vs a reference.
RocksDB's C API (include/rocksdb/c.h) has a strong backward-compatibility
guarantee. Because most wrappers are now code-generated from the C++ headers, a
careless C++ change (renamed/removed field, changed field type) or a generator
change can silently remove a public C function or change its signature -- an
ABI/API break for every downstream language binding.
This is a robust, signature-level gate (it compares declared function
signatures, not function bodies, so it has no false positives from formatting
or body-token differences). For every function present in the reference
revision's c.h it requires that the current c.h still declares it with an
identical signature (parameter names are ignored; they do not affect the C
ABI). New functions are reported but never fail the check.
Intentional, reviewed incompatibilities (e.g. removing a function that was
declared but never implemented) must be recorded in
api_compatibility_allowlist.json with a reason.
Usage:
python3 tools/c_api_gen/check_api_compatibility.py [--ref main]
"""
from __future__ import annotations
import argparse
import json
import re
import subprocess
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
C_HEADER_REL = "include/rocksdb/c.h"
C_HEADER = ROOT / C_HEADER_REL
ALLOWLIST_PATH = ROOT / "tools/c_api_gen/api_compatibility_allowlist.json"
# C type-name tokens that are never a parameter *name*. Used to tell
# "unsigned char" (type, no name) apart from "rocksdb_t db" (type + name).
_TYPE_KEYWORDS = frozenset(
{
"void",
"char",
"short",
"int",
"long",
"float",
"double",
"unsigned",
"signed",
"bool",
"const",
"size_t",
"ssize_t",
"intptr_t",
"uintptr_t",
"ptrdiff_t",
}
)
DECL_RE = re.compile(
r"extern\s+ROCKSDB_LIBRARY_API\s+([\s\S]*?)\b(rocksdb_[A-Za-z0-9_]+)\s*\("
r"([^;]*?)\)\s*;",
)
def _strip_param_name(param: str) -> str:
"""Return the parameter type with any trailing parameter name removed."""
param = " ".join(param.replace("[]", " []").split())
if not param:
return param
tokens = param.split()
last = tokens[-1]
if (
last in _TYPE_KEYWORDS
or last.endswith("_t")
or "*" in last
or last == "[]"
):
return param # unnamed parameter; nothing to strip
if len(tokens) > 1 and re.fullmatch(r"[A-Za-z_]\w*", last):
return " ".join(tokens[:-1])
return param
def parse_signatures(header_text: str) -> dict[str, str]:
"""Map function name -> normalized signature string (param names removed)."""
sigs: dict[str, str] = {}
for match in DECL_RE.finditer(header_text):
ret = " ".join(match.group(1).split())
name = match.group(2)
params = [
_strip_param_name(p) for p in match.group(3).split(",") if p.strip()
]
sigs[name] = f"{ret} {name}({', '.join(params)})"
return sigs
def parse_symbols(header_text: str) -> set[str]:
"""Non-function public identifiers: enum constants and typedef names.
These are part of the C API contract too (e.g. rocksdb_txndb_write_policy_*,
the rocksdb tickers enum). A rocksdb_* token followed by '=', ',' or '}' is
an enum constant; one introduced/closed by typedef is a type name. Anything
followed by '(' is a function (handled by parse_signatures) and excluded.
"""
functions = {m.group(2) for m in DECL_RE.finditer(header_text)}
functions |= set(re.findall(r"\b(rocksdb_[A-Za-z0-9_]+)\s*\(", header_text))
symbols: set[str] = set()
for m in re.finditer(r"\b(rocksdb_[A-Za-z0-9_]+)\s*(?:=|,|\}|;)", header_text):
symbols.add(m.group(1))
symbols |= set(
re.findall(r"typedef\s+struct\s+(rocksdb_[A-Za-z0-9_]+)", header_text)
)
return symbols - functions
def git_show(ref: str, path: str) -> str | None:
proc = subprocess.run(
["git", "show", f"{ref}:{path}"],
cwd=ROOT,
text=True,
capture_output=True,
check=False,
)
if proc.returncode != 0:
return None
return proc.stdout
def load_allowlist() -> dict[str, set[str]]:
"""Allowed incompatibilities keyed by kind: removed / changed / removed_symbol."""
allowed = {"removed": set(), "changed": set(), "removed_symbol": set()}
if not ALLOWLIST_PATH.exists():
return allowed
data = json.loads(ALLOWLIST_PATH.read_text())
for entry in data.get("allow", []):
kind = entry.get("kind")
name = entry.get("function") or entry.get("symbol")
if kind in allowed and name:
allowed[kind].add(name)
return allowed
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--ref",
default="main",
help=(
"git revision to treat as the compatibility baseline (default: "
"main). The current working-tree c.h must stay compatible with it."
),
)
args = parser.parse_args()
ref_text = git_show(args.ref, C_HEADER_REL)
if ref_text is None:
sys.stderr.write(
f"error: could not read {C_HEADER_REL} at revision '{args.ref}'. "
"Pass an existing revision via --ref (e.g. --ref origin/main).\n"
)
return 2
cur_text = C_HEADER.read_text()
ref = parse_signatures(ref_text)
cur = parse_signatures(cur_text)
allowed = load_allowlist()
removed = sorted(n for n in ref if n not in cur and n not in allowed["removed"])
changed = sorted(
n
for n in ref
if n in cur and ref[n] != cur[n] and n not in allowed["changed"]
)
new = sorted(n for n in cur if n not in ref)
ref_symbols = parse_symbols(ref_text)
cur_symbols = parse_symbols(cur_text)
removed_symbols = sorted(
s
for s in ref_symbols
if s not in cur_symbols and s not in allowed["removed_symbol"]
)
status = 0
if removed:
status = 1
sys.stderr.write(
f"error: {len(removed)} public C API function(s) present at "
f"'{args.ref}' are missing now (backward-incompatible removal):\n"
)
for name in removed:
sys.stderr.write(f" - {name}\n")
if changed:
status = 1
sys.stderr.write(
f"error: {len(changed)} public C API function(s) changed signature "
f"(backward-incompatible ABI change):\n"
)
for name in changed:
sys.stderr.write(f" - {name}\n")
sys.stderr.write(f" was: {ref[name]}\n")
sys.stderr.write(f" now: {cur[name]}\n")
if removed_symbols:
status = 1
sys.stderr.write(
f"error: {len(removed_symbols)} public C API symbol(s) (enum "
f"constants / typedefs) present at '{args.ref}' are missing now "
"(backward-incompatible removal):\n"
)
for name in removed_symbols:
sys.stderr.write(f" - {name}\n")
if status != 0:
sys.stderr.write(
"\nIf a change is intentional and reviewed, record it in\n"
f"{ALLOWLIST_PATH.relative_to(ROOT)} with a reason; otherwise restore "
"the original declaration (see tools/c_api_gen/abi_type_overrides.json "
"for pinning a generated C type).\n"
)
else:
print(
f"C API is backward-compatible with '{args.ref}': "
f"{len(ref)} reference functions preserved, {len(new)} new; "
f"{len(ref_symbols)} enum/typedef symbols preserved."
)
return status
if __name__ == "__main__":
raise SystemExit(main())
+117
View File
@@ -0,0 +1,117 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
# This source code is licensed under both the GPLv2 (found in the COPYING file in the root directory)
# and the Apache 2.0 License (found in the LICENSE.Apache file in the root directory).
#!/usr/bin/env python3
"""Check that the public C API is link-complete and free of duplicate symbols.
Every function declared in ``include/rocksdb/c.h`` with
``extern ROCKSDB_LIBRARY_API`` must have exactly one definition in ``db/c.cc``.
This is a cheap, dependency-free safety net (no clang/libclang required) that
guards against a whole class of code-generation migration bugs: a wrapper whose
declaration is kept while its hand-written implementation is removed and never
regenerated. Such a function compiles fine into ``librocksdb`` (the missing
symbol is simply absent from the archive) and is invisible to RocksDB's own C
test unless that test happens to call it -- but it breaks every downstream
language binding (Rust, Go, Python, ...) that links against the symbol.
It also flags duplicate definitions, which would otherwise fail only at link
time with a less obvious error.
Run:
python3 tools/c_api_gen/check_api_completeness.py
"""
from __future__ import annotations
import re
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
C_HEADER = ROOT / "include/rocksdb/c.h"
C_SOURCE = ROOT / "db/c.cc"
# A public C API declaration looks like:
# extern ROCKSDB_LIBRARY_API <return type> rocksdb_foo(...);
# The return type may be on the same line or the following one, so anchor on
# the export macro and capture the first rocksdb_* identifier that is
# immediately followed by '('.
DECL_RE = re.compile(
r"extern\s+ROCKSDB_LIBRARY_API\b[\s\S]*?\b(rocksdb_[A-Za-z0-9_]+)\s*\(",
)
# A definition in c.cc is a top-level (column 0) function whose name is a
# rocksdb_* identifier immediately followed by '('. Return types/pointers may
# precede the name on the same line (e.g. "rocksdb_t* rocksdb_open(").
DEF_RE = re.compile(
r"^(?:[A-Za-z_][\w:<>,\s\*&]*?\s[\*&]*)?(rocksdb_[A-Za-z0-9_]+)\s*\(",
re.MULTILINE,
)
# Function-pointer typedefs etc. are not function definitions; the patterns
# above already exclude lines containing "(*name)" because the identifier must
# be directly followed by '('.
def declared_functions(header_text: str) -> set[str]:
return set(DECL_RE.findall(header_text))
def defined_functions(source_text: str) -> dict[str, int]:
counts: dict[str, int] = {}
for name in DEF_RE.findall(source_text):
counts[name] = counts.get(name, 0) + 1
return counts
def main() -> int:
if not C_HEADER.is_file() or not C_SOURCE.is_file():
sys.stderr.write(
f"error: expected {C_HEADER} and {C_SOURCE} to exist\n"
)
return 2
declared = declared_functions(C_HEADER.read_text())
defined = defined_functions(C_SOURCE.read_text())
missing = sorted(name for name in declared if name not in defined)
duplicated = sorted(name for name, n in defined.items() if n > 1)
status = 0
if missing:
status = 1
sys.stderr.write(
f"error: {len(missing)} C API function(s) are declared in "
f"{C_HEADER.relative_to(ROOT)} but have no definition in "
f"{C_SOURCE.relative_to(ROOT)}:\n"
)
for name in missing:
sys.stderr.write(f" - {name}\n")
sys.stderr.write(
"\nEach such function breaks downstream bindings at link time.\n"
"Add the implementation to tools/c_api_gen/c_base.cc (or via the\n"
"generators) and rerun python3 tools/c_api_gen/regen_all.py.\n"
)
if duplicated:
status = 1
sys.stderr.write(
f"error: {len(duplicated)} C API function(s) are defined more than "
f"once in {C_SOURCE.relative_to(ROOT)}:\n"
)
for name in duplicated:
sys.stderr.write(f" - {name} ({defined[name]} definitions)\n")
if status == 0:
print(
f"C API is link-complete: all {len(declared)} declared functions "
"have exactly one definition."
)
return status
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,8 @@
{
"allowlist": [
{
"name": "rocksdb_transactiondb_options_set_use_per_key_point_lock_mgr",
"reason": "The old handwritten implementation existed in db/c.cc but was not declared in include/rocksdb/c.h. The generated declaration intentionally fixes that historical inconsistency."
}
]
}
+206
View File
@@ -0,0 +1,206 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
# This source code is licensed under both the GPLv2 (found in the COPYING file in the root directory)
# and the Apache 2.0 License (found in the LICENSE.Apache file in the root directory).
#!/usr/bin/env python3
"""Generate round-trip (set -> get -> assert) C tests for the generated C API.
A large share of the auto-generated option getters/setters had no test
coverage. Rather than hand-writing hundreds of set/get assertions (and letting
coverage drift as the API grows), this tool derives the tests from the same
checked-in generated fragments that define the wrappers.
It parses the generated declaration fragments (c_api_gen/*.h.inc), pairs every
``rocksdb_<prefix>_set_<field>`` with its ``rocksdb_<prefix>_get_<field>``,
and emits, for each option object with a parameterless ``_create`` /
``_destroy``, a test that creates the object, sets a sentinel value, asserts
the getter returns it, and destroys the object.
Because the generated setters/getters are direct field assignments, a sentinel
round-trips reliably:
- string getters (``const char*`` + ``size_t*``) -> set "test", compare bytes
- everything else -> set 1 then 0 and assert the getter returns each.
1 and 0 are used (rather than a larger sentinel) because a bool field whose C
getter has the legacy ``int`` shape -- indistinguishable from a real scalar by
the C signature alone -- would collapse any value > 1 to 1. Using both 1 and 0
also exercises the setter in both directions.
No clang/libclang is required (it only reads the committed .inc files). The
output, c_api_gen/c_generated_roundtrip_tests.c.inc, is included by db/c_test.c.
"""
from __future__ import annotations
import re
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
GENERATED_ROOT = ROOT / "c_api_gen"
C_HEADER = ROOT / "include/rocksdb/c.h"
OUT = GENERATED_ROOT / "c_generated_roundtrip_tests.c.inc"
DECL_RE = re.compile(
r"extern\s+ROCKSDB_LIBRARY_API\s+(.+?)\s*\b(rocksdb_[A-Za-z0-9_]+)\s*\(([^;]*?)\)\s*;",
re.S,
)
class Pair:
__slots__ = ("prefix", "field", "receiver", "getter", "setter", "ret", "is_string")
def __init__(self, prefix: str, field: str, receiver: str) -> None:
self.prefix = prefix
self.field = field
self.receiver = receiver
self.getter: str | None = None
self.setter: str | None = None
self.ret: str | None = None
self.is_string = False
def _params(param_str: str) -> list[str]:
return [p.strip() for p in param_str.split(",") if p.strip()]
def _first_param_type(param: str) -> str:
# "rocksdb_options_t* opt" -> "rocksdb_options_t*"
param = " ".join(param.split())
return re.sub(r"\b[A-Za-z_]\w*$", "", param).strip()
def _split_role(name: str) -> tuple[str, str, str] | None:
for role in ("_set_", "_get_"):
idx = name.find(role)
if idx != -1:
return name[:idx], role.strip("_"), name[idx + len(role) :]
return None
def collect_pairs() -> list[Pair]:
pairs: dict[tuple[str, str], Pair] = {}
for inc in sorted(GENERATED_ROOT.glob("*.h.inc")):
text = inc.read_text()
for m in DECL_RE.finditer(text):
ret = " ".join(m.group(1).split())
name = m.group(2)
params = _params(m.group(3))
split = _split_role(name)
if split is None or not params:
continue
prefix, role, field = split
receiver = _first_param_type(params[0])
key = (prefix, field)
pair = pairs.get(key)
if pair is None:
pair = Pair(prefix, field, receiver)
pairs[key] = pair
if role == "set":
# Only simple scalar/string setters: (receiver, value).
if len(params) == 2:
pair.setter = name
else: # get
if len(params) == 1 and ret != "void":
pair.getter = name
pair.ret = ret
elif len(params) == 2 and ret == "const char*":
pair.getter = name
pair.ret = ret
pair.is_string = True
return [p for p in pairs.values() if p.getter and p.setter]
def parameterless_creators(header_text: str) -> set[str]:
"""Prefixes whose <prefix>_create() takes no args and <prefix>_destroy exists."""
creators: set[str] = set()
for m in re.finditer(
r"\b(rocksdb_[A-Za-z0-9_]+)_create\s*\(\s*(void)?\s*\)\s*;", header_text
):
creators.add(m.group(1))
destroyers = set(
re.findall(r"\b(rocksdb_[A-Za-z0-9_]+)_destroy\s*\(", header_text)
)
return {p for p in creators if p in destroyers}
def emit() -> str:
header_text = C_HEADER.read_text()
declared = set(re.findall(r"\b(rocksdb_[A-Za-z0-9_]+)\s*\(", header_text))
creators = parameterless_creators(header_text)
by_prefix: dict[str, list[Pair]] = {}
for pair in collect_pairs():
if pair.prefix not in creators:
continue
if pair.getter not in declared or pair.setter not in declared:
continue
by_prefix.setdefault(pair.prefix, []).append(pair)
lines: list[str] = []
lines.append("// @generated")
lines.append(
"// -----------------------------------------------------------------------------"
)
lines.append("// Auto-generated by tools/c_api_gen/gen_roundtrip_tests.py.")
lines.append("// DO NOT EDIT THIS FILE DIRECTLY.")
lines.append(
"// Round-trip (set -> get -> assert) coverage for generated option wrappers."
)
lines.append("// Rerun: python3 tools/c_api_gen/regen_all.py")
lines.append(
"// -----------------------------------------------------------------------------"
)
lines.append("")
test_fns: list[str] = []
for prefix in sorted(by_prefix):
pairs = sorted(by_prefix[prefix], key=lambda p: p.field)
receiver = pairs[0].receiver
fn = f"rocksdb_roundtrip_test_{prefix}"
test_fns.append(fn)
lines.append(f"static void {fn}(void) {{")
lines.append(f" {receiver} obj = {prefix}_create();")
for pair in pairs:
if pair.is_string:
lines.append(f' {pair.setter}(obj, "test");')
lines.append(" {")
lines.append(" size_t rt_len = 0;")
lines.append(f" const char* rt_v = {pair.getter}(obj, &rt_len);")
lines.append(
" CheckCondition(rt_len == 4 && rt_v != NULL && "
'memcmp(rt_v, "test", 4) == 0);'
)
lines.append(" }")
else:
# Use 1 and 0 (both directions). These round-trip through any
# numeric/enum field AND through bool fields -- a larger value
# would be collapsed to 1 by a bool field whose C getter is the
# legacy `int` shape (e.g. rocksdb_options_get_use_fsync), so we
# cannot tell bool from a plain scalar by the C signature alone.
for value in ("1", "0"):
lines.append(f" {pair.setter}(obj, {value});")
lines.append(
f" CheckCondition({pair.getter}(obj) == {value});"
)
lines.append(f" {prefix}_destroy(obj);")
lines.append("}")
lines.append("")
lines.append("static void rocksdb_run_generated_roundtrip_tests(void) {")
for fn in test_fns:
lines.append(f" {fn}();")
lines.append("}")
lines.append("")
return "\n".join(lines)
def main() -> int:
OUT.write_text(emit())
print(f"Generated {OUT.relative_to(ROOT)}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
+304
View File
@@ -0,0 +1,304 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
# This source code is licensed under both the GPLv2 (found in the COPYING file in the root directory)
# and the Apache 2.0 License (found in the LICENSE.Apache file in the root directory).
#!/usr/bin/env python3
"""Generate preview C API wrapper fragments from a declarative spec.
This prototype intentionally targets a constrained subset of RocksDB's C API:
- plain field setters/getters
- simple method forwarding wrappers
- Status -> char** errptr wrappers
- simple string metadata accessors
It does not attempt to infer wrappers from arbitrary C++ headers.
"""
from __future__ import annotations
import argparse
import json
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
from typing import Iterable
HEADER_BANNER = [
"// @generated",
"// -----------------------------------------------------------------------------",
"// Auto-generated by tools/c_api_gen/generate_c_api.py.",
"// DO NOT EDIT THIS FILE DIRECTLY.",
"// Source: tools/c_api_gen/spec.json",
"// -----------------------------------------------------------------------------",
"",
]
def format_signature(prefix: str, params: list[str], suffix: str) -> list[str]:
one_line = f"{prefix}{', '.join(params)}{suffix}"
if len(one_line) <= 80:
return [one_line]
lines = [prefix]
for i, param in enumerate(params):
trailing = "," if i + 1 < len(params) else ""
lines.append(f" {param}{trailing}")
lines[-1] = f"{lines[-1]}{suffix}"
return lines
def c_param_decl(param: dict) -> list[str]:
kind = param["kind"]
if kind == "scalar":
return [f'{param["c_type"]} {param["name"]}']
if kind == "slice":
return [f'const char* {param["name"]}', f'size_t {param["len_name"]}']
raise ValueError(f"Unsupported parameter kind: {kind}")
def flatten_params(params: Iterable[dict], include_errptr: bool = False) -> list[str]:
result: list[str] = []
for param in params:
result.extend(c_param_decl(param))
if include_errptr:
result.append("char** errptr")
return result
def render_decl(fn: dict) -> list[str]:
kind = fn["kind"]
if kind == "field_setter":
params = [
f'{fn["receiver_type"]} {fn["receiver_name"]}',
f'{fn["value_type"]} {fn["value_name"]}',
]
return format_signature(
f'extern ROCKSDB_LIBRARY_API void {fn["name"]}(',
params,
");",
)
if kind == "field_getter":
params = [f'{fn["receiver_type"]} {fn["receiver_name"]}']
return format_signature(
f'extern ROCKSDB_LIBRARY_API {fn["return_type"]} {fn["name"]}(',
params,
");",
)
if kind == "string_field_getter":
params = [
f'{fn["receiver_type"]} {fn["receiver_name"]}',
f'{fn["len_type"]} {fn["len_name"]}',
]
return format_signature(
f'extern ROCKSDB_LIBRARY_API const char* {fn["name"]}(',
params,
");",
)
if kind == "status_getter":
params = [
f'{fn["receiver_type"]} {fn["receiver_name"]}',
"char** errptr",
]
return format_signature(
f'extern ROCKSDB_LIBRARY_API void {fn["name"]}(',
params,
");",
)
if kind == "void_method":
return format_signature(
f'extern ROCKSDB_LIBRARY_API void {fn["name"]}(',
flatten_params(fn["params"]),
");",
)
if kind == "status_method":
return format_signature(
f'extern ROCKSDB_LIBRARY_API void {fn["name"]}(',
flatten_params(fn["params"], include_errptr=True),
");",
)
raise ValueError(f"Unsupported function kind: {kind}")
def render_impl(fn: dict) -> list[str]:
kind = fn["kind"]
if kind == "field_setter":
params = [
f'{fn["receiver_type"]} {fn["receiver_name"]}',
f'{fn["value_type"]} {fn["value_name"]}',
]
lines = format_signature(f'void {fn["name"]}(', params, ") {")
value_expr = fn.get("value_expr", fn["value_name"])
lines.append(f' {fn["field"]} = {value_expr};')
lines.append("}")
return lines
if kind == "field_getter":
params = [f'{fn["receiver_type"]} {fn["receiver_name"]}']
lines = format_signature(
f'{fn["return_type"]} {fn["name"]}(', params, ") {"
)
lines.append(f' return {fn["expr"]};')
lines.append("}")
return lines
if kind == "string_field_getter":
params = [
f'{fn["receiver_type"]} {fn["receiver_name"]}',
f'{fn["len_type"]} {fn["len_name"]}',
]
lines = format_signature(f'const char* {fn["name"]}(', params, ") {")
lines.append(f' *{fn["len_name"]} = {fn["expr"]}.size();')
lines.append(f' return {fn["expr"]}.data();')
lines.append("}")
return lines
if kind == "status_getter":
params = [
f'{fn["receiver_type"]} {fn["receiver_name"]}',
"char** errptr",
]
lines = format_signature(f'void {fn["name"]}(', params, ") {")
lines.append(f' SaveError(errptr, {fn["expr"]});')
lines.append("}")
return lines
if kind in ("void_method", "status_method"):
params = flatten_params(fn["params"], include_errptr=(kind == "status_method"))
lines = format_signature(f'void {fn["name"]}(', params, ") {")
call = f'{fn["call_expr"]}({", ".join(fn["method_args"])})'
if kind == "void_method":
lines.append(f" {call};")
else:
lines.append(f" SaveError(errptr, {call});")
lines.append("}")
return lines
raise ValueError(f"Unsupported function kind: {kind}")
def regen_comment_lines(mode: str) -> list[str]:
if mode == "header":
return [
"// To regenerate this file:",
"// python3 tools/c_api_gen/generate_c_api.py",
"// --spec tools/c_api_gen/spec.json",
"// --header-out c_api_gen/c_generated_subset.h.inc",
"// --source-out c_api_gen/c_generated_subset.cc.inc",
"",
]
return [
"// To regenerate this file:",
"// python3 tools/c_api_gen/generate_c_api.py",
"// --spec tools/c_api_gen/spec.json",
"// --header-out c_api_gen/c_generated_subset.h.inc",
"// --source-out c_api_gen/c_generated_subset.cc.inc",
"",
]
def section_comment_lines(
sections: list[str], header_out: Path, source_out: Path
) -> list[str]:
lines = [
"// To regenerate this file:",
"// python3 tools/c_api_gen/generate_c_api.py",
]
current = "// --spec tools/c_api_gen/spec.json"
for section in sections:
addition = f" --section {section!r}"
if len(current) + len(addition) > 78:
lines.append(current)
current = f"// --section {section!r}"
else:
current += addition
lines.append(current)
try:
rel_header = header_out.relative_to(ROOT)
except ValueError:
rel_header = header_out
try:
rel_source = source_out.relative_to(ROOT)
except ValueError:
rel_source = source_out
lines.append("// --header-out")
lines.append(f"// {rel_header}")
lines.append("// --source-out")
lines.append(f"// {rel_source}")
lines.append("")
return lines
def render_sections(spec: dict, mode: str, cmd_comment: list[str] | None = None) -> str:
lines: list[str] = []
lines.extend(HEADER_BANNER)
lines.extend(cmd_comment if cmd_comment is not None else regen_comment_lines(mode))
for section in spec["sections"]:
lines.append(f'/* {section["name"]} */')
lines.append("")
for fn in section["functions"]:
render = render_decl if mode == "header" else render_impl
lines.extend(render(fn))
lines.append("")
return "\n".join(lines).rstrip() + "\n"
def write_if_changed(path: Path, content: str) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
if not path.exists() or path.read_text() != content:
path.write_text(content)
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--spec", required=True, type=Path)
parser.add_argument("--header-out", required=True, type=Path)
parser.add_argument("--source-out", required=True, type=Path)
parser.add_argument(
"--section",
action="append",
default=[],
help="Only emit the named section(s) from the spec. May be repeated.",
)
parser.add_argument(
"--check",
action="store_true",
help="fail instead of writing if outputs are stale",
)
args = parser.parse_args()
spec = json.loads(args.spec.read_text())
if args.section:
allowed = set(args.section)
spec = {
**spec,
"sections": [
section for section in spec["sections"] if section["name"] in allowed
],
}
comment = regen_comment_lines("header")
if args.section:
comment = section_comment_lines(
args.section, args.header_out, args.source_out
)
header = render_sections(spec, "header", cmd_comment=comment)
source = render_sections(spec, "source", cmd_comment=comment)
if args.check:
expected = {
args.header_out: header,
args.source_out: source,
}
stale: list[str] = []
for path, content in expected.items():
if not path.exists() or path.read_text() != content:
stale.append(str(path))
if stale:
for path in stale:
print(f"stale: {path}")
return 1
return 0
write_if_changed(args.header_out, header)
write_if_changed(args.source_out, source)
return 0
if __name__ == "__main__":
raise SystemExit(main())
+266
View File
@@ -0,0 +1,266 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
# This source code is licensed under both the GPLv2 (found in the COPYING file in the root directory)
# and the Apache 2.0 License (found in the LICENSE.Apache file in the root directory).
#!/usr/bin/env python3
"""Regenerate all checked-in RocksDB C API generated fragments."""
from __future__ import annotations
import argparse
import shutil
import subprocess
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
GEN = ROOT / "tools/c_api_gen/generate_c_api.py"
AUTO_GEN = ROOT / "tools/c_api_gen/auto_simple_bindings.py"
ROUNDTRIP_GEN = ROOT / "tools/c_api_gen/gen_roundtrip_tests.py"
SPEC = ROOT / "tools/c_api_gen/spec.json"
GENERATED_ROOT = ROOT / "c_api_gen"
CLANG_FORMAT_STYLE_FILE = ROOT / ".clang-format"
JOBS = [
(
["DB data operations", "WriteBatch", "Transaction", "TransactionDB simple"],
GENERATED_ROOT / "c_generated_subset.h.inc",
GENERATED_ROOT / "c_generated_subset.cc.inc",
),
(
["DB data operations"],
GENERATED_ROOT / "c_generated_db_simple_subset.h.inc",
GENERATED_ROOT / "c_generated_db_simple_subset.cc.inc",
),
(
["WriteBatch"],
GENERATED_ROOT / "c_generated_writebatch_subset.h.inc",
GENERATED_ROOT / "c_generated_writebatch_subset.cc.inc",
),
(
["Transaction"],
GENERATED_ROOT / "c_generated_transaction_subset.h.inc",
GENERATED_ROOT / "c_generated_transaction_subset.cc.inc",
),
(
["TransactionDB simple"],
GENERATED_ROOT / "c_generated_transactiondb_subset.h.inc",
GENERATED_ROOT / "c_generated_transactiondb_subset.cc.inc",
),
(
["BlockBasedOptions simple"],
GENERATED_ROOT / "c_generated_block_based_options_subset.h.inc",
GENERATED_ROOT / "c_generated_block_based_options_subset.cc.inc",
),
(
["JobInfo metadata simple"],
GENERATED_ROOT / "c_generated_jobinfo_metadata_subset.h.inc",
GENERATED_ROOT / "c_generated_jobinfo_metadata_subset.cc.inc",
),
(
["CuckooOptions simple"],
GENERATED_ROOT / "c_generated_cuckoo_options_subset.h.inc",
GENERATED_ROOT / "c_generated_cuckoo_options_subset.cc.inc",
),
(
["Options simple"],
GENERATED_ROOT / "c_generated_options_subset.h.inc",
GENERATED_ROOT / "c_generated_options_subset.cc.inc",
),
]
def run_job(sections: list[str], header_out: Path, source_out: Path) -> None:
cmd = [
sys.executable,
str(GEN),
"--spec",
str(SPEC),
]
for section in sections:
cmd.extend(["--section", section])
cmd.extend(
[
"--header-out",
str(header_out),
"--source-out",
str(source_out),
]
)
subprocess.run(cmd, cwd=ROOT, check=True)
def format_generated_outputs(clang_format: str | None) -> None:
# The checked-in .inc fragments (and therefore the inlined c.h/c.cc) are
# clang-format-canonicalized. Pin the formatter (e.g. clang-format-21) to
# match CI so regeneration is byte-reproducible across environments; see
# tools/c_api_gen/README.md for the required version.
resolved = shutil.which(clang_format) if clang_format else None
if resolved is None:
print(
f"warning: clang-format binary '{clang_format}' not found in PATH; "
"skipping formatting (generated output may not be byte-reproducible)",
file=sys.stderr,
)
return
generated_paths = sorted(GENERATED_ROOT.glob("*.inc"))
subprocess.run(
[
resolved,
f"--style=file:{CLANG_FORMAT_STYLE_FILE}",
"-i",
*(str(path) for path in generated_paths),
],
cwd=ROOT,
check=True,
)
C_BASE_H = ROOT / "tools/c_api_gen/c_base.h"
C_H = ROOT / "include/rocksdb/c.h"
C_BASE_CC = ROOT / "tools/c_api_gen/c_base.cc"
C_CC = ROOT / "db/c.cc"
def _generated_banner(edit_target: str) -> str:
return (
"// @generated\n"
"// -----------------------------------------------------------------------------\n"
"// Auto-generated by tools/c_api_gen/regen_all.py.\n"
"// DO NOT EDIT THIS FILE DIRECTLY.\n"
f"// Edit {edit_target} or the inputs under tools/c_api_gen/,\n"
"// then rerun: python3 tools/c_api_gen/regen_all.py\n"
"// -----------------------------------------------------------------------------\n\n"
)
def _strip_source_template_notice(base: str) -> str:
import re
return re.sub(
r"(?ms)^// SOURCE TEMPLATE -- DO NOT .*?^//\s*$\n?",
"",
base,
count=1,
)
def _split_leading_line_comment_header(base: str) -> tuple[str, str]:
lines = base.splitlines(keepends=True)
idx = 0
while idx < len(lines):
stripped = lines[idx].lstrip()
if stripped.startswith("//"):
idx += 1
continue
break
return "".join(lines[:idx]), "".join(lines[idx:])
def _inline_fragments(
base_path: Path,
out_path: Path,
inc_pattern: str,
search_root: Path,
main_include: str | None = None,
generated_banner: str | None = None,
) -> None:
"""Inline generated .inc fragments into out_path from base_path."""
import re
from pathlib import Path as _Path
base = _strip_source_template_notice(base_path.read_text())
if generated_banner is not None:
header, rest = _split_leading_line_comment_header(base)
if header:
base = header.rstrip("\n") + "\n" + generated_banner + rest.lstrip("\n")
else:
base = generated_banner + base.lstrip("\n")
# Prepend main include as a separate group (own line + blank line)
if main_include is not None:
first_include = re.search(r'^#include ', base, re.MULTILINE)
if first_include:
pos = first_include.start()
base = base[:pos] + main_include + "\n\n" + base[pos:]
def inline_include(m: re.Match) -> str:
inc_path = search_root / m.group(1)
inc_content = inc_path.read_text().strip("\n")
filename = _Path(m.group(1)).name
return (
f"// BEGIN generated: {filename}\n"
+ inc_content
+ f"\n// END generated: {filename}"
)
result = re.sub(inc_pattern, inline_include, base)
out_path.write_text(result)
print(f"Generated {out_path.relative_to(ROOT)}")
def generate_c_h() -> None:
"""Inline all generated .h.inc fragments into c.h from c_base.h."""
_inline_fragments(
C_BASE_H,
C_H,
r'#include ["<](c_api_gen/[^">]+)[">]',
ROOT,
generated_banner=_generated_banner("tools/c_api_gen/c_base.h"),
)
def generate_c_cc() -> None:
"""Inline all generated .cc.inc fragments into c.cc from c_base.cc."""
_inline_fragments(
C_BASE_CC,
C_CC,
r'#include "(c_api_gen/[^"]+)"',
ROOT,
main_include='#include "rocksdb/c.h"',
generated_banner=_generated_banner("tools/c_api_gen/c_base.cc"),
)
def main() -> int:
parser = argparse.ArgumentParser(
description="Regenerate all checked-in RocksDB C API generated fragments."
)
parser.add_argument(
"--clang-format",
default="clang-format",
help=(
"clang-format binary used to canonicalize the generated .inc "
"fragments (default: clang-format). Pin to the version CI uses "
"(e.g. clang-format-21) for byte-reproducible output."
),
)
args = parser.parse_args()
for sections, header_out, source_out in JOBS:
run_job(sections, header_out, source_out)
subprocess.run([sys.executable, str(AUTO_GEN)], cwd=ROOT, check=True)
format_generated_outputs(args.clang_format)
generate_c_h()
generate_c_cc()
# c.h and c.cc are assembled from already-formatted .inc fragments.
# We do NOT re-run clang-format on them after inlining -- the .inc content
# is formatted above, and reformatting the inlined result would produce
# different line-wrapping since clang-format sees more context.
#
# Generate the round-trip C tests last: they read the (now generated)
# c.h to discover which option objects have a parameterless create/destroy
# and the .h.inc fragments to pair setters with getters. Re-run formatting
# so the new test fragment is canonicalized like the rest. This does not
# affect c.h/c.cc, which are not assembled from the test fragment.
subprocess.run([sys.executable, str(ROUNDTRIP_GEN)], cwd=ROOT, check=True)
format_generated_outputs(args.clang_format)
return 0
if __name__ == "__main__":
raise SystemExit(main())
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,487 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
# This source code is licensed under both the GPLv2 (found in the COPYING file in the root directory)
# and the Apache 2.0 License (found in the LICENSE.Apache file in the root directory).
#!/usr/bin/env python3
"""Validate generated C API wrappers against a reference handwritten revision.
This script compares the generated wrapper fragments currently included by
`include/rocksdb/c.h` and `db/c.cc` against the declarations/definitions in a
reference git revision, which defaults to `HEAD`.
The intent is to provide a guardrail when migrating handwritten wrappers to the
code generator:
- the generated declaration should match the old declaration shape
- the generated definition should match the old implementation shape
- known historical inconsistencies can be allowlisted with an explanation
"""
from __future__ import annotations
import argparse
import json
import re
import subprocess
import sys
from dataclasses import dataclass
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
@dataclass
class FunctionDecl:
name: str
text: str
return_type: str
param_types: list[str]
@dataclass
class FunctionDef:
name: str
signature: str
return_type: str
param_types: list[str]
param_names: list[str]
body: str
def strip_comments(text: str) -> str:
text = re.sub(r"//.*", "", text)
text = re.sub(r"/\*.*?\*/", "", text, flags=re.S)
return text
def normalize_space(text: str) -> str:
return " ".join(strip_comments(text).split())
TOKEN_RE = re.compile(
r'"(?:\\.|[^"\\])*"'
r"|'(?:\\.|[^'\\])*'"
r"|->|::|==|!=|<=|>=|&&|\|\|"
r"|[A-Za-z_][A-Za-z0-9_]*"
r"|[0-9]+"
r"|[{}()[\];,.*&<>!=+\-/%:?]"
)
TYPE_WORD_PREFIXES = {
"const",
"volatile",
"unsigned",
"signed",
"short",
"long",
}
def tokenize(text: str) -> list[str]:
return TOKEN_RE.findall(strip_comments(text))
def map_identifiers(tokens: list[str], mapping: dict[str, str]) -> list[str]:
return [mapping.get(tok, tok) for tok in tokens]
def normalize_return_casts(body: str, return_type: str) -> str:
escaped_type = re.escape(normalize_space(return_type)).replace(r"\ ", r"\s+")
pattern = re.compile(
rf"return\s+static_cast\s*<\s*{escaped_type}\s*>\s*\((.*?)\)\s*;",
re.S,
)
return pattern.sub(lambda m: f"return {m.group(1).strip()};", body)
def find_matching(text: str, start: int, open_ch: str, close_ch: str) -> int:
assert text[start] == open_ch
depth = 0
i = start
in_string = False
string_quote = ""
while i < len(text):
ch = text[i]
if in_string:
if ch == "\\":
i += 2
continue
if ch == string_quote:
in_string = False
i += 1
continue
if ch in ("'", '"'):
in_string = True
string_quote = ch
i += 1
continue
if ch == open_ch:
depth += 1
elif ch == close_ch:
depth -= 1
if depth == 0:
return i
i += 1
raise ValueError(f"Unmatched {open_ch} in text")
def find_signature_start(text: str, pos: int) -> int:
start = text.rfind("\n", 0, pos)
start = 0 if start < 0 else start + 1
while start > 0:
prev_end = start - 1
prev_start = text.rfind("\n", 0, prev_end)
prev_start = 0 if prev_start < 0 else prev_start + 1
prev_line = text[prev_start:prev_end].strip()
if not prev_line:
break
if prev_line.startswith("//"):
break
if prev_line.endswith(";") or prev_line.endswith("}") or prev_line.endswith("{"):
break
start = prev_start
return start
def split_top_level(text: str, delimiter: str) -> list[str]:
parts: list[str] = []
depth_paren = depth_angle = depth_bracket = 0
start = 0
i = 0
while i < len(text):
ch = text[i]
if ch == "(":
depth_paren += 1
elif ch == ")":
depth_paren -= 1
elif ch == "<":
depth_angle += 1
elif ch == ">":
depth_angle -= 1
elif ch == "[":
depth_bracket += 1
elif ch == "]":
depth_bracket -= 1
elif (
ch == delimiter
and depth_paren == 0
and depth_angle == 0
and depth_bracket == 0
):
parts.append(text[start:i].strip())
start = i + 1
i += 1
tail = text[start:].strip()
if tail:
parts.append(tail)
return parts
def parse_param_decl(param: str) -> tuple[str, str]:
param = normalize_space(param)
if not param or param == "void":
return "", ""
if "(" in param and "*" in param:
raise ValueError(f"Unsupported function pointer parameter: {param}")
m = re.match(r"^(.*?)([A-Za-z_][A-Za-z0-9_]*)$", param)
if not m:
return param, ""
type_part = m.group(1).strip()
name = m.group(2)
return normalize_space(type_part), name
def parse_param_type_only(param: str) -> str:
param = normalize_space(param)
if not param or param == "void":
return ""
if "(" in param and "*" in param:
raise ValueError(f"Unsupported function pointer parameter: {param}")
tokens = re.findall(r"[A-Za-z_][A-Za-z0-9_]*|[&*\[\]]", param)
if not tokens:
return param
if tokens[-1] in {"*", "&", "[", "]"}:
return param
if len(tokens) == 1:
return param
if len(tokens) == 2 and tokens[0] in TYPE_WORD_PREFIXES:
return param
# Treat the trailing identifier as the parameter name.
m = re.match(r"^(.*?)([A-Za-z_][A-Za-z0-9_]*)$", param)
if not m:
return param
return normalize_space(m.group(1).strip())
def parse_signature_shape(
signature: str, name: str, require_param_names: bool
) -> tuple[str, list[str], list[str]]:
signature = normalize_space(signature)
signature = re.sub(r"\bextern\b", "", signature)
signature = re.sub(r"\bROCKSDB_LIBRARY_API\b", "", signature)
signature = normalize_space(signature)
marker = f"{name}("
pos = signature.find(marker)
if pos < 0:
raise ValueError(f"Could not find function name {name} in signature")
return_type = normalize_space(signature[:pos].strip())
params_start = pos + len(name)
assert signature[params_start] == "("
params_end = find_matching(signature, params_start, "(", ")")
params_text = signature[params_start + 1 : params_end]
param_types: list[str] = []
param_names: list[str] = []
if params_text.strip():
for raw_param in split_top_level(params_text, ","):
if require_param_names:
ptype, pname = parse_param_decl(raw_param)
else:
ptype, pname = parse_param_type_only(raw_param), ""
if ptype:
param_types.append(ptype)
param_names.append(pname)
return return_type, param_types, param_names
def extract_function_decls(text: str) -> dict[str, FunctionDecl]:
result: dict[str, FunctionDecl] = {}
pos = 0
while True:
start = text.find("extern ROCKSDB_LIBRARY_API", pos)
if start < 0:
break
semi = text.find(";", start)
if semi < 0:
break
snippet = text[start : semi + 1]
m = re.search(r"\b(rocksdb_[A-Za-z0-9_]+)\s*\(", snippet)
if m:
name = m.group(1)
try:
return_type, param_types, _ = parse_signature_shape(
snippet[:-1], name, require_param_names=False
)
result[name] = FunctionDecl(
name=name,
text=snippet,
return_type=return_type,
param_types=param_types,
)
except ValueError:
pass
pos = semi + 1
return result
def extract_function_defs(text: str) -> dict[str, FunctionDef]:
result: dict[str, FunctionDef] = {}
pattern = re.compile(r"\b(rocksdb_[A-Za-z0-9_]+)\s*\(")
pos = 0
while True:
m = pattern.search(text, pos)
if not m:
break
name = m.group(1)
paren_start = text.find("(", m.start(1))
paren_end = find_matching(text, paren_start, "(", ")")
body_start = paren_end + 1
while body_start < len(text) and text[body_start].isspace():
body_start += 1
if body_start >= len(text) or text[body_start] != "{":
pos = m.end(1)
continue
sig_start = find_signature_start(text, m.start(1))
signature = text[sig_start:paren_end + 1]
body_end = find_matching(text, body_start, "{", "}")
body = text[body_start : body_end + 1]
try:
return_type, param_types, param_names = parse_signature_shape(
signature, name, require_param_names=True
)
result[name] = FunctionDef(
name=name,
signature=signature,
return_type=return_type,
param_types=param_types,
param_names=param_names,
body=body,
)
except ValueError:
pass
pos = body_end + 1
return result
def git_show(rev: str, path: str) -> str:
return subprocess.check_output(
["git", "show", f"{rev}:{path}"], cwd=ROOT, text=True
)
def active_generated_paths(
path: Path, include_prefix: str, root_prefix: str
) -> list[Path]:
text = path.read_text()
pattern = re.compile(rf'#include "{re.escape(include_prefix)}/(c_generated_[^"]+)"')
return [ROOT / root_prefix / m.group(1) for m in pattern.finditer(text)]
def load_allowlist(path: Path | None) -> dict[str, str]:
if path is None or not path.exists():
return {}
data = json.loads(path.read_text())
return {entry["name"]: entry["reason"] for entry in data.get("allowlist", [])}
def compare_headers(
generated_headers: list[Path],
ref_header_text: str,
allowlist: dict[str, str],
) -> list[str]:
ref = extract_function_decls(ref_header_text)
failures: list[str] = []
for path in generated_headers:
for name, generated in extract_function_decls(path.read_text()).items():
if name in allowlist:
continue
ref_decl = ref.get(name)
if ref_decl is None:
failures.append(
f"[header missing] {name}: not declared in reference include/rocksdb/c.h"
)
continue
if (
generated.return_type != ref_decl.return_type
or generated.param_types != ref_decl.param_types
):
failures.append(
f"[header mismatch] {name}: generated "
f"{generated.return_type}({', '.join(generated.param_types)}) "
f"!= reference {ref_decl.return_type}"
f"({', '.join(ref_decl.param_types)})"
)
return failures
def compare_sources(
generated_sources: list[Path],
ref_source_text: str,
allowlist: dict[str, str],
) -> list[str]:
ref = extract_function_defs(ref_source_text)
failures: list[str] = []
for path in generated_sources:
for name, generated in extract_function_defs(path.read_text()).items():
if name in allowlist:
continue
ref_def = ref.get(name)
if ref_def is None:
failures.append(
f"[source missing] {name}: not defined in reference db/c.cc"
)
continue
if (
generated.return_type != ref_def.return_type
or generated.param_types != ref_def.param_types
):
failures.append(
f"[source signature mismatch] {name}: generated "
f"{generated.return_type}({', '.join(generated.param_types)}) "
f"!= reference {ref_def.return_type}"
f"({', '.join(ref_def.param_types)})"
)
continue
mapping = {
ref_name: gen_name
for ref_name, gen_name in zip(ref_def.param_names, generated.param_names)
if ref_name and gen_name
}
ref_body = normalize_return_casts(ref_def.body, generated.return_type)
gen_body = normalize_return_casts(generated.body, generated.return_type)
ref_tokens = map_identifiers(tokenize(ref_body), mapping)
gen_tokens = tokenize(gen_body)
if ref_tokens != gen_tokens:
failures.append(f"[source body mismatch] {name}")
return failures
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument(
"--ref",
required=True,
help=(
"Reference git revision to compare the generated wrappers against. "
"This must be a PRE-migration revision that still had the "
"hand-written wrappers (e.g. a release tag from before codegen "
"landed); comparing against a post-migration revision is a "
"tautology because the reference is itself generated. This is a "
"best-effort body-equivalence aid; the authoritative, ongoing "
"backward-compatibility gate is check_api_compatibility.py."
),
)
parser.add_argument(
"--allowlist",
type=Path,
default=ROOT / "tools/c_api_gen/equivalence_allowlist.json",
help="JSON allowlist for intentional historical differences",
)
parser.add_argument(
"--generated-header",
action="append",
type=Path,
default=[],
help="Generated header fragment(s) to validate. Defaults to active includes.",
)
parser.add_argument(
"--generated-source",
action="append",
type=Path,
default=[],
help="Generated source fragment(s) to validate. Defaults to active includes.",
)
args = parser.parse_args()
generated_headers = (
args.generated_header
if args.generated_header
else active_generated_paths(
ROOT / "tools/c_api_gen/c_base.h", "c_api_gen", "c_api_gen"
)
)
generated_sources = (
args.generated_source
if args.generated_source
else active_generated_paths(
ROOT / "tools/c_api_gen/c_base.cc", "c_api_gen", "c_api_gen"
)
)
allowlist = load_allowlist(args.allowlist)
ref_header_text = git_show(args.ref, "include/rocksdb/c.h")
ref_source_text = git_show(args.ref, "db/c.cc")
failures = []
failures.extend(compare_headers(generated_headers, ref_header_text, allowlist))
failures.extend(compare_sources(generated_sources, ref_source_text, allowlist))
if failures:
for name, reason in sorted(allowlist.items()):
print(f"[allowlist] {name}: {reason}")
for failure in failures:
print(failure)
return 1
print(
"Validated generated wrappers against "
f"{args.ref}: {len(generated_headers)} header fragments, "
f"{len(generated_sources)} source fragments."
)
if allowlist:
print(f"Applied allowlist entries: {len(allowlist)}")
return 0
if __name__ == "__main__":
sys.exit(main())
@@ -0,0 +1,166 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
# This source code is licensed under both the GPLv2 (found in the COPYING file in the root directory)
# and the Apache 2.0 License (found in the LICENSE.Apache file in the root directory).
#!/usr/bin/env python3
"""Verify checked-in C API generated fragments are up to date without Git."""
from __future__ import annotations
import argparse
import shutil
import subprocess
import sys
import tempfile
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
REGEN_ALL = ROOT / "tools/c_api_gen/regen_all.py"
CLANG_FORMAT_STYLE_FILE = ROOT / ".clang-format"
GENERATED_DIRS = (
Path("c_api_gen"),
)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description=(
"Regenerate the checked-in C API fragments and compare them against "
"a pre-regen snapshot without relying on git diff."
)
)
parser.add_argument(
"--clang-format",
default="clang-format",
help=(
"clang-format binary to canonicalize both the pre-regen snapshot "
"and regenerated output before comparison (default: clang-format)"
),
)
return parser.parse_args()
def resolve_executable(command: str) -> str:
if Path(command).parent != Path():
if Path(command).exists():
return str(Path(command))
raise FileNotFoundError(f"Executable not found: {command}")
resolved = shutil.which(command)
if resolved is None:
raise FileNotFoundError(
f"{command} not found in PATH. Install it or pass --clang-format."
)
return resolved
# c.h and c.cc are also generated artifacts inlined from c_base.* + .inc fragments
GENERATED_FILES = (
Path("include/rocksdb/c.h"),
Path("db/c.cc"),
)
def copy_generated_dirs(destination_root: Path) -> None:
for rel_dir in GENERATED_DIRS:
source = ROOT / rel_dir
if not source.is_dir():
raise FileNotFoundError(f"Generated directory missing: {source}")
destination = destination_root / rel_dir
destination.parent.mkdir(parents=True, exist_ok=True)
shutil.copytree(source, destination)
for rel_file in GENERATED_FILES:
source = ROOT / rel_file
if not source.is_file():
raise FileNotFoundError(f"Generated file missing: {source}")
destination = destination_root / rel_file
destination.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(source, destination)
def collect_inc_files(root: Path) -> list[str]:
inc_files: list[str] = []
for rel_dir in GENERATED_DIRS:
directory = root / rel_dir
if not directory.is_dir():
raise FileNotFoundError(f"Generated directory missing: {directory}")
inc_files.extend(str(path) for path in sorted(directory.rglob("*.inc")))
return inc_files
def format_generated_dirs(root: Path, clang_format: str) -> None:
inc_files = collect_inc_files(root)
if not inc_files:
raise RuntimeError(f"No generated .inc files found under {root}")
subprocess.run(
[
clang_format,
f"--style=file:{CLANG_FORMAT_STYLE_FILE}",
"-i",
*inc_files,
],
cwd=root,
check=True,
)
def compare_snapshots(work_root: Path) -> int:
proc = subprocess.run(
["diff", "-ruN", "checked_in", "regenerated"],
cwd=work_root,
text=True,
capture_output=True,
check=False,
)
if proc.returncode == 0:
print("C API generated files are up to date.")
return 0
if proc.returncode == 1:
sys.stderr.write(
"C API generated files are out of date. Re-run "
"`python3 tools/c_api_gen/regen_all.py` and commit the updated "
"files under c_api_gen/, "
"include/rocksdb/c.h, and db/c.cc.\n"
)
if proc.stdout:
sys.stderr.write(proc.stdout)
return 1
if proc.stdout:
sys.stderr.write(proc.stdout)
if proc.stderr:
sys.stderr.write(proc.stderr)
raise RuntimeError(f"diff failed with exit code {proc.returncode}")
def main() -> int:
args = parse_args()
clang_format = resolve_executable(args.clang_format)
with tempfile.TemporaryDirectory(prefix="rocksdb-c-api-gen-verify-") as tmp:
work_root = Path(tmp)
checked_in_root = work_root / "checked_in"
regenerated_root = work_root / "regenerated"
copy_generated_dirs(checked_in_root)
format_generated_dirs(checked_in_root, clang_format)
# Pass the pinned formatter down so the regenerated .inc fragments (and
# thus the inlined c.h/c.cc) are canonicalized with the same clang-format
# version on both sides of the comparison.
subprocess.run(
[sys.executable, str(REGEN_ALL), "--clang-format", args.clang_format],
cwd=ROOT,
check=True,
)
format_generated_dirs(ROOT, clang_format)
copy_generated_dirs(regenerated_root)
return compare_snapshots(work_root)
if __name__ == "__main__":
raise SystemExit(main())
+8 -4
View File
@@ -1,10 +1,8 @@
#!/usr/bin/env python3
# Copyright (c) Meta Platforms, Inc. and affiliates.
# This source code is licensed under both the GPLv2 (found in the COPYING file in the root directory)
# and the Apache 2.0 License (found in the LICENSE.Apache file in the root directory).
#!/usr/bin/env python3
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
import importlib.util
import io
import os
@@ -130,7 +128,13 @@ class DBCrashTestTest(unittest.TestCase):
db_crashtest = self.load_db_crashtest()
params = self.build_params(
db_crashtest.default_params,
{"disable_wal": 1, "test_batches_snapshots": 1},
{
"disable_wal": 1,
"test_batches_snapshots": 1,
# finalize_and_sanitize() intentionally forces disable_wal=0
# when inplace_update_support=1.
"inplace_update_support": 0,
},
)
finalized = db_crashtest.finalize_and_sanitize(params)
@@ -0,0 +1 @@
Expanded the C API (`include/rocksdb/c.h`) with a large set of new `rocksdb_*` functions, mostly option getters/setters plus table-properties, job/event-listener, and metadata accessors, a WAL filter, a ReadOptions table filter, and a backup exclude-files callback. Many are now produced by a new semi-automated generator (`tools/c_api_gen/`) from the C++ headers; `include/rocksdb/c.h` remains a single self-contained header and the signatures of pre-existing functions are unchanged.
@@ -11,11 +11,26 @@
#include "db/dbformat.h"
#include "rocksdb/comparator.h"
#include "rocksdb/utilities/object_registry.h"
#include "util/coding.h"
namespace ROCKSDB_NAMESPACE {
namespace trie_index {
int RegisterBuiltinTrieIndexFactory(ObjectLibrary& library,
const std::string& /*arg*/) {
library.AddFactory<UserDefinedIndexFactory>(
TrieIndexFactory::kClassName(),
[](const std::string& /*uri*/,
std::unique_ptr<UserDefinedIndexFactory>* guard,
std::string* /*errmsg*/) {
guard->reset(new TrieIndexFactory());
return guard->get();
});
size_t num_types;
return static_cast<int>(library.GetFactoryCount(&num_types));
}
// ============================================================================
// TrieIndexBuilder
// ============================================================================
@@ -39,8 +39,14 @@
#include "utilities/trie_index/louds_trie.h"
namespace ROCKSDB_NAMESPACE {
class ObjectLibrary;
namespace trie_index {
// Registers the built-in trie UDI in the supplied object library.
int RegisterBuiltinTrieIndexFactory(ObjectLibrary& library,
const std::string& arg);
// ============================================================================
// TrieIndexBuilder: Implements UserDefinedIndexBuilder using LoudsTrieBuilder.
//