lithos 0.1.0 → 0.1.1
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 +4 -4
- data/README.md +11 -101
- data/lib/lithos.rb +4 -170
- metadata +10 -84
- data/CHANGELOG.md +0 -28
- data/ext/lithos/extconf.rb +0 -20
- data/ext/lithos/lithos.cpp +0 -1026
- data/lib/lithos/version.rb +0 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 010db6b8b65ba9a4c32abe95c6d58dfc11a9e8a50e9599aaca10b32460a545dc
|
|
4
|
+
data.tar.gz: 912268f45027878b57a7cf0629c8b7efac5043f1df9e02f7855e91e2bbbf0d2f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ee08a3bac4e558814df30ae9c92a9a119912be3be89828755bb85186b68570cd86d32f2746f195ec4d7edd48ceb0e7628918f42fb6a1784875cdf7978c95690c
|
|
7
|
+
data.tar.gz: adc8d75678a6625460996dd376021ec4ed18101982015ac2ae96344df6533ba57e465aaca9ab6f353585dfeb8a53af10187de71ea6f1b638aa643456ceb9402c
|
data/README.md
CHANGED
|
@@ -1,101 +1,11 @@
|
|
|
1
|
-
# lithos
|
|
2
|
-
|
|
3
|
-
**
|
|
4
|
-
|
|
5
|
-
`
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
detected and discarded.
|
|
13
|
-
- **Ordered keys** — keys are stored sorted (unsigned-byte order), so you get
|
|
14
|
-
`each`, `each_key`, and range `scan`s for free.
|
|
15
|
-
- **Binary safe** — keys and values are arbitrary byte strings (embedded NULs OK).
|
|
16
|
-
|
|
17
|
-
The niche it fills: every other ordered + crash-safe Ruby KV store is a binding
|
|
18
|
-
to an external C/C++ library (LMDB/LevelDB/RocksDB) that's a pain to build on a
|
|
19
|
-
native-MSVC Windows Ruby. `lithos` is self-contained and builds with
|
|
20
|
-
[`vcvars`](https://rubygems.org/gems/vcvars) — no prebuilt database needed.
|
|
21
|
-
|
|
22
|
-
## Requirements
|
|
23
|
-
|
|
24
|
-
- **Windows** with a native **MSVC (mswin)** Ruby. Not supported on MinGW/UCRT.
|
|
25
|
-
- Visual Studio 2017+ / Build Tools with the **Desktop development with C++** workload.
|
|
26
|
-
|
|
27
|
-
## Install
|
|
28
|
-
|
|
29
|
-
```sh
|
|
30
|
-
gem install lithos
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## Usage
|
|
34
|
-
|
|
35
|
-
```ruby
|
|
36
|
-
require "lithos"
|
|
37
|
-
|
|
38
|
-
Lithos.open("data/mydb") do |db|
|
|
39
|
-
db["alpha"] = "one"
|
|
40
|
-
db.put("beta", "two")
|
|
41
|
-
db.put("\x00raw\xff", "binary ok") # arbitrary binary keys + values
|
|
42
|
-
|
|
43
|
-
db["alpha"] # => "one"
|
|
44
|
-
db["missing"] # => nil
|
|
45
|
-
db.key?("beta") # => true
|
|
46
|
-
db.fetch("nope", "default") # => "default" (or raises KeyError)
|
|
47
|
-
db.delete("beta") # => true (existed)
|
|
48
|
-
|
|
49
|
-
# ordered iteration (ascending unsigned-byte key order)
|
|
50
|
-
db.each { |k, v| puts "#{k}=#{v}" }
|
|
51
|
-
db.each_key { |k| puts k }
|
|
52
|
-
|
|
53
|
-
# ordered range scans
|
|
54
|
-
db.scan(gte: "a", lt: "m") { |k, v| ... } # gt/lt exclusive, gte/lte inclusive
|
|
55
|
-
db.range("a", "m") { |k, v| ... } # half-open [a, m)
|
|
56
|
-
db.scan(gte: "a").to_a # Enumerator without a block
|
|
57
|
-
|
|
58
|
-
db.size # live key count
|
|
59
|
-
db.flush # seal the memtable into an SSTable
|
|
60
|
-
db.compact # merge SSTables, dropping shadowed keys + tombstones
|
|
61
|
-
end # closed automatically (flush + fsync)
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
Open without a block when you want to manage the lifetime yourself:
|
|
65
|
-
|
|
66
|
-
```ruby
|
|
67
|
-
db = Lithos.open("data/mydb", sync: true)
|
|
68
|
-
db["k"] = "v"
|
|
69
|
-
db.close
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
Data persists across reopens, and survives a crash (process kill, power loss at
|
|
73
|
-
the OS-flush boundary): reopening replays the WAL and discards any partial tail.
|
|
74
|
-
|
|
75
|
-
## How it works
|
|
76
|
-
|
|
77
|
-
```
|
|
78
|
-
put/delete ──> WAL (append + CRC + fsync) ──> memtable (sorted std::map)
|
|
79
|
-
│ (size threshold)
|
|
80
|
-
▼
|
|
81
|
-
SSTable (immutable, mmap'd:
|
|
82
|
-
sorted data + bloom + sparse index)
|
|
83
|
-
get ──> memtable ──> SSTables newest→oldest (bloom-filtered)
|
|
84
|
-
compact ──> k-way merge of all SSTables ──> one SSTable (drops tombstones)
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
The set of live SSTables + the active WAL is recorded in a `MANIFEST` that is
|
|
88
|
-
rewritten atomically (temp file + `FlushFileBuffers` + atomic rename), so the
|
|
89
|
-
on-disk catalog is never observed half-updated.
|
|
90
|
-
|
|
91
|
-
## Notes
|
|
92
|
-
|
|
93
|
-
- **Durability vs speed:** `sync: true` (default) `fsync`s every write. For bulk
|
|
94
|
-
loads, `Lithos.open(path, sync: false)` skips per-write `fsync` (call `#flush`
|
|
95
|
-
or `#close` to make data durable) — faster, but a crash can lose recent writes.
|
|
96
|
-
- **Single writer:** a store takes an exclusive directory lock on open; it is not
|
|
97
|
-
safe to share one store across threads (give each thread its own, or use a Mutex).
|
|
98
|
-
|
|
99
|
-
## License
|
|
100
|
-
|
|
101
|
-
[MIT](LICENSE.txt).
|
|
1
|
+
# lithos (discontinued)
|
|
2
|
+
|
|
3
|
+
**lithos is no longer maintained.** This final release (0.1.1) contains no
|
|
4
|
+
code: installing it compiles nothing, and `require "lithos"` raises a
|
|
5
|
+
`LoadError` explaining the discontinuation.
|
|
6
|
+
|
|
7
|
+
Use sqlite3, or PStore from the standard library instead.
|
|
8
|
+
|
|
9
|
+
Earlier releases remain on RubyGems only because RubyGems does not allow
|
|
10
|
+
versions older than 30 days to be yanked. They are unmaintained and not
|
|
11
|
+
recommended.
|
data/lib/lithos.rb
CHANGED
|
@@ -1,170 +1,4 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
# lithos — a small embedded, ordered, crash-safe key-value store.
|
|
7
|
-
#
|
|
8
|
-
# Lithos.open("data/db") do |db|
|
|
9
|
-
# db["alpha"] = "1"
|
|
10
|
-
# db.put("\x00bin\xff", "raw") # binary keys/values welcome
|
|
11
|
-
# db["alpha"] # => "1"
|
|
12
|
-
# db.scan(gte: "a", lt: "m") { |k, v| } # ordered range
|
|
13
|
-
# end # auto-closed (flushes + fsyncs)
|
|
14
|
-
module Lithos
|
|
15
|
-
# Open a store at `path` (a directory, created if missing). Options:
|
|
16
|
-
# sync: durably fsync each write before it returns (default true)
|
|
17
|
-
# memtable_bytes: flush the in-memory table to an SSTable past this size
|
|
18
|
-
#
|
|
19
|
-
# With a block: yields the store, closes it when the block returns (even on
|
|
20
|
-
# error), and returns the block's value. Without a block: returns the store,
|
|
21
|
-
# and the caller must #close it.
|
|
22
|
-
def self.open(path, **opts)
|
|
23
|
-
db = DB.new(path, **opts)
|
|
24
|
-
return db unless block_given?
|
|
25
|
-
|
|
26
|
-
begin
|
|
27
|
-
yield db
|
|
28
|
-
ensure
|
|
29
|
-
db.close
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
class DB
|
|
34
|
-
include Enumerable
|
|
35
|
-
|
|
36
|
-
# --- mutators (forbidden while an each/scan is in progress) --------------
|
|
37
|
-
# The merge iterator holds raw pointers into memory-mapped SSTables and live
|
|
38
|
-
# memtable iterators; mutating mid-scan would free them underneath it. We
|
|
39
|
-
# refuse here with a plain Ruby exception (which unwinds safely), rather than
|
|
40
|
-
# let it reach the C engine during iteration.
|
|
41
|
-
|
|
42
|
-
def put(key, value)
|
|
43
|
-
forbid_during_iteration!
|
|
44
|
-
_put(key, value)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def delete(key)
|
|
48
|
-
forbid_during_iteration!
|
|
49
|
-
_delete(key)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def flush
|
|
53
|
-
forbid_during_iteration!
|
|
54
|
-
_flush
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def compact
|
|
58
|
-
forbid_during_iteration!
|
|
59
|
-
_compact
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def close
|
|
63
|
-
forbid_during_iteration!
|
|
64
|
-
_close
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# Hash-like access. `db[k]` => value or nil; `db[k] = v` stores v.
|
|
68
|
-
def [](key)
|
|
69
|
-
get(key)
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def []=(key, value)
|
|
73
|
-
put(key, value)
|
|
74
|
-
value
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
# Like Hash#fetch: return the value, else the block result, else the default,
|
|
78
|
-
# else raise KeyError. (Stored values are never nil, so nil == absent.)
|
|
79
|
-
def fetch(key, *default)
|
|
80
|
-
if default.size > 1
|
|
81
|
-
raise ArgumentError, "wrong number of arguments (given #{default.size + 1}, expected 1..2)"
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
value = get(key)
|
|
85
|
-
return value unless value.nil?
|
|
86
|
-
return yield(key) if block_given?
|
|
87
|
-
return default.first unless default.empty?
|
|
88
|
-
|
|
89
|
-
raise KeyError, "key not found: #{key.inspect}"
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
alias include? key?
|
|
93
|
-
alias has_key? key?
|
|
94
|
-
alias member? key?
|
|
95
|
-
|
|
96
|
-
# Iterate all pairs in ascending (unsigned-byte) key order.
|
|
97
|
-
def each(&block)
|
|
98
|
-
return enum_for(:each) unless block
|
|
99
|
-
|
|
100
|
-
bounded_each(nil, false, nil, false, &block)
|
|
101
|
-
end
|
|
102
|
-
alias each_pair each
|
|
103
|
-
|
|
104
|
-
# Iterate keys only, ascending.
|
|
105
|
-
def each_key
|
|
106
|
-
return enum_for(:each_key) unless block_given?
|
|
107
|
-
|
|
108
|
-
bounded_each(nil, false, nil, false) { |k, _| yield k }
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
# Ordered range scan. Bounds are optional; gt/lt are exclusive, gte/lte
|
|
112
|
-
# inclusive. Returns an Enumerator without a block.
|
|
113
|
-
def scan(gte: nil, gt: nil, lte: nil, lt: nil, &block)
|
|
114
|
-
lower, lower_incl = gt ? [gt, false] : (gte ? [gte, true] : [nil, false])
|
|
115
|
-
upper, upper_incl = lt ? [lt, false] : (lte ? [lte, true] : [nil, false])
|
|
116
|
-
bounded_each(lower, lower_incl, upper, upper_incl, &block)
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
# Half-open range [from, to) in ascending order.
|
|
120
|
-
def range(from, to, &block)
|
|
121
|
-
bounded_each(from, true, to, false, &block)
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
# Number of live keys. O(n) — counts via an ordered scan.
|
|
125
|
-
def size
|
|
126
|
-
n = 0
|
|
127
|
-
each_key { n += 1 }
|
|
128
|
-
n
|
|
129
|
-
end
|
|
130
|
-
alias length size
|
|
131
|
-
|
|
132
|
-
def empty?
|
|
133
|
-
each { return false }
|
|
134
|
-
true
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
def to_h
|
|
138
|
-
h = {}
|
|
139
|
-
each { |k, v| h[k] = v }
|
|
140
|
-
h
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
def inspect
|
|
144
|
-
"#<Lithos::DB path=#{path.inspect}#{closed? ? ' (closed)' : ''}>"
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
private
|
|
148
|
-
|
|
149
|
-
def forbid_during_iteration!
|
|
150
|
-
return unless (@iterating || 0).positive?
|
|
151
|
-
|
|
152
|
-
raise Error, "lithos: cannot modify the store during iteration"
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
# Shared range driver; positional args so enum_for forwards cleanly. The
|
|
156
|
-
# @iterating depth lets reads nest while mutations are blocked, and the
|
|
157
|
-
# ensure guarantees the count is restored even on break/exception.
|
|
158
|
-
def bounded_each(lower, lower_incl, upper, upper_incl, &block)
|
|
159
|
-
return enum_for(:bounded_each, lower, lower_incl, upper, upper_incl) unless block
|
|
160
|
-
|
|
161
|
-
@iterating = (@iterating || 0) + 1
|
|
162
|
-
begin
|
|
163
|
-
_each_range(lower, lower_incl, upper, upper_incl, &block)
|
|
164
|
-
ensure
|
|
165
|
-
@iterating -= 1
|
|
166
|
-
end
|
|
167
|
-
self
|
|
168
|
-
end
|
|
169
|
-
end
|
|
170
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
raise LoadError, "lithos is discontinued and this release contains no code. Use sqlite3, or PStore from the standard library instead." \
|
|
4
|
+
" Earlier lithos releases are unmaintained and not recommended."
|
metadata
CHANGED
|
@@ -1,104 +1,30 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lithos
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ned
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
-
dependencies:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
requirements:
|
|
16
|
-
- - "~>"
|
|
17
|
-
- !ruby/object:Gem::Version
|
|
18
|
-
version: '13.0'
|
|
19
|
-
type: :development
|
|
20
|
-
prerelease: false
|
|
21
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
-
requirements:
|
|
23
|
-
- - "~>"
|
|
24
|
-
- !ruby/object:Gem::Version
|
|
25
|
-
version: '13.0'
|
|
26
|
-
- !ruby/object:Gem::Dependency
|
|
27
|
-
name: rake-compiler
|
|
28
|
-
requirement: !ruby/object:Gem::Requirement
|
|
29
|
-
requirements:
|
|
30
|
-
- - "~>"
|
|
31
|
-
- !ruby/object:Gem::Version
|
|
32
|
-
version: '1.2'
|
|
33
|
-
type: :development
|
|
34
|
-
prerelease: false
|
|
35
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
-
requirements:
|
|
37
|
-
- - "~>"
|
|
38
|
-
- !ruby/object:Gem::Version
|
|
39
|
-
version: '1.2'
|
|
40
|
-
- !ruby/object:Gem::Dependency
|
|
41
|
-
name: minitest
|
|
42
|
-
requirement: !ruby/object:Gem::Requirement
|
|
43
|
-
requirements:
|
|
44
|
-
- - "~>"
|
|
45
|
-
- !ruby/object:Gem::Version
|
|
46
|
-
version: '5.0'
|
|
47
|
-
type: :development
|
|
48
|
-
prerelease: false
|
|
49
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
-
requirements:
|
|
51
|
-
- - "~>"
|
|
52
|
-
- !ruby/object:Gem::Version
|
|
53
|
-
version: '5.0'
|
|
54
|
-
- !ruby/object:Gem::Dependency
|
|
55
|
-
name: vcvars
|
|
56
|
-
requirement: !ruby/object:Gem::Requirement
|
|
57
|
-
requirements:
|
|
58
|
-
- - "~>"
|
|
59
|
-
- !ruby/object:Gem::Version
|
|
60
|
-
version: '0.1'
|
|
61
|
-
- - ">="
|
|
62
|
-
- !ruby/object:Gem::Version
|
|
63
|
-
version: 0.1.1
|
|
64
|
-
type: :development
|
|
65
|
-
prerelease: false
|
|
66
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
67
|
-
requirements:
|
|
68
|
-
- - "~>"
|
|
69
|
-
- !ruby/object:Gem::Version
|
|
70
|
-
version: '0.1'
|
|
71
|
-
- - ">="
|
|
72
|
-
- !ruby/object:Gem::Version
|
|
73
|
-
version: 0.1.1
|
|
74
|
-
description: |
|
|
75
|
-
lithos is a self-contained embedded key-value store written from scratch as a
|
|
76
|
-
native extension — no external database dependency. It uses a log-structured
|
|
77
|
-
merge (LSM) tree: a write-ahead log makes every write durable, an in-memory
|
|
78
|
-
sorted memtable flushes to immutable SSTables (with bloom filters), and
|
|
79
|
-
compaction merges them. Keys and values are arbitrary binary strings; keys
|
|
80
|
-
are kept in sorted order so you get ordered iteration and range scans, plus
|
|
81
|
-
crash recovery via WAL replay. Windows MSVC (mswin) Ruby only.
|
|
11
|
+
dependencies: []
|
|
12
|
+
description: lithos is discontinued. This final release contains no code and exists
|
|
13
|
+
only so that installing lithos explains the discontinuation instead of building
|
|
14
|
+
an unmaintained native extension.
|
|
82
15
|
executables: []
|
|
83
|
-
extensions:
|
|
84
|
-
- ext/lithos/extconf.rb
|
|
16
|
+
extensions: []
|
|
85
17
|
extra_rdoc_files: []
|
|
86
18
|
files:
|
|
87
|
-
- CHANGELOG.md
|
|
88
19
|
- LICENSE.txt
|
|
89
20
|
- README.md
|
|
90
|
-
- ext/lithos/extconf.rb
|
|
91
|
-
- ext/lithos/lithos.cpp
|
|
92
21
|
- lib/lithos.rb
|
|
93
|
-
- lib/lithos/version.rb
|
|
94
|
-
homepage: https://github.com/main-path/lithos
|
|
95
22
|
licenses:
|
|
96
23
|
- MIT
|
|
97
24
|
metadata:
|
|
98
|
-
homepage_uri: https://github.com/main-path/lithos
|
|
99
|
-
changelog_uri: https://github.com/main-path/lithos/blob/main/CHANGELOG.md
|
|
100
|
-
bug_tracker_uri: https://github.com/main-path/lithos/issues
|
|
101
25
|
rubygems_mfa_required: 'true'
|
|
26
|
+
post_install_message: lithos is discontinued and this release contains no code. Use
|
|
27
|
+
sqlite3, or PStore from the standard library instead.
|
|
102
28
|
rdoc_options: []
|
|
103
29
|
require_paths:
|
|
104
30
|
- lib
|
|
@@ -106,7 +32,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
106
32
|
requirements:
|
|
107
33
|
- - ">="
|
|
108
34
|
- !ruby/object:Gem::Version
|
|
109
|
-
version: '
|
|
35
|
+
version: '2.0'
|
|
110
36
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
111
37
|
requirements:
|
|
112
38
|
- - ">="
|
|
@@ -115,5 +41,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
115
41
|
requirements: []
|
|
116
42
|
rubygems_version: 3.6.9
|
|
117
43
|
specification_version: 4
|
|
118
|
-
summary:
|
|
44
|
+
summary: Discontinued. Use sqlite3, or PStore from the standard library instead.
|
|
119
45
|
test_files: []
|
data/CHANGELOG.md
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to this project are documented here. The format is based on
|
|
4
|
-
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
|
|
5
|
-
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
-
|
|
7
|
-
## [Unreleased]
|
|
8
|
-
|
|
9
|
-
## [0.1.0] - 2026-05-30
|
|
10
|
-
|
|
11
|
-
### Added
|
|
12
|
-
- `Lithos.open(path, sync:, memtable_bytes:)` with block (auto-close) and
|
|
13
|
-
non-block forms; `#close`, `#closed?`, `#path`.
|
|
14
|
-
- `#put`/`#[]=`, `#get`/`#[]`, `#delete`, `#key?` (+ `include?`/`has_key?`),
|
|
15
|
-
`#fetch` (with default/block, raises `KeyError`).
|
|
16
|
-
- Ordered iteration: `#each`, `#each_key`, `#scan(gte:/gt:/lte:/lt:)`,
|
|
17
|
-
`#range(from, to)`; `Enumerable` mixed in; `#size`/`#length`, `#empty?`, `#to_h`.
|
|
18
|
-
- `#flush` (seal the memtable into an SSTable) and `#compact` (merge SSTables,
|
|
19
|
-
dropping shadowed keys and tombstones).
|
|
20
|
-
- LSM engine: CRC32 write-ahead log (durable per write in sync mode), sorted
|
|
21
|
-
memtable, immutable memory-mapped SSTables with bloom filters + sparse index,
|
|
22
|
-
atomically-published MANIFEST catalog, crash recovery via WAL replay (torn /
|
|
23
|
-
bad-CRC tail discarded), and an exclusive single-writer directory lock.
|
|
24
|
-
- Arbitrary binary keys and values (embedded NULs); lexicographic unsigned-byte
|
|
25
|
-
key ordering.
|
|
26
|
-
|
|
27
|
-
[Unreleased]: https://github.com/main-path/lithos/compare/v0.1.0...HEAD
|
|
28
|
-
[0.1.0]: https://github.com/main-path/lithos/releases/tag/v0.1.0
|
data/ext/lithos/extconf.rb
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
#
|
|
3
|
-
# extconf.rb for the lithos LSM key-value store extension.
|
|
4
|
-
|
|
5
|
-
require "mkmf"
|
|
6
|
-
|
|
7
|
-
unless RbConfig::CONFIG["target_os"] =~ /mswin/
|
|
8
|
-
abort <<~MSG
|
|
9
|
-
lithos requires a native Windows MSVC (mswin) Ruby — its storage engine uses
|
|
10
|
-
Win32 file APIs (memory-mapped SSTables, FlushFileBuffers, atomic rename) and
|
|
11
|
-
is built with cl.exe. Your Ruby is "#{RbConfig['arch']}".
|
|
12
|
-
MSG
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
# C++ engine (std::map/std::string/std::vector/std::priority_queue) — needs C++ exceptions.
|
|
16
|
-
$CXXFLAGS << " -EHsc"
|
|
17
|
-
|
|
18
|
-
# kernel32 (file APIs / mapping) is linked by default; no extra import libs needed.
|
|
19
|
-
|
|
20
|
-
create_makefile("lithos/lithos")
|