Skip to content

Commit c47cac0

Browse files
committed
feat: allow skip full block download in first few page read in block
1 parent f85b395 commit c47cac0

File tree

4 files changed

+44
-11
lines changed

4 files changed

+44
-11
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "sqlite-vfs-http"
3-
version = "0.1.1"
3+
version = "0.1.2"
44
edition = "2021"
55
authors = ["DarkSky <darksky2048@gmail.com>"]
66
license = "AGPL-3.0-only"

src/buffer.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ type Fetch = Box<dyn Fn(usize, usize) -> Result<Vec<u8>> + Send + Sync>;
3535

3636
pub struct LazyBuffer {
3737
blocks: HashMap<usize, LazyBlock>,
38+
blocks_read: HashMap<usize, usize>,
3839
block_size: usize,
3940
download_threshold: usize,
4041
length: usize,
@@ -45,6 +46,7 @@ impl LazyBuffer {
4546
pub fn new(length: usize, block_size: usize, download_threshold: usize, fetch: Fetch) -> Self {
4647
Self {
4748
blocks: HashMap::new(),
49+
blocks_read: HashMap::new(),
4850
block_size,
4951
download_threshold,
5052
length,
@@ -76,13 +78,25 @@ impl LazyBuffer {
7678
}
7779
let block_index = offset / self.block_size;
7880
let block_offset = offset - block_index * self.block_size;
79-
if !self.blocks.contains_key(&block_index) && buf.len() <= self.download_threshold {
81+
let block_read = self
82+
.blocks_read
83+
.get(&block_index)
84+
.copied()
85+
.unwrap_or_default();
86+
let buffer_size = buf.len();
87+
if !self.blocks.contains_key(&block_index)
88+
&& block_read + buffer_size <= self.download_threshold
89+
{
8090
// skip full block fetch if buf is smaller than download_threshold
81-
let data = (self.fetch)(offset, buf.len())?;
82-
if data.len() != buf.len() {
91+
let data = (self.fetch)(offset, buffer_size)?;
92+
if data.len() != buffer_size {
8393
return Err(Error::new(ErrorKind::UnexpectedEof, "read out of bounds"));
8494
}
8595
buf.copy_from_slice(&data);
96+
self.blocks_read
97+
.entry(block_index)
98+
.and_modify(|size| *size += buffer_size)
99+
.or_insert(buffer_size);
86100
} else {
87101
self.get_block(block_index)?.read(buf, block_offset)?;
88102
}

src/lib.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,44 @@ use std::sync::{Arc, Once, RwLock};
1010
use utils::AtomicRuntime;
1111
use vfs::HttpVfs;
1212

13-
pub use vfs::HTTP_VFS;
13+
const SQLITE_PAGE_SIZE: usize = 1024 * 4;
14+
pub const HTTP_VFS: &str = "http";
1415

1516
pub struct HttpVfsRegister {
17+
/// how many pages in block, default is 8MB, 2048 pages
1618
block_size: usize,
19+
/// read the first few pages of each block without downloading the entire block
1720
download_threshold: usize,
21+
/// sqlite's page size is 4KB by default
22+
page_size: usize,
1823
}
1924

2025
impl HttpVfsRegister {
2126
pub fn new() -> Self {
2227
Self {
23-
block_size: 1024 * 1024 * 4,
24-
download_threshold: 1024,
28+
block_size: SQLITE_PAGE_SIZE * 1024 * 2,
29+
download_threshold: 0,
30+
page_size: SQLITE_PAGE_SIZE,
2531
}
2632
}
2733

28-
pub fn with_block_size(self, block_size: usize) -> Self {
29-
Self { block_size, ..self }
34+
pub fn with_block_size(self, page_num: usize) -> Self {
35+
Self {
36+
block_size: page_num * self.page_size,
37+
..self
38+
}
39+
}
40+
41+
/// Set how many page read don't download full block
42+
pub fn with_download_threshold(self, page_num: usize) -> Self {
43+
Self {
44+
download_threshold: page_num * self.page_size,
45+
..self
46+
}
47+
}
48+
49+
pub fn with_page_size(self, page_size: usize) -> Self {
50+
Self { page_size, ..self }
3051
}
3152

3253
pub fn register(self) {

src/vfs.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ use std::{
66
time::Duration,
77
};
88

9-
pub const HTTP_VFS: &str = "http";
10-
119
pub struct HttpVfs {
1210
pub(crate) block_size: usize,
1311
pub(crate) download_threshold: usize,

0 commit comments

Comments
 (0)