Skip to content

Commit 3dd450e

Browse files
committed
fix invalid transaction numbers when no transactions exists yet
1 parent 01e0c88 commit 3dd450e

File tree

4 files changed

+33
-20
lines changed

4 files changed

+33
-20
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "aora"
3-
version = "0.5.1"
3+
version = "0.6.0"
44
description = "Append-only random-accessed data persistence"
55
authors = ["Dr. Maxim Orlovsky <[email protected]>"]
66
keywords = ["database", "append-only-log"]

src/lib.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,12 +154,15 @@ where
154154
pub trait TransactionalMap<K> {
155155
/// Commits transaction, returning transaction number.
156156
///
157+
/// If the pending transaction is empty, a new transaction is not created and `None` is
158+
/// returned.
159+
///
157160
/// Transaction numbers are always sequential.
158161
///
159-
/// # Panics
162+
/// # Panic
160163
///
161-
/// Panics if another transaction is already taking place.
162-
fn commit_transaction(&mut self) -> u64;
164+
/// May panic due to internal errors.
165+
fn commit_transaction(&mut self) -> Option<u64>;
163166

164167
/// Aborts latest transaction.
165168
fn abort_transaction(&mut self);

src/providers/file/aumap.rs

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -197,12 +197,13 @@ where
197197
K: From<[u8; KEY_LEN]> + Into<[u8; KEY_LEN]>,
198198
V: From<[u8; VAL_LEN]> + Into<[u8; VAL_LEN]>,
199199
{
200-
fn commit_transaction(&mut self) -> u64 {
201-
if !self.pending.is_empty() {
202-
self.dirty.push(mem::take(&mut self.pending));
203-
self.save().expect("Cannot save log file");
200+
fn commit_transaction(&mut self) -> Option<u64> {
201+
if self.pending.is_empty() {
202+
return None;
204203
}
205-
self.transaction_count() - 1
204+
self.dirty.push(mem::take(&mut self.pending));
205+
self.save().expect("Cannot save the log file");
206+
Some(self.transaction_count() - 1)
206207
}
207208

208209
fn abort_transaction(&mut self) { self.pending.clear(); }
@@ -281,7 +282,7 @@ mod tests {
281282
#[test]
282283
fn abort() {
283284
let dir = tempfile::tempdir().unwrap();
284-
let mut db = Db::create_new(dir.path(), "happy_path").unwrap();
285+
let mut db = Db::create_new(dir.path(), "abort").unwrap();
285286

286287
normal_ops(&mut db);
287288
db.abort_transaction();
@@ -292,17 +293,26 @@ mod tests {
292293
assert_eq!(db.keys().count(), 0);
293294
assert_eq!(db.transaction_count(), 0);
294295

295-
let data = fs::read(dir.path().join("happy_path.log")).unwrap();
296+
let data = fs::read(dir.path().join("abort.log")).unwrap();
296297
assert_eq!(data, b"DUMBTEST\0\x01\0\0\0\0\0\0\0\0");
297298
}
298299

300+
#[test]
301+
fn empty_commit() {
302+
let dir = tempfile::tempdir().unwrap();
303+
let mut db = Db::create_new(dir.path(), "dir").unwrap();
304+
305+
// No pending transaction
306+
assert_eq!(db.commit_transaction(), None);
307+
}
308+
299309
#[test]
300310
fn commit() {
301311
let dir = tempfile::tempdir().unwrap();
302-
let mut db = Db::create_new(dir.path(), "happy_transactions").unwrap();
312+
let mut db = Db::create_new(dir.path(), "commit").unwrap();
303313

304314
normal_ops(&mut db);
305-
assert_eq!(db.commit_transaction(), 0);
315+
assert_eq!(db.commit_transaction(), Some(0));
306316

307317
// Check that commitment hasn't changed anything
308318
assert_eq!(db.get_expect(1.into()).0, 4);
@@ -315,12 +325,12 @@ mod tests {
315325

316326
// Insert another item
317327
db.insert_only(3.into(), 5.into());
318-
assert_eq!(db.commit_transaction(), 1);
328+
assert_eq!(db.commit_transaction(), Some(1));
319329
assert_eq!(db.transaction_count(), 2);
320330
assert_eq!(db.transaction_keys(0).collect::<HashSet<_>>(), set![0.into(), 1.into()]);
321331
assert_eq!(db.transaction_keys(1).collect::<HashSet<_>>(), set![3.into()]);
322332

323-
let db = Db::open(dir.path(), "happy_transactions").unwrap();
333+
let db = Db::open(dir.path(), "commit").unwrap();
324334

325335
// Check that commitment hasn't changed anything
326336
assert_eq!(db.get_expect(1.into()).0, 4);
@@ -340,10 +350,10 @@ mod tests {
340350

341351
db.insert_only(0.into(), 1.into());
342352
db.insert_only(0.into(), 1.into());
343-
assert_eq!(db.commit_transaction(), 0);
353+
assert_eq!(db.commit_transaction(), Some(0));
344354

345355
db.insert_only(0.into(), 1.into());
346-
assert_eq!(db.commit_transaction(), 0);
356+
assert_eq!(db.commit_transaction(), None);
347357

348358
assert_eq!(db.transaction_count(), 1);
349359
}
@@ -355,10 +365,10 @@ mod tests {
355365
let mut db = Db::create_new(dir.path(), "unique_keys").unwrap();
356366

357367
db.insert_only(0.into(), 1.into());
358-
assert_eq!(db.commit_transaction(), 0);
368+
assert_eq!(db.commit_transaction(), Some(0));
359369

360370
db.insert_only(0.into(), 2.into());
361-
assert_eq!(db.commit_transaction(), 1);
371+
assert_eq!(db.commit_transaction(), Some(1));
362372
}
363373

364374
#[test]

0 commit comments

Comments
 (0)