slatedb 0.3.2.beta.3-aarch64-linux → 0.4.2-aarch64-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e76279bb9bc5aa478e7e23ac4511c207e91c8b14cdf607cb14d6de4bb313294d
4
- data.tar.gz: b445f20056d97a6bde1db9a015c8dde2882a51b34a63dc5e30ee83f3584b73f7
3
+ metadata.gz: a048a2dc5967cf32c55414f25edd93b101f37e473d9f4852641d4b10b6da4b9c
4
+ data.tar.gz: 6ba87318128ed507047bc9abf0ded29d1d2c8774f4b55f63d161b5feae2cabdc
5
5
  SHA512:
6
- metadata.gz: ae4a654eadc4731ef29d64d6623a827cf200f554935659e4daf0b603f97ede90abf3122611b8d559c7b26dd11b1d870a0f48777376f1175478eb11bc835961e7
7
- data.tar.gz: 2705167ceefbaa4c7deac2a1562c4e383f55a69a8cca4be1372f64ee7ff826b5a7e25acf43cf2a1678829d049b68d0e2e9447973d88caac3fade97782b3ece62
6
+ metadata.gz: f1639d74b9dc65c95966bd2cca5835c091096a5af2603b8769a208c866529ba5f48bbff44127b39dd6f1f08fa86b7457735ef21616517ed2f96792f4c05d7bd4
7
+ data.tar.gz: 05a547c559a58bdc6ff64223f685621f2363525e08cdbb5b80a263e5a415d621bbd0454f480a92eaacaf10e44f407e8fec1810dc5cf2cec64f5f1ea387a1e005
data/README.md CHANGED
@@ -8,10 +8,6 @@ Ruby bindings for [SlateDB](https://slatedb.io), a cloud-native embedded key-val
8
8
 
9
9
  These bindings are still in early development, and while SlateDB itself is used in Production, these bindings have yet to be. Contributions are welcome!
10
10
 
11
- ### TODO
12
-
13
- - [ ] Cross-compile native extensions
14
-
15
11
  ## Installation
16
12
 
17
13
  Add this line to your application's Gemfile:
@@ -32,8 +28,7 @@ Or install it yourself as:
32
28
  gem install slatedb
33
29
  ```
34
30
 
35
- > [!IMPORTANT]
36
- > This gem currently requires a working Rust toolchain to install until the dependencies are cross-compiled.
31
+ Precompiled native gems are published for common Linux and Darwin platforms. Building from source still requires a Rust toolchain.
37
32
 
38
33
  ## Usage
39
34
 
@@ -268,6 +263,27 @@ db.transaction do |txn|
268
263
  end
269
264
  ```
270
265
 
266
+ You can narrow a prefix scan to a sub-range using the `from:` (inclusive) and
267
+ `to:` (exclusive) options (SlateDB >= 0.14.0). Both are key *suffixes* that are
268
+ appended to the prefix, so they let you paginate or resume within a prefix
269
+ without building full-key ranges by hand. The scan never escapes the prefix.
270
+
271
+ ```ruby
272
+ # Keys "user:100" (inclusive) up to "user:200" (exclusive)
273
+ db.scan_prefix("user:", from: "100", to: "200").each do |key, value|
274
+ puts "#{key}: #{value}"
275
+ end
276
+
277
+ # Only a lower bound: from "user:500" to the end of the prefix
278
+ db.scan_prefix("user:", from: "500")
279
+
280
+ # Only an upper bound: from the start of the prefix up to (but not including) "user:100"
281
+ db.scan_prefix("user:", to: "100")
282
+
283
+ # Sub-ranges compose with order: and work on transactions, snapshots, and readers
284
+ db.scan_prefix("user:", from: "100", to: "200", order: :desc)
285
+ ```
286
+
271
287
  ### Merge Operations
272
288
 
273
289
  Merge operations allow you to combine values without reading them first, useful for counters, append-only logs, and similar patterns:
@@ -487,13 +503,24 @@ SlateDb::Reader.open("/tmp/mydb", url: "s3://bucket/path") do |reader|
487
503
  end
488
504
  end
489
505
 
490
- # Open at a specific checkpoint
506
+ # Open at a specific checkpoint (pins the reader to that checkpoint's state)
491
507
  SlateDb::Reader.open("/tmp/mydb",
492
508
  url: "s3://bucket/path",
493
509
  checkpoint_id: "uuid-here") do |reader|
494
510
  reader.get("key")
495
511
  end
496
512
 
513
+ # Follow the latest state without managing a checkpoint (SlateDB >= 0.15.0).
514
+ # This performs no object-store writes but offers no protection from garbage
515
+ # collection, so it suits read-only or mirrored databases. By default (neither
516
+ # checkpoint_id nor follow_latest set) the reader creates and periodically
517
+ # refreshes its own checkpoint instead.
518
+ SlateDb::Reader.open("/tmp/mydb",
519
+ url: "s3://bucket/path",
520
+ follow_latest: true) do |reader|
521
+ reader.get("key")
522
+ end
523
+
497
524
  # Enable the reader's on-disk cache and cap its open file handles
498
525
  # (max_open_file_handles, added in SlateDB 0.13.0, only takes effect when
499
526
  # cache_root is set, since that is what enables the cached object store).
@@ -604,6 +631,37 @@ Exception hierarchy:
604
631
  - Ruby 3.3+
605
632
  - Rust toolchain (for building from source)
606
633
 
634
+ ## Releasing
635
+
636
+ Releases publish a generic `ruby` platform gem and **precompiled native gems**
637
+ for six platforms (`x86_64-linux`, `aarch64-linux`, `x86_64-linux-musl`,
638
+ `aarch64-linux-musl`, `arm64-darwin`, `x86_64-darwin`) to
639
+ [rubygems.org](https://rubygems.org/gems/slatedb). The generic gem keeps
640
+ RubyGems' latest-version metadata aligned; supported platforms should still
641
+ resolve to their matching precompiled native gem.
642
+
643
+ ### Cutting a release
644
+
645
+ The gem version comes from `lib/slatedb/version.rb`, not from the tag. Use the
646
+ mise helper to bump, commit, tag, and push in one step (must be on `main` with a
647
+ clean working tree):
648
+
649
+ ```bash
650
+ mise run release:cut 0.4.3
651
+ # or: mise run release:cut 0.4.3 --no-push
652
+ ```
653
+
654
+ That updates `SlateDb::VERSION`, commits `Release v0.4.3`, creates tag `v0.4.3`,
655
+ and pushes the commit + tag (unless `--no-push`). The tag triggers the release
656
+ pipeline.
657
+
658
+ The `release:verify-tag` step fails the build if the tag and
659
+ `SlateDb::VERSION` disagree, so the tag (`v0.4.3`) must match `version.rb`
660
+ (`0.4.3`).
661
+
662
+ To exercise packaging without publishing, trigger a manual build on the
663
+ `slatedb-rb-release` pipeline or set `DRY_RUN=true`.
664
+
607
665
  ## Development
608
666
 
609
667
  After checking out the repo, run:
Binary file
Binary file
Binary file
@@ -246,6 +246,11 @@ module SlateDb
246
246
  # @param cache_blocks [Boolean, nil] Whether to cache blocks
247
247
  # @param max_fetch_tasks [Integer, nil] Maximum number of fetch tasks
248
248
  # @param order [Symbol, String, nil] Iteration order (:asc/:ascending or :desc/:descending)
249
+ # @param from [String, nil] Inclusive lower bound suffix, appended to the
250
+ # prefix, to start scanning from (e.g. prefix "user:" with from "100"
251
+ # starts at "user:100"). Defaults to the start of the prefix.
252
+ # @param to [String, nil] Exclusive upper bound suffix, appended to the
253
+ # prefix, to stop scanning at. Defaults to the end of the prefix.
249
254
  # @return [Iterator] An iterator over key-value pairs
250
255
  #
251
256
  # @example Scan all user keys
@@ -253,8 +258,13 @@ module SlateDb
253
258
  # puts "#{key}: #{value}"
254
259
  # end
255
260
  #
261
+ # @example Scan a sub-range within a prefix
262
+ # # keys "user:100" (inclusive) up to "user:200" (exclusive)
263
+ # db.scan_prefix("user:", from: "100", to: "200")
264
+ #
256
265
  def scan_prefix(prefix, durability_filter: nil, dirty: nil,
257
- read_ahead_bytes: nil, cache_blocks: nil, max_fetch_tasks: nil, order: nil, &)
266
+ read_ahead_bytes: nil, cache_blocks: nil, max_fetch_tasks: nil, order: nil,
267
+ from: nil, to: nil, &)
258
268
  opts = scan_options(
259
269
  durability_filter: durability_filter,
260
270
  dirty: dirty,
@@ -263,6 +273,8 @@ module SlateDb
263
273
  max_fetch_tasks: max_fetch_tasks,
264
274
  order: order
265
275
  )
276
+ opts[:subrange_from] = from if from
277
+ opts[:subrange_to] = to if to
266
278
 
267
279
  iter = if opts.empty?
268
280
  _scan_prefix(prefix)
@@ -7,7 +7,14 @@ module SlateDb
7
7
  #
8
8
  # @param path [String] The path identifier for the database
9
9
  # @param url [String, nil] Optional object store URL
10
- # @param checkpoint_id [String, nil] Optional checkpoint UUID to read at
10
+ # @param checkpoint_id [String, nil] Optional checkpoint UUID to read at. When
11
+ # given, the reader is pinned to that checkpoint and does not follow new writes.
12
+ # @param follow_latest [Boolean, nil] When true, the reader tails the latest
13
+ # manifest without creating or maintaining its own checkpoint. This performs no
14
+ # object-store writes but provides no protection from garbage collection, so it
15
+ # is best suited to read-only or mirrored databases. Mutually exclusive with
16
+ # +checkpoint_id+. When neither is set (the default), the reader manages its own
17
+ # checkpoint and refreshes it periodically. (Requires SlateDB >= 0.15.0)
11
18
  # @param manifest_poll_interval [Integer, nil] Poll interval in milliseconds
12
19
  # @param checkpoint_lifetime [Integer, nil] Checkpoint lifetime in milliseconds
13
20
  # @param max_memtable_bytes [Integer, nil] Maximum memtable size in bytes
@@ -35,16 +42,20 @@ module SlateDb
35
42
  # @example Open at a specific checkpoint
36
43
  # reader = SlateDb::Reader.open("/tmp/mydb", checkpoint_id: "uuid-here")
37
44
  #
45
+ # @example Follow the latest state without managing a checkpoint
46
+ # reader = SlateDb::Reader.open("/tmp/mydb", follow_latest: true)
47
+ #
38
48
  # @example Enable the on-disk cache and cap its open file handles
39
49
  # reader = SlateDb::Reader.open("/tmp/mydb",
40
50
  # cache_root: "/var/cache/slatedb",
41
51
  # max_open_file_handles: 256)
42
52
  #
43
- def open(path, url: nil, checkpoint_id: nil,
53
+ def open(path, url: nil, checkpoint_id: nil, follow_latest: nil,
44
54
  manifest_poll_interval: nil, checkpoint_lifetime: nil,
45
55
  max_memtable_bytes: nil, cache_root: nil, max_open_file_handles: nil,
46
56
  merge_operator: nil)
47
57
  opts = {}
58
+ opts[:follow_latest] = follow_latest unless follow_latest.nil?
48
59
  opts[:manifest_poll_interval] = manifest_poll_interval if manifest_poll_interval
49
60
  opts[:checkpoint_lifetime] = checkpoint_lifetime if checkpoint_lifetime
50
61
  opts[:max_memtable_bytes] = max_memtable_bytes if max_memtable_bytes
@@ -127,16 +138,25 @@ module SlateDb
127
138
  # @param read_ahead_bytes [Integer, nil] Number of bytes to read ahead
128
139
  # @param cache_blocks [Boolean, nil] Whether to cache blocks
129
140
  # @param max_fetch_tasks [Integer, nil] Maximum number of fetch tasks
141
+ # @param from [String, nil] Inclusive lower bound suffix, appended to the
142
+ # prefix, to start scanning from (e.g. prefix "user:" with from "100"
143
+ # starts at "user:100"). Defaults to the start of the prefix.
144
+ # @param to [String, nil] Exclusive upper bound suffix, appended to the
145
+ # prefix, to stop scanning at. Defaults to the end of the prefix.
130
146
  # @return [Iterator] An iterator over key-value pairs
131
147
  #
132
148
  def scan_prefix(prefix, durability_filter: nil, dirty: nil,
133
- read_ahead_bytes: nil, cache_blocks: nil, max_fetch_tasks: nil, &)
134
- opts = {}
135
- opts[:durability_filter] = durability_filter.to_s if durability_filter
136
- opts[:dirty] = dirty unless dirty.nil?
137
- opts[:read_ahead_bytes] = read_ahead_bytes if read_ahead_bytes
138
- opts[:cache_blocks] = cache_blocks unless cache_blocks.nil?
139
- opts[:max_fetch_tasks] = max_fetch_tasks if max_fetch_tasks
149
+ read_ahead_bytes: nil, cache_blocks: nil, max_fetch_tasks: nil,
150
+ from: nil, to: nil, &)
151
+ opts = {
152
+ durability_filter: durability_filter&.to_s,
153
+ dirty: dirty,
154
+ read_ahead_bytes: read_ahead_bytes,
155
+ cache_blocks: cache_blocks,
156
+ max_fetch_tasks: max_fetch_tasks,
157
+ subrange_from: from,
158
+ subrange_to: to
159
+ }.compact
140
160
 
141
161
  iter = if opts.empty?
142
162
  _scan_prefix(prefix)
@@ -59,16 +59,24 @@ module SlateDb
59
59
  # @param read_ahead_bytes [Integer, nil] Number of bytes to read ahead
60
60
  # @param cache_blocks [Boolean, nil] Whether to cache blocks
61
61
  # @param max_fetch_tasks [Integer, nil] Maximum number of fetch tasks
62
+ # @param from [String, nil] Inclusive lower bound suffix, appended to the
63
+ # prefix, to start scanning from. Defaults to the start of the prefix.
64
+ # @param to [String, nil] Exclusive upper bound suffix, appended to the
65
+ # prefix, to stop scanning at. Defaults to the end of the prefix.
62
66
  # @return [Iterator] An iterator over key-value pairs
63
67
  #
64
68
  def scan_prefix(prefix, durability_filter: nil, dirty: nil,
65
- read_ahead_bytes: nil, cache_blocks: nil, max_fetch_tasks: nil, &)
66
- opts = {}
67
- opts[:durability_filter] = durability_filter.to_s if durability_filter
68
- opts[:dirty] = dirty unless dirty.nil?
69
- opts[:read_ahead_bytes] = read_ahead_bytes if read_ahead_bytes
70
- opts[:cache_blocks] = cache_blocks unless cache_blocks.nil?
71
- opts[:max_fetch_tasks] = max_fetch_tasks if max_fetch_tasks
69
+ read_ahead_bytes: nil, cache_blocks: nil, max_fetch_tasks: nil,
70
+ from: nil, to: nil, &)
71
+ opts = {
72
+ durability_filter: durability_filter&.to_s,
73
+ dirty: dirty,
74
+ read_ahead_bytes: read_ahead_bytes,
75
+ cache_blocks: cache_blocks,
76
+ max_fetch_tasks: max_fetch_tasks,
77
+ subrange_from: from,
78
+ subrange_to: to
79
+ }.compact
72
80
 
