summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml15
-rw-r--r--examples/demo1.rs8
-rw-r--r--src/wal.rs32
-rw-r--r--tests/common/mod.rs32
4 files changed, 59 insertions, 28 deletions
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..dd69f92
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,15 @@
+language: rust
+rust:
+ - stable
+ - beta
+ - nightly
+matrix:
+ allow_failures:
+ - rust: nightly
+ fast_finish: true
+cache: cargo
+before_install:
+ - sudo apt-get -y install libaio-dev
+script:
+ - cargo build --verbose --all
+ - cargo test --release --verbose --all
diff --git a/examples/demo1.rs b/examples/demo1.rs
index 47d1423..0c735f8 100644
--- a/examples/demo1.rs
+++ b/examples/demo1.rs
@@ -191,13 +191,9 @@ fn test(
records: Vec<String>,
wal: &mut WALWriter<WALStoreTest>,
) -> Vec<WALRingId> {
- let records: Vec<WALBytes> = records
- .into_iter()
- .map(|s| s.into_bytes().into_boxed_slice())
- .collect();
let mut res = Vec::new();
- for r in wal.grow(&records).into_iter() {
- let ring_id = futures::executor::block_on(r).unwrap();
+ for r in wal.grow(records).into_iter() {
+ let ring_id = futures::executor::block_on(r).unwrap().1;
println!("got ring id: {:?}", ring_id);
res.push(ring_id);
}
diff --git a/src/wal.rs b/src/wal.rs
index fe4f11d..c378e0a 100644
--- a/src/wal.rs
+++ b/src/wal.rs
@@ -61,6 +61,22 @@ impl PartialOrd for WALRingId {
}
}
+pub trait Record {
+ fn serialize(&self) -> WALBytes;
+}
+
+impl Record for WALBytes {
+ fn serialize(&self) -> WALBytes { self[..].into() }
+}
+
+impl Record for String {
+ fn serialize(&self) -> WALBytes { self.as_bytes().into() }
+}
+
+impl Record for str {
+ fn serialize(&self) -> WALBytes { self.as_bytes().into() }
+}
+
/// the state for a WAL writer
struct WALState {
/// the first file id of WAL
@@ -369,10 +385,10 @@ impl<F: WALStore> WALWriter<F> {
/// record is already logged. Then, after finalizing the changes encoded by that record to
/// the persistent storage, the caller can recycle the WAL files by invoking the given
/// `peel` with the given `WALRingId`s.
- pub fn grow<'a, T: AsRef<[WALBytes]>>(
+ pub fn grow<'a, R: Record + 'a>(
&'a mut self,
- records: T,
- ) -> Vec<impl Future<Output = Result<WALRingId, ()>> + 'a> {
+ records: Vec<R>,
+ ) -> Vec<impl Future<Output = Result<(R, WALRingId), ()>> + 'a> {
let mut res = Vec::new();
let mut writes = Vec::new();
let msize = self.msize as u32;
@@ -382,8 +398,9 @@ impl<F: WALStore> WALWriter<F> {
// the end of the unwritten data
let mut bbuff_cur = bbuff_start;
- for _rec in records.as_ref() {
- let mut rec = &_rec[..];
+ for rec in records.iter() {
+ let bytes = rec.serialize();
+ let mut rec = &bytes[..];
let mut rsize = rec.len() as u32;
let mut ring_start = None;
while rsize > 0 {
@@ -494,12 +511,13 @@ impl<F: WALStore> WALWriter<F> {
.collect();
let res = res
.into_iter()
- .map(|(ringid, blks)| {
+ .zip(records.into_iter())
+ .map(|((ringid, blks), rec)| {
future::try_join_all(
blks.into_iter().map(|idx| writes[idx].clone()),
)
.or_else(|_| future::ready(Err(())))
- .and_then(move |_| future::ready(Ok(ringid)))
+ .and_then(move |_| future::ready(Ok((rec, ringid))))
})
.collect();
res
diff --git a/tests/common/mod.rs b/tests/common/mod.rs
index d4645f9..b61233b 100644
--- a/tests/common/mod.rs
+++ b/tests/common/mod.rs
@@ -335,6 +335,10 @@ impl PaintStrokes {
}
}
+impl growthring::wal::Record for PaintStrokes {
+ fn serialize(&self) -> WALBytes { self.to_bytes() }
+}
+
#[test]
fn test_paint_strokes() {
let mut p = PaintStrokes::new();
@@ -548,22 +552,20 @@ impl PaintingSim {
)
})
.collect::<Vec<PaintStrokes>>();
- let payloads =
- pss.iter().map(|e| e.to_bytes()).collect::<Vec<WALBytes>>();
+ let pss_ = pss.clone();
// write ahead
- let rids = wal.grow(payloads);
- assert_eq!(pss.len(), rids.len());
- let rids = rids
+ let rids = wal.grow(pss);
+ assert_eq!(rids.len(), self.m);
+ let recs = rids
.into_iter()
- .map(|r| futures::executor::block_on(r))
- .collect::<Vec<_>>();
- // keep track of the operations
- // grow could fail
- for (ps, rid) in pss.iter().zip(rids.iter()) {
- ops.push(ps.clone());
- ringid_map.insert((*rid)?, ops.len() - 1);
- }
- let rids = rids.into_iter().map(|r| r.unwrap());
+ .zip(pss_.into_iter())
+ .map(|(r, ps)| -> Result<_, _> {
+ ops.push(ps);
+ let (rec, rid) = futures::executor::block_on(r)?;
+ ringid_map.insert(rid, ops.len() - 1);
+ Ok((rec, rid))
+ })
+ .collect::<Result<Vec<_>, ()>>()?;
// finish appending to WAL
/*
for rid in rids.iter() {
@@ -571,7 +573,7 @@ impl PaintingSim {
}
*/
// prepare data writes
- for (ps, rid) in pss.into_iter().zip(rids.into_iter()) {
+ for (ps, rid) in recs.into_iter() {
canvas.prepaint(&ps, &rid);
}
// run k ticks of the fine-grained scheduler