Skip to content

2018 edition + async/await #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
unstable_features = true
merge_imports = true
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["foundationdb",
members = ["foundationdb",
"foundationdb-sys",
"foundationdb-gen",
"foundationdb-bench"]
Expand Down
4 changes: 3 additions & 1 deletion foundationdb-bench/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "foundationdb-bench"
version = "0.1.0"
authors = ["Benjamin Fry <[email protected]>"]
edition = "2018"

description = """
Bindings to the C api for FoundationDB
Expand All @@ -21,11 +22,12 @@ travis-ci = { repository = "bluejekyll/foundationdb-rs" }

[dependencies]
rand = "0.7"
futures = "0.1"
futures-preview = { version = "0.3.0-alpha.17", features = ["compat", "nightly", "async-await"] }
foundationdb = { version = "*", path = "../foundationdb" }
stopwatch = "0"
log = "0.4"
env_logger = "0.6"
structopt = "0.2"
tokio = "=0.2.0-alpha.2"

[build-dependencies]
140 changes: 57 additions & 83 deletions foundationdb-bench/src/bin/fdb-bench.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
extern crate foundationdb as fdb;
extern crate futures;
extern crate rand;
extern crate stopwatch;
#[macro_use]
extern crate log;
extern crate env_logger;
extern crate structopt;

use std::sync::atomic::*;
use std::sync::Arc;
#![feature(async_await)]

use env_logger;
use log::info;
use structopt;

use std::sync::{atomic::*, Arc};

use futures::future::*;
use rand::prelude::*;
use rand::rngs::mock::StepRng;
use rand::{prelude::*, rngs::mock::StepRng};
use stopwatch::Stopwatch;
use structopt::StructOpt;

use fdb::error::*;
use fdb::*;
use tokio::runtime::Builder;

use foundationdb::{self as fdb, error::*, *};

#[derive(Clone)]
struct Counter {
Expand Down Expand Up @@ -51,11 +47,8 @@ struct BenchRunner {

impl BenchRunner {
fn new(db: Database, rng: StepRng, counter: Counter, opt: &Opt) -> Self {
let mut key_buf = Vec::with_capacity(opt.key_len);
key_buf.resize(opt.key_len, 0u8);

let mut val_buf = Vec::with_capacity(opt.val_len);
val_buf.resize(opt.val_len, 0u8);
let key_buf = vec![0; opt.key_len];
let val_buf = vec![0; opt.val_len];

let trx = db.create_trx().expect("failed to create trx");

Expand All @@ -71,33 +64,22 @@ impl BenchRunner {
}
}

//TODO: impl future
fn run(self) -> Box<Future<Item = (), Error = Error>> {
Box::new(loop_fn(self, Self::step))
}

//TODO: impl future
fn step(mut self) -> Box<Future<Item = Loop<(), Self>, Error = Error>> {
let trx = self.trx.take().unwrap();

for _ in 0..self.trx_batch_size {
self.rng.fill_bytes(&mut self.key_buf);
self.rng.fill_bytes(&mut self.val_buf);
self.key_buf[0] = 0x01;
trx.set(&self.key_buf, &self.val_buf);
}
async fn run(mut self) -> Result<()> {
let mut trx = self.trx.take().unwrap();
loop {
for _ in 0..self.trx_batch_size {
self.rng.fill_bytes(&mut self.key_buf);
self.rng.fill_bytes(&mut self.val_buf);
self.key_buf[0] = 0x01;
trx.set(&self.key_buf, &self.val_buf);
}

let f = trx.commit().map(move |trx| {
trx = trx.commit().await?;
trx.reset();
self.trx = Some(trx);

if self.counter.decr(self.trx_batch_size) {
Loop::Continue(self)
} else {
Loop::Break(())
if !self.counter.decr(self.trx_batch_size) {
return Ok(());
}
});
Box::new(f)
}
}
}

Expand All @@ -108,34 +90,23 @@ struct Bench {
}

impl Bench {
fn run(self) {
async fn run(self) {
let opt = &self.opt;
let counter = Counter::new(opt.count);

let mut handles = Vec::new();

let sw = Stopwatch::start_new();

let step = (opt.queue_depth + opt.threads - 1) / opt.threads;
let mut start = 0;
for _ in 0..opt.threads {
let end = std::cmp::min(start + step, opt.queue_depth);

let range = start..end;
let counter = counter.clone();
let b = self.clone();
let handle = std::thread::spawn(move || b.run_range(range, counter).wait());
handles.push(handle);

start = end;
}
let start = 0;
let end = std::cmp::min(start + step, opt.queue_depth);
let range = start..end;
let counter = counter.clone();
let b = self.clone();

for handle in handles {
handle
.join()
.expect("failed to join")
.expect("failed to run bench");
}
b.run_range(range, counter)
.await
.expect("error running range");

let elapsed = sw.elapsed_ms() as usize;

Expand All @@ -146,22 +117,18 @@ impl Bench {
);
}

fn run_range(
&self,
r: std::ops::Range<usize>,
counter: Counter,
) -> Box<Future<Item = (), Error = Error>> {
async fn run_range(&self, r: std::ops::Range<usize>, counter: Counter) -> Result<()> {
let runners = r
.into_iter()
.map(|n| {
// With deterministic Rng, benchmark with same parameters will overwrite same set
// of keys again, which makes benchmark result stable.
let rng = StepRng::new(n as u64, 1);
BenchRunner::new(self.db.clone(), rng, counter.clone(), &self.opt).run()
}).collect::<Vec<_>>();
})
.collect::<Vec<_>>();

let f = join_all(runners).map(|_| ());
Box::new(f)
join_all(runners).await;
Ok(())
}
}

Expand Down Expand Up @@ -192,6 +159,11 @@ fn main() {

info!("opt: {:?}", opt);

let rt = Builder::new()
.core_threads(opt.threads)
.build()
.expect("failed to build tokio runtime");

let network = fdb::init().expect("failed to init network");

let handle = std::thread::spawn(move || {
Expand All @@ -204,18 +176,20 @@ fn main() {

network.wait();

let cluster_path = fdb::default_config_path();
let cluster = Cluster::new(cluster_path)
.wait()
.expect("failed to create cluster");
rt.block_on(async {
let cluster_path = fdb::default_config_path();
let cluster = Cluster::new(cluster_path)
.await
.expect("failed to create cluster");

let db = cluster
.create_database()
.wait()
.expect("failed to get database");
let db = cluster
.create_database()
.await
.expect("failed to get database");

let bench = Bench { db, opt };
bench.run();
let bench = Bench { db, opt };
bench.run().await;
});

network.stop().expect("failed to stop network");
handle.join().expect("failed to join fdb thread");
Expand Down
1 change: 1 addition & 0 deletions foundationdb-gen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "foundationdb-gen"
version = "0.1.0"
authors = ["Jihyun Yu <[email protected]>"]
edition = "2018"

description = """
Binding generation helper for FoundationDB.
Expand Down
2 changes: 1 addition & 1 deletion foundationdb-gen/src/bin/foundationdb-options-gen.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
extern crate foundationdb_gen;
use foundationdb_gen;

fn main() {
let code = foundationdb_gen::emit().expect("couldn't generate options.rs code!");
Expand Down
27 changes: 14 additions & 13 deletions foundationdb-gen/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
extern crate inflector;
extern crate xml;
use xml;
#[macro_use]
extern crate failure;

type Result<T> = std::result::Result<T, failure::Error>;

use inflector::cases::classcase;
use inflector::cases::screamingsnakecase;
use xml::attribute::OwnedAttribute;
use xml::reader::{EventReader, XmlEvent};
use inflector::cases::{classcase, screamingsnakecase};
use xml::{
attribute::OwnedAttribute,
reader::{EventReader, XmlEvent},
};

#[derive(Debug)]
struct FdbScope {
Expand Down Expand Up @@ -62,7 +62,7 @@ impl FdbScope {
for option in self.options.iter() {
let rs_name = match option.name.as_ref() {
"AppendIfFit" => "AppendIfFits",
s => s
s => s,
};

s += &format!("{}::{}", self.name, rs_name);
Expand Down Expand Up @@ -320,7 +320,7 @@ where
I: Iterator<Item = xml::reader::Result<XmlEvent>>,
{
let mut options = Vec::new();
while let Some(e) = parser.next() {
for e in parser {
let e = e?;
match e {
XmlEvent::StartElement {
Expand Down Expand Up @@ -352,10 +352,11 @@ const OPTIONS_DATA: &[u8] = include_bytes!("/usr/include/foundationdb/fdb.option
const OPTIONS_DATA: &[u8] = include_bytes!("/usr/local/include/foundationdb/fdb.options");

#[cfg(target_os = "windows")]
const OPTIONS_DATA: &[u8] = include_bytes!("C:/Program Files/foundationdb/include/foundationdb/fdb.options");
const OPTIONS_DATA: &[u8] =
include_bytes!("C:/Program Files/foundationdb/include/foundationdb/fdb.options");

pub fn emit() -> Result<String> {
let mut reader = OPTIONS_DATA.as_ref();
let mut reader = OPTIONS_DATA;
let parser = EventReader::new(&mut reader);
let mut iter = parser.into_iter();
let mut scopes = Vec::new();
Expand Down Expand Up @@ -387,12 +388,12 @@ pub fn emit() -> Result<String> {

let mut result = format!(
"{}\n{}\n{}\n\n",
"use std;", "use error;", "use foundationdb_sys as fdb;"
"use std;", "use crate::error;", "use foundationdb_sys as fdb;"
);

for scope in scopes.iter() {
result.push_str(&format!("{}", scope.gen_ty()));
result.push_str(&format!("{}", scope.gen_impl()));
result.push_str(&scope.gen_ty().to_string());
result.push_str(&scope.gen_impl().to_string());
}

Ok(result)
Expand Down
1 change: 1 addition & 0 deletions foundationdb-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "foundationdb-sys"
version = "0.2.0"
authors = ["Benjamin Fry <[email protected]>"]
edition = "2018"

description = """
Bindings to the C api for FoundationDB
Expand Down
5 changes: 1 addition & 4 deletions foundationdb-sys/build.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
extern crate bindgen;

use std::env;
use std::fs::File;
use std::io::prelude::*;
use std::path::PathBuf;
use std::{env, fs::File, io::prelude::*, path::PathBuf};

#[cfg(target_os = "linux")]
const INCLUDE_PATH: &str = "-I/usr/include/foundationdb/";
Expand Down
1 change: 1 addition & 0 deletions foundationdb-sys/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(clippy::all)]

include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
4 changes: 3 additions & 1 deletion foundationdb/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "foundationdb"
version = "0.3.0"
authors = ["Benjamin Fry <[email protected]>"]
edition = "2018"

description = """
High level client bindings for FoundationDB.
Expand Down Expand Up @@ -33,12 +34,13 @@ foundationdb-gen = { version = "0.1.0", path = "../foundationdb-gen" }
failure = "0.1"
failure_derive = "0.1"
foundationdb-sys = { version = "0.2.0", path = "../foundationdb-sys", default-features = false }
futures = "0.1"
futures-preview = { version = "0.3.0-alpha.17", features = ["compat", "nightly", "async-await"] }
lazy_static = "1.0"
byteorder = "1.2"
log = "0.4"
uuid = { version = "0.7", optional = true }
rand = "0.7.0"
tokio = "=0.2.0-alpha.2"

[dev-dependencies]
rand = "0.7"
5 changes: 1 addition & 4 deletions foundationdb/build.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
extern crate foundationdb_gen;

use std::env;
use std::fs::File;
use std::io::prelude::*;
use std::path::PathBuf;
use std::{env, fs::File, io::prelude::*, path::PathBuf};

fn main() {
let out_path = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR is undefined!"));
Expand Down
Loading