Skip to content

Commit 81d47a9

Browse files
Add # Example docstrings to all public API and remove fastarena re-export
- Add runnable examples to all 32 ConcurrentSkipList methods - Add runnable examples to all 12 FrozenMemtable methods - Add examples to error types (InsertError, BatchError, SealError) - Add examples to iter.rs public methods (Snapshot::iter, Cursor::seek/next_entry/entry/valid) - Remove (was leaking internal dependency) - Add [Unreleased] section to CHANGELOG.md 50 doc tests verified passing.
1 parent bf536db commit 81d47a9

3 files changed

Lines changed: 610 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,23 @@ 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]
9+
10+
### Added
11+
12+
- `# Example` code blocks on every public method and type (50 doc tests)
13+
- `CHANGELOG.md`
14+
15+
### Changed
16+
17+
- `Cargo.toml`: updated `repository` URL to `themankindproject/fastskip`
18+
- `Cargo.toml`: added `documentation`, `homepage`, `readme`, `exclude` fields
19+
- `README.md`: fixed build badge URL to `themankindproject/fastskip`
20+
21+
### Removed
22+
23+
- `pub use fastarena;` re-export (was leaking internal dependency into public API)
24+
825
## [0.1.0] - 2026-03-26
926

1027
### Added

src/iter.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,19 @@ impl<'a> Snapshot<'a> {
107107
/// skipping any node whose insertion sequence number is `>= snap_seq`.
108108
/// This guarantees that only nodes present at the time of the snapshot
109109
/// are yielded.
110+
///
111+
/// # Example
112+
///
113+
/// ```rust
114+
/// use fastskip::ConcurrentSkipList;
115+
///
116+
/// let sl = ConcurrentSkipList::new();
117+
/// sl.insert(b"a", b"1");
118+
/// let snap = sl.snapshot();
119+
///
120+
/// let entries: Vec<_> = snap.iter().collect();
121+
/// assert_eq!(entries.len(), 1);
122+
/// ```
110123
pub fn iter(&self) -> SnapshotIter<'a> {
111124
SnapshotIter {
112125
current: self.head,
@@ -253,6 +266,20 @@ impl<'a> Cursor<'a> {
253266
///
254267
/// Returns `true` if a key was found (cursor is now valid),
255268
/// `false` if all keys in the list are `< target` (cursor is invalid).
269+
///
270+
/// # Example
271+
///
272+
/// ```rust
273+
/// use fastskip::ConcurrentSkipList;
274+
///
275+
/// let sl = ConcurrentSkipList::new();
276+
/// sl.insert(b"a", b"1");
277+
/// sl.insert(b"c", b"3");
278+
///
279+
/// let mut cursor = sl.cursor();
280+
/// assert!(cursor.seek(&sl, b"b")); // lands on "c"
281+
/// assert_eq!(cursor.entry().unwrap().key, b"c");
282+
/// ```
256283
pub fn seek(&mut self, skiplist: &'a ConcurrentSkipList, target: &[u8]) -> bool {
257284
// Walk from head to find the predecessor of target
258285
let mut x = skiplist.skiplist.head;
@@ -299,6 +326,21 @@ impl<'a> Cursor<'a> {
299326
///
300327
/// Returns `true` if a next entry exists (cursor remains valid),
301328
/// `false` if the end of the list was reached (cursor becomes invalid).
329+
///
330+
/// # Example
331+
///
332+
/// ```rust
333+
/// use fastskip::ConcurrentSkipList;
334+
///
335+
/// let sl = ConcurrentSkipList::new();
336+
/// sl.insert(b"a", b"1");
337+
/// sl.insert(b"b", b"2");
338+
///
339+
/// let mut cursor = sl.cursor();
340+
/// assert!(cursor.next_entry()); // "a"
341+
/// assert!(cursor.next_entry()); // "b"
342+
/// assert!(!cursor.next_entry()); // end
343+
/// ```
302344
pub fn next_entry(&mut self) -> bool {
303345
if self.current.is_null() {
304346
return false;
@@ -310,6 +352,20 @@ impl<'a> Cursor<'a> {
310352
/// Get the entry at the cursor's current position.
311353
///
312354
/// Returns `None` if the cursor is invalid (at end or not yet seeked).
355+
///
356+
/// # Example
357+
///
358+
/// ```rust
359+
/// use fastskip::ConcurrentSkipList;
360+
///
361+
/// let sl = ConcurrentSkipList::new();
362+
/// sl.insert(b"a", b"1");
363+
///
364+
/// let cursor = sl.cursor_at(b"a").unwrap();
365+
/// let entry = cursor.entry().unwrap();
366+
/// assert_eq!(entry.key, b"a");
367+
/// assert_eq!(entry.value, b"1");
368+
/// ```
313369
pub fn entry(&self) -> Option<Entry<'a>> {
314370
if self.current.is_null() {
315371
return None;
@@ -325,6 +381,20 @@ impl<'a> Cursor<'a> {
325381
///
326382
/// A cursor is invalid if it was never seeked, if `seek` found no
327383
/// matching key, or if `next_entry` reached the end of the list.
384+
///
385+
/// # Example
386+
///
387+
/// ```rust
388+
/// use fastskip::ConcurrentSkipList;
389+
///
390+
/// let sl = ConcurrentSkipList::new();
391+
/// sl.insert(b"a", b"1");
392+
///
393+
/// let cursor = sl.cursor_at(b"a").unwrap();
394+
/// assert!(cursor.valid());
395+
///
396+
/// assert!(sl.cursor_at(b"z").is_none());
397+
/// ```
328398
pub fn valid(&self) -> bool {
329399
!self.current.is_null()
330400
}

0 commit comments

Comments
 (0)