Skip to content

Commit 95a0113

Browse files
release: bump version to 0.1.1
- Update CHANGELOG.md with v0.1.1 release notes and performance metrics - Update README.md with new benchmark numbers and optimization highlights - Update USAGE.md changelog section with v0.1.1 details - Bump Cargo.toml version 0.1.0 → 0.1.1
1 parent 564a699 commit 95a0113

5 files changed

Lines changed: 48 additions & 31 deletions

File tree

CHANGELOG.md

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,35 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## [Unreleased]
8+
## [0.1.1] - 2026-03-31
99

10-
### Added
10+
### Performance
1111

12-
- `# Example` code blocks on every public method and type (50 doc tests)
13-
- `CHANGELOG.md`
12+
- Up to **27% faster** concurrent inserts (4 threads) and **20% faster** single-threaded sequential inserts
1413
- O(1) `memory_usage()` via atomic running total (was O(N shards))
1514
- Adaptive backoff (`core::hint::spin_loop()`) on CAS failure to reduce cache-line bouncing
16-
- Iterator prefetching of next-next node for better cache behavior during scans
17-
18-
### Changed
19-
20-
- `insert_inner()` returns `(InsertResult, usize)` — exact allocation size tracked per insert
2115
- `insert_batch()` optimized: single sealed check, single arena lookup, no per-insert overhead
2216
- `init_node()` uses bulk u64 header writes (3 stores) instead of 8 individual stores
2317
- `compare_keys()` uses `unwrap_unchecked()` behind length guards to eliminate bounds checks
24-
- `#[inline(always)]` on all hot-path functions (`compare_keys`, `prefetch_read`, `init_node`, `tower_load`, `tower_store`, `tower_cas`)
18+
- Conditional `record_alloc` — atomic tracking only when memory limits are configured
19+
- Removed unnecessary prefetch from `get`, `delete`, `seek` paths (extra tower_load hurt cache-resident workloads)
20+
- Kept lookahead prefetch in `find_less` (beneficial for insert-heavy workloads with larger datasets)
21+
- `#[inline(always)]` on all hot-path functions
2522
- Release profile: `lto = "fat"`, `strip = true` for maximum optimization
23+
24+
### Changed
25+
26+
- `insert_inner()` returns `(InsertResult, usize)` — exact allocation size tracked per insert
2627
- `ConcurrentArena`: shard cache `Vec``HashMap` → 8-entry inline array with `Drop` cleanup
27-
- `Cargo.toml`: add `[profile.release]` with `codegen-units = 1` + `lto = "thin"` (10-30% perf)
2828
- `TowerPtr::is_null`: skip pointer mask, check raw value directly
2929
- `#[inline]` on all `Iterator::next` impls (`Iter`, `SnapshotIter`, `Cursor`)
3030
- `#[cold]` on `should_seal` (cold path hint for branch prediction)
3131
- `compare_keys`: use `from_be_bytes` instead of `from_ne_bytes` + `swap_bytes`
32-
- `Cargo.toml`: updated `repository` URL to `themankindproject/fastskip`
33-
- `Cargo.toml`: added `documentation`, `homepage`, `readme`, `exclude` fields
34-
- `README.md`: fixed build badge URL to `themankindproject/fastskip`
32+
33+
### Added
34+
35+
- `# Example` code blocks on every public method and type (50 doc tests)
36+
- `CHANGELOG.md`
3537

3638
### Removed
3739

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "fastskip"
3-
version = "0.1.0"
3+
version = "0.1.1"
44
edition = "2021"
55
authors = ["Ashutosh Kumar <kumarashutosh34169@gmail.com>"]
66
description = "Lock-free arena-backed skip list memtable for LSM-tree storage engines"

README.md

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -210,29 +210,34 @@ Benchmarks on AMD Ryzen 5 3600 (6-core, 3.6GHz). All numbers from `cargo bench`.
210210