73
81
  iter = if opts.empty?
74
82
  _scan_prefix(prefix)
@@ -98,16 +98,24 @@ module SlateDb
98
98
  # @param read_ahead_bytes [Integer, nil] Number of bytes to read ahead
99
99
  # @param cache_blocks [Boolean, nil] Whether to cache blocks
100
100
  # @param max_fetch_tasks [Integer, nil] Maximum number of fetch tasks
101
+ # @param from [String, nil] Inclusive lower bound suffix, appended to the
102
+ # prefix, to start scanning from. Defaults to the start of the prefix.
103
+ # @param to [String, nil] Exclusive upper bound suffix, appended to the
104
+ # prefix, to stop scanning at. Defaults to the end of the prefix.
101
105
  # @return [Iterator] An iterator over key-value pairs
102
106
  #
103
107
  def scan_prefix(prefix, durability_filter: nil, dirty: nil,
104
- read_ahead_bytes: nil, cache_blocks: nil, max_fetch_tasks: nil, &)
105
- opts = {}
106
- opts[:durability_filter] = durability_filter.to_s if durability_filter
107
- opts[:dirty] = dirty unless dirty.nil?
108
- opts[:read_ahead_bytes] = read_ahead_bytes if read_ahead_bytes
109
- opts[:cache_blocks] = cache_blocks unless cache_blocks.nil?
110
- opts[:max_fetch_tasks] = max_fetch_tasks if max_fetch_tasks
108
+ read_ahead_bytes: nil, cache_blocks: nil, max_fetch_tasks: nil,
109
+ from: nil, to: nil, &)
110
+ opts = {
111
+ durability_filter: durability_filter&.to_s,
112
+ dirty: dirty,
113
+ read_ahead_bytes: read_ahead_bytes,
114
+ cache_blocks: cache_blocks,
115
+ max_fetch_tasks: max_fetch_tasks,
116
+ subrange_from: from,
117
+ subrange_to: to
118
+ }.compact
111
119
 
112
120
  iter = if opts.empty?
113
121
  _scan_prefix(prefix)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SlateDb
4
- VERSION = "0.3.2.beta.3"
4
+ VERSION = "0.4.2"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slatedb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2.beta.3
4
+ version: 0.4.2
5
5
  platform: aarch64-linux
6
6
  authors:
7
7
  - SlateDB Contributors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-06-16 00:00:00.000000000 Z
11
+ date: 2026-08-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake