Skip to content

Commit b5dc49b

Browse files
committed
move segment key to storage mod
1 parent 2059d02 commit b5dc49b

File tree

3 files changed

+94
-92
lines changed

3 files changed

+94
-92
lines changed

libsql-wal/src/storage/backend/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use fst::Map;
88
use uuid::Uuid;
99

1010
use super::{RestoreOptions, Result};
11+
use super::{RestoreOptions, Result, SegmentKey};
1112
use crate::io::file::FileExt;
1213
use libsql_sys::name::NamespaceName;
1314

libsql-wal/src/storage/backend/s3.rs

Lines changed: 1 addition & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use std::fmt;
44
use std::mem::size_of;
55
use std::path::Path;
66
use std::pin::Pin;
7-
use std::str::FromStr;
87
use std::sync::Arc;
98
use std::task::Poll;
109

@@ -28,7 +27,7 @@ use crate::io::compat::copy_to_file;
2827
use crate::io::{FileExt, Io, StdIO};
2928
use crate::segment::compacted::CompactedSegmentDataHeader;
3029
use crate::segment::Frame;
31-
use crate::storage::{Error, RestoreOptions, Result};
30+
use crate::storage::{Error, RestoreOptions, Result, SegmentKey};
3231
use crate::LIBSQL_MAGIC;
3332

3433
pub struct S3Backend<IO> {
@@ -300,95 +299,6 @@ pub struct S3Config {
300299
cluster_id: String,
301300
}
302301

303-
/// SegmentKey is used to index segment data, where keys a lexicographically ordered.
304-
/// The scheme is `{u64::MAX - start_frame_no}-{u64::MAX - end_frame_no}`. With that naming convention, when looking for
305-
/// the segment containing 'n', we can perform a prefix search with "{u64::MAX - n}". The first
306-
/// element of the range will be the biggest segment that contains n if it exists.
307-
/// Beware that if no segments contain n, either the smallest segment not containing n, if n < argmin
308-
/// {start_frame_no}, or the largest segment if n > argmax {end_frame_no} will be returned.
309-
/// e.g:
310-
/// ```ignore
311-
/// let mut map = BTreeMap::new();
312-
///
313-
/// let meta = SegmentMeta { start_frame_no: 1, end_frame_no: 100 };
314-
/// map.insert(SegmentKey(&meta).to_string(), meta);
315-
///
316-
/// let meta = SegmentMeta { start_frame_no: 101, end_frame_no: 500 };
317-
/// map.insert(SegmentKey(&meta).to_string(), meta);
318-
///
319-
/// let meta = SegmentMeta { start_frame_no: 101, end_frame_no: 1000 };
320-
/// map.insert(SegmentKey(&meta).to_string(), meta);
321-
///
322-
/// map.range(format!("{:019}", u64::MAX - 50)..).next();
323-
/// map.range(format!("{:019}", u64::MAX - 0)..).next();
324-
/// map.range(format!("{:019}", u64::MAX - 1)..).next();
325-
/// map.range(format!("{:019}", u64::MAX - 100)..).next();
326-
/// map.range(format!("{:019}", u64::MAX - 101)..).next();
327-
/// map.range(format!("{:019}", u64::MAX - 5000)..).next();
328-
/// ```
329-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
330-
pub struct SegmentKey {
331-
pub start_frame_no: u64,
332-
pub end_frame_no: u64,
333-
}
334-
335-
impl PartialOrd for SegmentKey {
336-
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
337-
match self.start_frame_no.partial_cmp(&other.start_frame_no) {
338-
Some(core::cmp::Ordering::Equal) => {}
339-
ord => return ord,
340-
}
341-
self.end_frame_no.partial_cmp(&other.end_frame_no)
342-
}
343-
}
344-
345-
impl Ord for SegmentKey {
346-
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
347-
self.partial_cmp(other).unwrap()
348-
}
349-
}
350-
351-
impl SegmentKey {
352-
pub(crate) fn includes(&self, frame_no: u64) -> bool {
353-
(self.start_frame_no..=self.end_frame_no).contains(&frame_no)
354-
}
355-
}
356-
357-
impl From<&SegmentMeta> for SegmentKey {
358-
fn from(value: &SegmentMeta) -> Self {
359-
Self {
360-
start_frame_no: value.start_frame_no,
361-
end_frame_no: value.end_frame_no,
362-
}
363-
}
364-
}
365-
366-
impl FromStr for SegmentKey {
367-
type Err = ();
368-
369-
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
370-
let (rev_start_fno, s) = s.split_at(20);
371-
let start_frame_no = u64::MAX - rev_start_fno.parse::<u64>().map_err(|_| ())?;
372-
let (_, rev_end_fno) = s.split_at(1);
373-
let end_frame_no = u64::MAX - rev_end_fno.parse::<u64>().map_err(|_| ())?;
374-
Ok(Self {
375-
start_frame_no,
376-
end_frame_no,
377-
})
378-
}
379-
}
380-
381-
impl fmt::Display for SegmentKey {
382-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
383-
write!(
384-
f,
385-
"{:019}-{:019}",
386-
u64::MAX - self.start_frame_no,
387-
u64::MAX - self.end_frame_no,
388-
)
389-
}
390-
}
391-
392302
struct FolderKey<'a> {
393303
cluster_id: &'a str,
394304
namespace: &'a NamespaceName,

