Skip to content

Commit 4b447bd

Browse files
committed
feat(foundationdb,bindingtester): add get_estimated_range_size_bytes
Based on apple/foundationdb#1122
1 parent dad2fe3 commit 4b447bd

File tree

4 files changed

+84
-4
lines changed

4 files changed

+84
-4
lines changed

foundationdb-bindingtester/src/main.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,16 @@ static GOT_COMMITTED_VERSION: Element =
2727
static ERROR_NONE: Element = Element::Bytes(Bytes(Cow::Borrowed(b"ERROR: NONE")));
2828
static ERROR_MULTIPLE: Element = Element::Bytes(Bytes(Cow::Borrowed(b"ERROR: MULTIPLE")));
2929
static OK: Element = Element::Bytes(Bytes(Cow::Borrowed(b"OK")));
30+
static ESTIMATE_RANGE_RESPONSE: Element =
31+
Element::Bytes(Bytes(Cow::Borrowed(b"GOT_ESTIMATED_RANGE_SIZE")));
3032

3133
#[cfg(feature = "fdb-6_2")]
3234
static GOT_APPROXIMATE_SIZE: Element =
3335
Element::Bytes(Bytes(Cow::Borrowed(b"GOT_APPROXIMATE_SIZE")));
3436

3537
use crate::fdb::options::{MutationType, StreamingMode};
3638
use tuple::VersionstampOffset;
39+
3740
fn mutation_from_str(s: &str) -> MutationType {
3841
match s {
3942
"ADD" => MutationType::Add,
@@ -171,6 +174,7 @@ enum InstrCode {
171174
GetCommittedVersion,
172175
GetApproximateSize,
173176
WaitFuture,
177+
GetEstimatedRangeSize,
174178

175179
TuplePack,
176180
TuplePackWithVersionstamp,
@@ -247,6 +251,7 @@ impl Instr {
247251
"GET_COMMITTED_VERSION" => GetCommittedVersion,
248252
"GET_APPROXIMATE_SIZE" => GetApproximateSize,
249253
"WAIT_FUTURE" => WaitFuture,
254+
"GET_ESTIMATED_RANGE_SIZE" => GetEstimatedRangeSize,
250255

251256
"TUPLE_PACK" => TuplePack,
252257
"TUPLE_PACK_WITH_VERSIONSTAMP" => TuplePackWithVersionstamp,
@@ -1230,6 +1235,33 @@ impl StackMachine {
12301235
let item = self.pop().await;
12311236
self.stack.push(item);
12321237
}
1238+
1239+
// Pops the top two items off of the stack as BEGIN_KEY and END_KEY to
1240+
// construct a key range. Then call the `getEstimatedRangeSize` API of
1241+
// the language binding. Make sure the API returns without error. Finally
1242+
// push the string "GOT_ESTIMATED_RANGE_SIZE" onto the stack.
1243+
GetEstimatedRangeSize => {
1244+
debug!("get estimated range size");
1245+
#[cfg(feature = "fdb-6_3")]
1246+
{
1247+
let begin = self.pop_bytes().await;
1248+
let end = self.pop_bytes().await;
1249+
1250+
if let Ok(estimate) = trx
1251+
.as_mut()
1252+
.get_estimated_range_size_bytes(&begin, &end)
1253+
.await
1254+
{
1255+
debug!("got an estimate of {} bytes", estimate);
1256+
self.push(number, ESTIMATE_RANGE_RESPONSE.clone().into_owned());
1257+
}
1258+
}
1259+
#[cfg(not(feature = "fdb-6_3"))]
1260+
{
1261+
unimplemented!("get_estimated_range_size requires fdb630+");
1262+
}
1263+
}
1264+
12331265
// Pops the top item off of the stack as N. Pops the next N items off of the
12341266
// stack and packs them as the tuple [item0,item1,...,itemN], and then pushes
12351267
// this single packed value onto the stack.

foundationdb/src/transaction.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,24 @@ impl Transaction {
596596
}
597597
}
598598

599+
/// Get the estimated byte size of the key range based on the byte sample collected by FDB
600+
#[cfg(feature = "fdb-6_3")]
601+
pub fn get_estimated_range_size_bytes(
602+
&self,
603+
begin: &[u8],
604+
end: &[u8],
605+
) -> impl Future<Output = FdbResult<i64>> + Send + Sync + Unpin {
606+
FdbFuture::<i64>::new(unsafe {
607+
fdb_sys::fdb_transaction_get_estimated_range_size_bytes(
608+
self.inner.as_ptr(),
609+
begin.as_ptr(),
610+
fdb_len(begin.len(), "begin"),
611+
end.as_ptr(),
612+
fdb_len(end.len(), "end"),
613+
)
614+
})
615+
}
616+
599617
/// Attempts to commit the sets and clears previously applied to the database snapshot
600618
/// represented by transaction to the actual database.
601619
///

foundationdb/tests/range.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ fn test_range() {
1818
futures::executor::block_on(test_get_range_async()).expect("failed to run");
1919
futures::executor::block_on(test_range_option_async()).expect("failed to run");
2020
futures::executor::block_on(test_get_ranges_async()).expect("failed to run");
21+
#[cfg(feature = "fdb-6_3")]
22+
futures::executor::block_on(test_get_estimate_range()).expect("failed to run");
2123
}
2224

2325
async fn test_get_range_async() -> FdbResult<()> {
@@ -203,3 +205,31 @@ async fn test_range_option_async() -> FdbResult<()> {
203205

204206
Ok(())
205207
}
208+
async fn test_get_estimate_range() -> FdbResult<()> {
209+
const N: usize = 10000;
210+
211+
let db = common::database().await?;
212+
let trx = db.create_trx()?;
213+
let key_begin = "test-rangeoption-";
214+
let key_end = "test-rangeoption.";
215+
let k = |i: u32| format!("{}-{:010}", key_begin, i);
216+
217+
eprintln!("clearing...");
218+
trx.clear_range(key_begin.as_bytes(), key_end.as_bytes());
219+
220+
eprintln!("inserting...");
221+
for i in 0..10000 {
222+
let value = common::random_str(10);
223+
trx.set(k(i).as_bytes(), value.as_bytes());
224+
}
225+
trx.commit().await?;
226+
227+
let trx = db.create_trx()?;
228+
let estimate = trx
229+
.get_estimated_range_size_bytes(key_begin.as_bytes(), key_end.as_bytes())
230+
.await?;
231+
eprintln!("get an estimate of {} bytes", estimate);
232+
assert!(estimate > 0);
233+
234+
Ok(())
235+
}

scripts/run_bindingtester.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ esac
2222
cd ${fdb_builddir:?}
2323

2424
## Get foundationdb source
25-
git clone --depth 1 https://github.com/apple/foundationdb.git -b release-6.1
25+
git clone --depth 1 https://github.com/apple/foundationdb.git -b release-6.3
2626
cd foundationdb
27-
git checkout release-6.1
27+
git checkout release-6.3
2828

2929
## need the python api bindings
3030
make fdb_python
@@ -33,6 +33,6 @@ esac
3333
echo "testers['rust'] = Tester('rust', '${bindingtester}', 2040, 23, MAX_API_VERSION, types=ALL_TYPES)
3434
" >> ./bindings/bindingtester/known_testers.py
3535
./bindings/bindingtester/bindingtester.py --test-name scripted rust
36-
./bindings/bindingtester/bindingtester.py --num-ops 1000 --api-version 610 --test-name api --compare python rust
37-
./bindings/bindingtester/bindingtester.py --num-ops 1000 --api-version 610 --test-name api --concurrency 5 rust
36+
./bindings/bindingtester/bindingtester.py --num-ops 1000 --api-version 630 --test-name api --compare python rust
37+
./bindings/bindingtester/bindingtester.py --num-ops 1000 --api-version 630 --test-name api --concurrency 5 rust
3838
)

0 commit comments

Comments
 (0)