mirror of
https://github.com/facebook/sapling.git
synced 2024-10-10 16:57:49 +03:00
Support BlobstoreWithLink in Sqlblob
Summary: We designed the schema to make this simple to implement - it's literally a metadata read and a metadata write. Reviewed By: ikostia Differential Revision: D22233922 fbshipit-source-id: b392b4a3a23859c6106934f73ef60084cc4de62c
This commit is contained in:
parent
b1c85aaf4b
commit
7938a1957a
@ -23,7 +23,9 @@ use crate::facebook::myadmin_delay;
|
||||
use crate::myadmin_delay_dummy as myadmin_delay;
|
||||
use crate::store::{ChunkSqlStore, ChunkingMethod, DataSqlStore};
|
||||
use anyhow::{format_err, Error, Result};
|
||||
use blobstore::{Blobstore, BlobstoreGetData, BlobstoreMetadata, CountedBlobstore};
|
||||
use blobstore::{
|
||||
Blobstore, BlobstoreGetData, BlobstoreMetadata, BlobstoreWithLink, CountedBlobstore,
|
||||
};
|
||||
use bytes::BytesMut;
|
||||
use cloned::cloned;
|
||||
use context::CoreContext;
|
||||
@ -374,3 +376,29 @@ impl Blobstore for Sqlblob {
|
||||
async move { data_store.is_present(&key).await }.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
impl BlobstoreWithLink for Sqlblob {
|
||||
fn link(
|
||||
&self,
|
||||
_ctx: CoreContext,
|
||||
existing_key: String,
|
||||
link_key: String,
|
||||
) -> BoxFuture<'static, Result<(), Error>> {
|
||||
cloned!(self.data_store);
|
||||
async move {
|
||||
let existing_data = data_store.get(&existing_key).await?.ok_or_else(|| {
|
||||
format_err!("Key {} does not exist in the blobstore", existing_key)
|
||||
})?;
|
||||
data_store
|
||||
.put(
|
||||
&link_key,
|
||||
existing_data.ctime,
|
||||
&existing_data.id,
|
||||
existing_data.count,
|
||||
existing_data.chunking_method,
|
||||
)
|
||||
.await
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
|
@ -131,3 +131,66 @@ async fn dedup(fb: FacebookInit) {
|
||||
"Chunking method differs"
|
||||
);
|
||||
}
|
||||
|
||||
#[fbinit::compat_test]
|
||||
async fn link(fb: FacebookInit) {
|
||||
let ctx = CoreContext::test_mock(fb);
|
||||
// Generate unique keys.
|
||||
let suffix: String = thread_rng().sample_iter(&Alphanumeric).take(10).collect();
|
||||
let key1 = format!("manifoldblob_test_{}", suffix);
|
||||
let suffix: String = thread_rng().sample_iter(&Alphanumeric).take(10).collect();
|
||||
let key2 = format!("manifoldblob_test_{}", suffix);
|
||||
|
||||
let bs = Arc::new(Sqlblob::with_sqlite_in_memory().unwrap());
|
||||
|
||||
let mut bytes_in = [0u8; 64];
|
||||
thread_rng().fill_bytes(&mut bytes_in);
|
||||
|
||||
let blobstore_bytes = BlobstoreBytes::from_bytes(Bytes::copy_from_slice(&bytes_in));
|
||||
|
||||
assert!(
|
||||
!bs.is_present(ctx.clone(), key1.clone()).await.unwrap(),
|
||||
"Blob should not exist yet"
|
||||
);
|
||||
|
||||
assert!(
|
||||
!bs.is_present(ctx.clone(), key2.clone()).await.unwrap(),
|
||||
"Blob should not exist yet"
|
||||
);
|
||||
|
||||
// Write a fresh blob
|
||||
bs.put(ctx.clone(), key1.clone(), blobstore_bytes.clone())
|
||||
.await
|
||||
.unwrap();
|
||||
// Link to a different key
|
||||
bs.link(ctx.clone(), key1.clone(), key2.clone())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Check that reads from the two keys match
|
||||
let bytes1 = bs.get(ctx.clone(), key1.clone()).await.unwrap();
|
||||
let bytes2 = bs.get(ctx.clone(), key2.clone()).await.unwrap();
|
||||
assert_eq!(
|
||||
bytes1.unwrap().as_raw_bytes(),
|
||||
bytes2.unwrap().as_raw_bytes()
|
||||
);
|
||||
|
||||
// Reach inside the store and confirm it only stored the data once
|
||||
let data_store = bs.as_inner().get_data_store();
|
||||
let row1 = data_store
|
||||
.get(&key1)
|
||||
.await
|
||||
.unwrap()
|
||||
.expect("Blob 1 not found");
|
||||
let row2 = data_store
|
||||
.get(&key2)
|
||||
.await
|
||||
.unwrap()
|
||||
.expect("Blob 2 not found");
|
||||
assert_eq!(row1.id, row2.id, "Chunk stored under different ids");
|
||||
assert_eq!(row1.count, row2.count, "Chunk count differs");
|
||||
assert_eq!(
|
||||
row1.chunking_method, row2.chunking_method,
|
||||
"Chunking method differs"
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user