libsql-wal/src/storage/mod.rs

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use std::collections::BTreeMap;
2+
use std::fmt;
23
use std::future::Future;
34
use std::path::PathBuf;
5+
use std::str::FromStr;
46
use std::sync::Arc;
57

68
use chrono::{DateTime, Utc};
@@ -14,7 +16,7 @@ use crate::io::{FileExt, Io, StdIO};
1416
use crate::segment::compacted::CompactedSegment;
1517
use crate::segment::{sealed::SealedSegment, Segment};
1618

17-
use self::backend::s3::SegmentKey;
19+
use self::backend::SegmentMeta;
1820
pub use self::error::Error;
1921

2022
pub mod async_storage;
@@ -30,6 +32,95 @@ pub enum RestoreOptions {
3032
Timestamp(DateTime<Utc>),
3133
}
3234

35+
/// SegmentKey is used to index segment data, where keys a lexicographically ordered.
36+
/// The scheme is `{u64::MAX - start_frame_no}-{u64::MAX - end_frame_no}`. With that naming convention, when looking for
37+
/// the segment containing 'n', we can perform a prefix search with "{u64::MAX - n}". The first
38+
/// element of the range will be the biggest segment that contains n if it exists.
39+
/// Beware that if no segments contain n, either the smallest segment not containing n, if n < argmin
40+
/// {start_frame_no}, or the largest segment if n > argmax {end_frame_no} will be returned.
41+
/// e.g:
42+
/// ```ignore
43+
/// let mut map = BTreeMap::new();
44+
///
45+
/// let meta = SegmentMeta { start_frame_no: 1, end_frame_no: 100 };
46+
/// map.insert(SegmentKey(&meta).to_string(), meta);
47+
///
48+
/// let meta = SegmentMeta { start_frame_no: 101, end_frame_no: 500 };
49+
/// map.insert(SegmentKey(&meta).to_string(), meta);
50+
///
51+
/// let meta = SegmentMeta { start_frame_no: 101, end_frame_no: 1000 };
52+
/// map.insert(SegmentKey(&meta).to_string(), meta);
53+
///
54+
/// map.range(format!("{:019}", u64::MAX - 50)..).next();
55+
/// map.range(format!("{:019}", u64::MAX - 0)..).next();
56+
/// map.range(format!("{:019}", u64::MAX - 1)..).next();
57+
/// map.range(format!("{:019}", u64::MAX - 100)..).next();
58+
/// map.range(format!("{:019}", u64::MAX - 101)..).next();
59+
/// map.range(format!("{:019}", u64::MAX - 5000)..).next();
60+
/// ```
61+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
62+
pub struct SegmentKey {
63+
pub start_frame_no: u64,
64+
pub end_frame_no: u64,
65+
}
66+
67+
impl PartialOrd for SegmentKey {
68+
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
69+
match self.start_frame_no.partial_cmp(&other.start_frame_no) {
70+
Some(core::cmp::Ordering::Equal) => {}
71+
ord => return ord,
72+
}
73+
self.end_frame_no.partial_cmp(&other.end_frame_no)
74+
}
75+
}
76+
77+
impl Ord for SegmentKey {
78+
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
79+
self.partial_cmp(other).unwrap()
80+
}
81+
}
82+
83+
impl SegmentKey {
84+
pub(crate) fn includes(&self, frame_no: u64) -> bool {
85+
(self.start_frame_no..=self.end_frame_no).contains(&frame_no)
86+
}
87+
}
88+
89+
impl From<&SegmentMeta> for SegmentKey {
90+
fn from(value: &SegmentMeta) -> Self {
91+
Self {
92+
start_frame_no: value.start_frame_no,
93+
end_frame_no: value.end_frame_no,
94+
}
95+
}
96+
}
97+
98+
impl FromStr for SegmentKey {
99+
type Err = ();
100+
101+
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
102+
let (rev_start_fno, s) = s.split_at(20);
103+
let start_frame_no = u64::MAX - rev_start_fno.parse::<u64>().map_err(|_| ())?;
104+
let (_, rev_end_fno) = s.split_at(1);
105+
let end_frame_no = u64::MAX - rev_end_fno.parse::<u64>().map_err(|_| ())?;
106+
Ok(Self {
107+
start_frame_no,
108+
end_frame_no,
109+
})
110+
}
111+
}
112+
113+
impl fmt::Display for SegmentKey {
114+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115+
write!(
116+
f,
117+
"{:019}-{:019}",
118+
u64::MAX - self.start_frame_no,
119+
u64::MAX - self.end_frame_no,
120+
)
121+
}
122+
}
123+
33124
pub trait Storage: Send + Sync + 'static {
34125
type Segment: Segment;
35126
type Config;

0 commit comments

Comments
 (0)