Skip to content

Commit

Permalink
[storage] Do not move values at end #163 (#164)
Browse files Browse the repository at this point in the history
* Update file_storage.rs

* Update storage.rs

* Update storage_impl.rs

* Update pr.yaml
  • Loading branch information
michaelvlach authored Sep 7, 2022
1 parent c50dd66 commit 528f299
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
- uses: actions/checkout@v3
- uses: taiki-e/install-action@cargo-llvm-cov
- run: rustup component add llvm-tools-preview
- run: cargo llvm-cov --fail-uncovered-regions 89 --fail-uncovered-functions 0 --fail-uncovered-lines 0
- run: cargo llvm-cov --fail-uncovered-regions 92 --fail-uncovered-functions 0 --fail-uncovered-lines 0

test:
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ pub(crate) trait Storage<T: StorageImpl = Self>: StorageImpl<T> {

if record.size != new_size {
self.transaction();
self.move_record_to_end(index, new_size, new_size, &mut record)?;
self.resize_record(index, new_size, new_size, &mut record)?;
self.commit()?;
}

Expand Down
14 changes: 14 additions & 0 deletions src/storage/file_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,20 @@ mod tests {
);
}

#[test]
fn resize_at_end_does_not_move() {
let test_file = TestFile::from("./file_storage-resize_at_end_does_not_move.agdb");
let mut storage = FileStorage::try_from(test_file.file_name().clone()).unwrap();

let index = storage.insert(&1_i64).unwrap();
let size = storage.size().unwrap();
let value_size = storage.value_size(index).unwrap();

storage.resize_value(index, value_size + 8).unwrap();

assert_eq!(storage.size(), Ok(size + 8));
}

#[test]
fn resize_value_greater() {
let test_file = TestFile::from("./file_storage-resize_value_greater.agdb");
Expand Down
33 changes: 29 additions & 4 deletions src/storage/storage_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pub(crate) trait StorageImpl<T = Self> {
let new_size = offset + value_size as u64;

if new_size > record.size {
self.move_record_to_end(index, new_size, offset, record)?;
self.resize_record(index, new_size, offset, record)?;
}

Ok(())
Expand All @@ -97,6 +97,14 @@ pub(crate) trait StorageImpl<T = Self> {
self.write(std::io::SeekFrom::Start(position), (-index).serialize())
}

fn is_at_end(&mut self, record: &StorageRecord) -> Result<bool, DbError> {
let file_size = self.seek(std::io::SeekFrom::End(0))?;
Ok(
(record.position + std::mem::size_of::<StorageRecord>() as u64 + record.size)
== file_size,
)
}

fn move_record_to_end(
&mut self,
index: i64,
Expand All @@ -112,9 +120,6 @@ pub(crate) trait StorageImpl<T = Self> {
new_size,
)?;
self.invalidate_record(index, old_position)?;
self.set_len(record.position + std::mem::size_of::<StorageRecord>() as u64 + new_size)?;
*self.record_mut(index) = record.clone();

Ok(())
}

Expand Down Expand Up @@ -163,6 +168,26 @@ pub(crate) trait StorageImpl<T = Self> {
fn record(&self, index: i64) -> Result<StorageRecord, DbError>;
fn record_mut(&mut self, index: i64) -> &mut StorageRecord;
fn remove_index(&mut self, index: i64);

fn resize_record(
&mut self,
index: i64,
new_size: u64,
offset: u64,
record: &mut StorageRecord,
) -> Result<(), DbError> {
if self.is_at_end(record)? {
record.size = new_size;
} else {
self.move_record_to_end(index, new_size, offset, record)?;
}

self.set_len(record.position + std::mem::size_of::<StorageRecord>() as u64 + new_size)?;
*self.record_mut(index) = record.clone();

Ok(())
}

fn seek(&mut self, position: std::io::SeekFrom) -> Result<u64, DbError>;
fn set_len(&mut self, len: u64) -> Result<(), DbError>;
fn set_records(&mut self, records: Vec<StorageRecordWithIndex>);
Expand Down

0 comments on commit 528f299

Please sign in to comment.