rust-rocksdb 0.52.0

Rust wrapper for Facebook's RocksDB embeddable database
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
name: RocksDB CI

on:
  push:
    branches: [master]
  pull_request:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

env:
  CARGO_TERM_COLOR: always

jobs:
  style:
    name: Rustfmt
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v5

      - name: Install rust
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          components: rustfmt
          cache: false
          rustflags: ""

      - name: Run rustfmt
        run: cargo fmt --all -- --check

  doc-check:
    name: Rustdoc-check
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v5
        with:
          submodules: recursive

      - name: Install rust
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          components: rust-docs
          cache-save-if: ${{ github.ref == 'refs/heads/master' }}

      - name: Run cargo rustdoc
        run: cargo rustdoc -- -D warnings

  doctest: # doctest are no supported in cargo nextest yet. https://github.com/nextest-rs/nextest/issues/16
    name: Doctests
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v5
        with:
          submodules: recursive

      - name: Install rust
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          cache-save-if: ${{ github.ref == 'refs/heads/master' }}

      - name: Run doctests
        run: cargo test --doc

  clippy:
    name: Clippy
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v5
        with:
          submodules: recursive

      - name: Install rust
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          components: clippy
          cache-save-if: ${{ github.ref == 'refs/heads/master' }}

      - name: Install dependencies
        run: sudo apt-get update && sudo apt-get install -y liburing-dev pkg-config

      - name: Set PKG_CONFIG_PATH
        run: echo "PKG_CONFIG_PATH=/usr/lib/x86_64-linux-gnu/pkgconfig" >> $GITHUB_ENV

      - name: Run clippy
        run: |
          cargo clippy --all-targets --features \
            "jemalloc \
            io-uring \
            valgrind \
            mt_static \
            rtti \
            multi-threaded-cf \
            malloc-usable-size \
            zstd-static-linking-only \
            serde1" \
            -- -D warnings

  # `rust-toolchain.toml` tracks stable, so nothing else here builds on the
  # MSRV. This job is what makes `rust-version` in Cargo.toml a real claim
  # rather than a number in a manifest. It reads that field instead of
  # repeating it, so the two cannot drift.
  #
  # `cargo check` on the default features is deliberate. The question is
  # whether the declared MSRV still compiles the crate, not whether the suite
  # passes on it a second time. The explicit `+toolchain` is required because
  # `rust-toolchain.toml` would otherwise win over the rustup default.
  msrv:
    name: MSRV
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v5
        with:
          submodules: recursive

      - name: Read the declared MSRV
        id: msrv
        run: |
          set -euo pipefail
          v=$(sed -n 's/^rust-version = "\(.*\)"$/\1/p' Cargo.toml)
          if [ -z "$v" ]; then
            echo "::error::could not read rust-version from Cargo.toml"
            exit 1
          fi
          echo "declared MSRV: $v"
          echo "version=$v" >> "$GITHUB_OUTPUT"

      - name: Install rust ${{ steps.msrv.outputs.version }}
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          toolchain: ${{ steps.msrv.outputs.version }}
          cache-key: "v1-rust-msrv"
          cache-save-if: ${{ github.ref == 'refs/heads/master' }}

      - name: Check on the declared MSRV
        run: cargo +${{ steps.msrv.outputs.version }} check --all-targets

  # Every other job builds for the target's baseline CPU, where
  # x86_64-unknown-linux-gnu reports only fxsr, sse and sse2. `build.rs` turns
  # target features into `-march`/`-mcpu` and into RocksDB and snappy defines,
  # so a tuned build takes entirely different code paths. A snappy build break
  # under `-Ctarget-cpu` shipped in 0.51.0 precisely because nothing here ever
  # left the baseline. `native` rather than a fixed level so the job keeps
  # matching whatever the runners actually are.
  build-tuned-cpu:
    name: Tuned CPU build - ${{ matrix.build }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        build: [Linux, Linux-ARM]
        include:
          - build: Linux
            os: ubuntu-latest
          - build: Linux-ARM
            os: ubuntu-24.04-arm
    steps:
      - name: Checkout sources
        uses: actions/checkout@v5
        with:
          submodules: recursive

      - name: Install rust
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          # Nothing this job caches may contain machine code. `native` bakes
          # whatever the saving runner supported into every host artifact,
          # including the dependency rlibs that get linked into `build.rs`, and
          # the hosted fleet spans CPU generations, so restoring those onto a
          # narrower machine kills the build script with SIGILL. That rules out
          # `target` and `~/.cargo/bin`, leaving the registry and git checkouts,
          # which are only sources. Costs about two minutes, 8m09s cold against
          # 6m05s warm, because the cache never covered the RocksDB build in the
          # first place: `librocksdb-sys` is a workspace member, and it was 5m17s
          # of that warm run.
          cache-key: "v2-rust-tuned-cpu"
          cache-targets: false
          cache-bin: false
          cache-save-if: ${{ github.ref == 'refs/heads/master' }}
          rustflags: ""

      - uses: taiki-e/install-action@nextest

      - name: Run tests with -Ctarget-cpu=native
        env:
          RUSTFLAGS: -Ctarget-cpu=native
        run: cargo nextest run --all

  # Nothing else builds without the default features, so a compression backend
  # that only compiles because a sibling feature happens to pull in its headers
  # goes unnoticed. Check builds only; the point is that each combination
  # compiles and links, which the default matrix already covers behaviourally.
  build-feature-matrix:
    name: Feature build - ${{ matrix.name }}
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        include:
          - name: no-default-features
            features: "--no-default-features"
          - name: snappy only
            features: "--no-default-features --features snappy"
          - name: lz4 only
            features: "--no-default-features --features lz4"
          - name: zstd only
            features: "--no-default-features --features zstd"
          - name: zlib only
            features: "--no-default-features --features zlib"
          - name: bzip2 only
            features: "--no-default-features --features bzip2"
          - name: serde1 + multi-threaded-cf
            features: "--features serde1,multi-threaded-cf"
    steps:
      - name: Checkout sources
        uses: actions/checkout@v5
        with:
          submodules: recursive

      - name: Install rust
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          cache-key: "v1-rust-features"
          cache-save-if: ${{ github.ref == 'refs/heads/master' }}

      # `--no-default-features` drops `bindgen-runtime`, and with neither
      # bindgen feature `clang-sys` stops loading libclang at runtime and
      # links it instead, which needs `llvm-config` from llvm-dev to locate
      # `libclang.so` from libclang-dev. Neither is on the runner by default.
      - name: Install dependencies
        run: sudo apt-get update && sudo apt-get install -y llvm-dev libclang-dev clang

      - name: Check ${{ matrix.name }}
        run: cargo check --all-targets ${{ matrix.features }}

  # What we publish is not what we test. Every other job builds from the git
  # checkout; users build from a tarball assembled by the `exclude` list in
  # `librocksdb-sys/Cargo.toml`. Trimming one glob too far breaks every
  # downstream build and cannot be fixed without publishing a new version, so
  # verify the tarball itself.
  package:
    name: Package verify
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v5
        with:
          submodules: recursive

      - name: Install rust
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          cache-key: "v1-rust-package"
          cache-save-if: ${{ github.ref == 'refs/heads/master' }}

      # No `--no-verify`: the point of this job is that cargo unpacks the
      # tarball into `target/package` and compiles RocksDB from it, which is
      # what proves the exclude list did not drop a header.
      - name: Package and build from the tarball
        run: cargo package -p rust-librocksdb-sys

      # An exclude list silently admits whatever upstream adds next, so assert
      # the result instead of trusting the patterns. RocksDB keeps tests in
      # `*_test.cc` beside the sources, which is how 222 test files, the Java
      # bindings and db_stress_tool were being published in the first place.
      #
      # This job runs with `submodules: recursive`, which is the point: snappy's
      # googletest and benchmark submodules are absent from a shallow clone, so
      # a local `cargo package` will not show them.
      - name: Assert the tarball stays trimmed
        run: |
          set -euo pipefail
          cargo package --list -p rust-librocksdb-sys > /tmp/pkg.txt
          total=$(wc -l < /tmp/pkg.txt)
          echo "packaged files: $total"

          fail=0
          for pat in '_test\.cc$' '^rocksdb/java/' '^rocksdb/db_stress_tool/' \
                     '^rocksdb/microbench/' '^rocksdb/fuzz/' '^rocksdb/buckifier/' \
                     '^snappy/third_party/'; do
            n=$(grep -cE "$pat" /tmp/pkg.txt || true)
            if [ "$n" -ne 0 ]; then
              echo "::error::$n packaged files match $pat, which nothing compiles"
              fail=1
            fi
          done

          # Ceiling with room for ordinary upstream growth. A jump past this
          # means a new directory started riding along; extend the exclude list
          # rather than raising the number.
          if [ "$total" -gt 1200 ]; then
            echo "::error::$total packaged files exceeds the 1200 ceiling"
            fail=1
          fi

          # The other direction: these are load-bearing and easy to strip by
          # accident. gtest is on the include path and three test_util files
          # are compiled.
          for pat in '^rocksdb/third-party/gtest-1.8.1/fused-src/' '^rocksdb/test_util/' \
                     '^rocksdb/tools/dump/db_dump_tool\.cc$'; do
            if ! grep -qE "$pat" /tmp/pkg.txt; then
              echo "::error::nothing matches $pat, but the build needs it"
              fail=1
            fi
          done

          exit $fail

  test:
    name: ${{ matrix.build }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        build: [Linux, Linux-ARM, macOS, Windows]
        include:
          - build: Linux
            os: ubuntu-latest
          - build: Linux-ARM
            os: ubuntu-24.04-arm
          - build: macOS
            os: macos-latest
          - build: Windows
            os: windows-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v5
        with:
          submodules: recursive

      - name: Install rust
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          cache-save-if: ${{ github.ref == 'refs/heads/master' }}

      - uses: taiki-e/install-action@nextest

      - name: Remove msys64 # Workaround to resolve link error with C:\msys64\mingw64\bin\libclang.dll
        if: runner.os == 'Windows'
        run: Remove-Item -LiteralPath "C:\msys64\" -Force -Recurse

      - name: Install dependencies
        if: runner.os == 'Windows'
        run: choco install llvm -y

      - name: Mark working directory as read-only
        if: runner.os == 'Linux'
        run: |
          mkdir -p target
          touch Cargo.lock
          chmod -R a-w .
          chmod -R a+w target Cargo.lock

      - name: Run rocksdb tests
        run: cargo nextest run --all

      - name: Mark working directory as writable
        if: runner.os == 'Linux'
        run: chmod -R a+w .

  test-multi-threaded-cf:
    name: ${{ matrix.build }} (multi-threaded-cf)
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        build: [Linux, Linux-ARM, macOS, Windows]
        include:
          - build: Linux
            os: ubuntu-latest
          - build: Linux-ARM
            os: ubuntu-24.04-arm
          - build: macOS
            os: macos-latest
          - build: Windows
            os: windows-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v5
        with:
          submodules: recursive

      - name: Install rust
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          cache-key: "v1-rust-multi-threaded-cf"
          cache-save-if: ${{ github.ref == 'refs/heads/master' }}

      - uses: taiki-e/install-action@nextest

      - name: Remove msys64 # Workaround to resolve link error with C:\msys64\mingw64\bin\libclang.dll
        if: runner.os == 'Windows'
        run: Remove-Item -LiteralPath "C:\msys64\" -Force -Recurse

      - name: Install dependencies
        if: runner.os == 'Windows'
        run: choco install llvm -y

      - name: Mark working directory as read-only
        if: runner.os == 'Linux'
        run: |
          mkdir -p target
          touch Cargo.lock
          chmod -R a-w .
          chmod -R a+w target Cargo.lock

      - name: Run rocksdb tests (multi-threaded-cf)
        run: cargo nextest run --all --features multi-threaded-cf

      - name: Mark working directory as writable
        if: runner.os == 'Linux'
        run: chmod -R a+w .

  test-jemalloc:
    name: Test with jemalloc - ${{ matrix.build }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        build: [Linux, Linux-ARM, macOS]
        include:
          - build: Linux
            os: ubuntu-latest
          - build: Linux-ARM
            os: ubuntu-24.04-arm
          - build: macOS
            os: macos-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v5
        with:
          submodules: recursive

      - name: Install rust
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          cache-key: "v1-rust-jemalloc"
          cache-save-if: ${{ github.ref == 'refs/heads/master' }}

      - uses: taiki-e/install-action@nextest

      - name: Mark working directory as read-only
        if: runner.os == 'Linux'
        run: |
          mkdir -p target
          touch Cargo.lock
          chmod -R a-w .
          chmod -R a+w target Cargo.lock

      - name: Run rocksdb tests with jemalloc
        run: cargo nextest run --all --features jemalloc

      - name: Mark working directory as writable
        if: runner.os == 'Linux'
        run: chmod -R a+w .

  # Everything else runs the debug profile. Release turns on optimization and
  # turns off debug_assertions, which changes both what the optimizer is
  # allowed to assume about the FFI boundary and which assertions run.
  test-release:
    name: Test release profile
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v5
        with:
          submodules: recursive

      - name: Install rust
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          cache-key: "v1-rust-release"
          cache-save-if: ${{ github.ref == 'refs/heads/master' }}

      - uses: taiki-e/install-action@nextest

      - name: Run rocksdb tests (release)
        run: cargo nextest run --all --release

  test-sanitizers:
    name: Test with Address/LeakSanitizer
    runs-on: ubuntu-latest
    steps:
      - name: Checkout sources
        uses: actions/checkout@v5
        with:
          submodules: recursive

      - name: Install rust nightly
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          toolchain: nightly
          components: rust-src
          cache-key: "v1-rust-asan"
          cache-save-if: ${{ github.ref == 'refs/heads/master' }}
          rustflags: ""

      - name: Install dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y llvm clang

      # `--lib --bins` skipped `tests/`, which is where nearly all of the FFI
      # coverage lives, so the job was running almost none of the code it was
      # meant to check. CFLAGS/CXXFLAGS carry the sanitizer into the `cc`
      # build, without which an overflow performed by uninstrumented C++ has no
      # instrumented load to trip on. `build.rs` looks for "sanitize" in those
      # vars and keeps its dev-profile size optimizations out of the way.
      #
      # Do not add `-fsanitize=address` as a link arg. `-Zsanitizer=address`
      # already links rustc's ASan runtime, and adding clang's on top of it
      # gives duplicate symbol definitions for the whole runtime.
      #
      # `--jobs 2` because linking these binaries takes several GB each and a
      # runner-wide parallel link gets the linker OOM-killed.
      - name: Run tests with Address/LeakSanitizer
        env:
          CC: clang
          CXX: clang++
          RUSTFLAGS: -Zsanitizer=address
          RUSTDOCFLAGS: -Zsanitizer=address
          CFLAGS: -fsanitize=address -fno-omit-frame-pointer
          CXXFLAGS: -fsanitize=address -fno-omit-frame-pointer
          ASAN_OPTIONS: detect_leaks=1:detect_stack_use_after_return=1:abort_on_error=1:print_stats=1
        run: |
          cargo +nightly test -Zbuild-std --target x86_64-unknown-linux-gnu \
            --all --lib --bins --tests --jobs 2