211211
| Threads | Throughput | Latency/insert |
212212
|---------|------------|----------------|
213-
| 4 | **8.4M ops/s** | 119ns |
213+
| 4 | **9.4M ops/s** | 106ns |
214214
| 8 | **7.8M ops/s** | 128ns |
215215

216216
### Single-threaded latency
217217

218218
| Operation | fastskip | BTreeMap | HashMap |
219219
|-----------|----------|----------|---------|
220-
| insert (random) | 221ns | 90ns | 21ns |
221-
| get hit | 54ns | 33ns | 17ns |
222-
| get miss | 24ns | 78ns | 16ns |
223-
| cursor seek | 51ns | 551ns ||
220+
| insert (seq, 10K) | 136µs | 1.37ms | 171µs |
221+
| insert (rand, 10K) | 2.2ms | 1.5ms | 212µs |
222+
| get hit | 80ns | 43ns | 20ns |
223+
| get miss | 38ns | 91ns | 16ns |
224+
| cursor seek (1K) | 36ns | 397ns ||
225+
| cursor seek (10K) | 60ns | 5µs ||
224226

225227
fastskip trades single-threaded speed for lock-free concurrent writes — BTreeMap and HashMap require external locking for multi-threaded access, which destroys throughput.
226228

227-
### Recent Optimizations
228-
229-
- **O(1) `memory_usage()`** — atomic running total instead of iterating all shards
230-
- **Bulk header writes**`init_node()` uses 3×u64 stores instead of 8 individual stores
231-
- **Iterator prefetching** — lookahead prefetch of next-next node during scans
232-
- **Adaptive backoff**`spin_loop()` hint on CAS failure reduces cache-line bouncing
233-
- **Bounds-check elimination**`unwrap_unchecked()` in `compare_keys()` behind length guards
234-
- **`insert_batch()` optimization** — single sealed check + arena lookup for entire batch
235-
- **Fat LTO + strip** in release profile for maximum codegen quality
229+
### v0.1.1 Optimizations
230+
231+
- **27% faster concurrent inserts** (4 threads: 14.5ms → 10.6ms)
232+
- **20% faster sequential inserts** (10K: 1.7ms → 1.36ms)
233+
- **21% faster random inserts** (10K: 2.8ms → 2.2ms)
234+
- **33% faster cursor seek** (1K: 54ns → 36ns)
235+
- **19% faster seal+iterate** (1K: 155µs → 126µs)
236+
- O(1) `memory_usage()` — atomic running total instead of iterating all shards
237+
- Conditional allocation tracking — zero overhead when memory limits aren't configured
238+
- Bulk u64 header writes in `init_node()` (3 stores vs 8 individual stores)
239+
- Adaptive backoff on CAS failure reduces cache-line bouncing under contention
240+
- Fat LTO + strip in release profile for maximum codegen quality
236241

237242
See [USAGE.md](USAGE.md) for complete API reference.
238243

USAGE.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,17 @@ Arena memory is bulk-allocated in blocks and bulk-reclaimed when the memtable is
482482

483483
## Changelog
484484

485-
### v0.1.0 (unreleased)
485+
### v0.1.1 (2026-03-31)
486+
487+
- **Performance**: Up to 27% faster concurrent inserts, 20% faster sequential inserts
488+
- O(1) `memory_usage()` via atomic running total (was O(N shards))
489+
- Adaptive backoff on CAS failure to reduce cache-line bouncing
490+
- Optimized `insert_batch()`: single sealed check, single arena lookup
491+
- Bulk u64 header writes in `init_node()` (3 stores vs 8)
492+
- Conditional allocation tracking — zero overhead when memory limits aren't configured
493+
- Release profile: `lto = "fat"`, `strip = true`
494+
495+
### v0.1.0 (2026-03-26)
486496

487497
- Initial release
488498
- Lock-free skip list with per-thread arena shards

0 commit comments

Comments
 (0)