diff options
author | Determinant <[email protected]> | 2020-06-13 15:20:39 -0400 |
---|---|---|
committer | Determinant <[email protected]> | 2020-06-13 15:20:39 -0400 |
commit | d0e8ceeb250ce362d7d9bf2c6e5c297c716259cc (patch) | |
tree | 0a2d915d2c332c73e1fb1fa1eea2608936e26da9 | |
parent | f02152a1c3ff0123efd2076fd9190feb81107b8e (diff) |
...
-rw-r--r-- | .travis.yml | 15 | ||||
-rw-r--r-- | examples/demo1.rs | 8 | ||||
-rw-r--r-- | src/wal.rs | 32 | ||||
-rw-r--r-- | tests/common/mod.rs | 32 |
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); } @@ -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 |