use crate::{Config, Persy, TransactionConfig};
use std::fs;
#[test]
pub fn test_recover_prepared_tx() {
Persy::create("./target/test_recover_prepared.persy").unwrap();
let id;
let val;
{
let persy = Persy::open("./target/test_recover_prepared.persy", Config::new()).unwrap();
let mut tx = persy.begin().expect("error on transaction begin");
tx.create_segment("def").expect("error on segment creation");
let fin = tx.prepare().expect("error on commit prepare");
fin.commit().expect("error on commit");
let mut tx = persy.begin().expect("error on transaction begin");
val = String::from("aaa").into_bytes();
id = tx.insert("def", &val).expect("error on insert value");
let prepared = tx.prepare().expect("error on commit prepare");
prepared.leak();
}
{
let persy = Persy::open("./target/test_recover_prepared.persy", Config::new()).unwrap();
assert_eq!(persy.read("def", &id).expect("error reading record"), Some(val));
}
fs::remove_file("./target/test_recover_prepared.persy").unwrap();
}
#[test]
pub fn test_double_recover_prepared_tx() {
Persy::create("./target/test_double_recover_prepared.persy").unwrap();
let id;
let id1;
let val;
let val1;
{
let persy = Persy::open("./target/test_double_recover_prepared.persy", Config::new()).unwrap();
let mut tx = persy.begin().expect("error on transaction begin");
tx.create_segment("def").expect("error on segment creation");
let fin = tx.prepare().expect("error on commit prepare");
fin.commit().expect("error on commit");
let mut tx = persy.begin().expect("error on transaction begin");
val = String::from("aaa").into_bytes();
id = tx.insert("def", &val).expect("error on insert value");
let prepared = tx.prepare().expect("error on commit prepare");
prepared.leak();
}
{
let persy = Persy::open("./target/test_double_recover_prepared.persy", Config::new()).unwrap();
assert_eq!(persy.read("def", &id).expect("error reading record"), Some(val.clone()));
let mut tx = persy.begin().expect("error on transaction begin");
val1 = String::from("bbbb").into_bytes();
id1 = tx.insert("def", &val1).expect("error on insert value");
let prepared = tx.prepare().expect("error on commit prepare");
prepared.leak();
}
{
let persy = Persy::open("./target/test_double_recover_prepared.persy", Config::new()).unwrap();
assert_eq!(persy.read("def", &id).expect("error reading record"), Some(val));
assert_eq!(persy.read("def", &id1).expect("error reading record",), Some(val1));
}
fs::remove_file("./target/test_double_recover_prepared.persy").unwrap();
}
#[test]
pub fn test_recover_tx_id() {
Persy::create("./target/test_recover_tx_id.persy").unwrap();
let id;
let id_pers;
let id_pers_update;
let val;
let val_1;
let tx_id = vec![10; 5];
{
val = String::from("aaa").into_bytes();
let persy = Persy::open("./target/test_recover_tx_id.persy", Config::new()).unwrap();
let mut tx = persy.begin().expect("error on transaction begin");
tx.create_segment("def").expect("error on segment creation");
id_pers = tx.insert("def", &val).expect("error on insert value");
id_pers_update = tx.insert("def", &val).expect("error on insert value");
let fin = tx.prepare().expect("error on commit prepare");
fin.commit().expect("error on commit");
let mut tx = persy
.begin_with(TransactionConfig::new().set_transaction_id(tx_id.clone()))
.expect("error on transaction begin");
id = tx.insert("def", &val).expect("error on insert value");
tx.delete("def", &id_pers).expect("delete record works");
val_1 = String::from("bbb").into_bytes();
tx.update("def", &id_pers_update, &val_1).expect("delete record works");
let prepared = tx.prepare().expect("error on commit prepare");
prepared.leak();
}
{
let persy = Persy::open_with_recover("./target/test_recover_tx_id.persy", Config::new(), |t_id| {
assert_eq!(&tx_id, t_id);
true
})
.unwrap();
assert_eq!(persy.read("def", &id).expect("error reading record"), Some(val));
assert_eq!(persy.read("def", &id_pers).expect("error reading record"), None);
assert_eq!(
persy.read("def", &id_pers_update).expect("error reading record"),
Some(val_1)
);
}
fs::remove_file("./target/test_recover_tx_id.persy").unwrap();
}
#[test]
pub fn test_recover_tx_choice() {
Persy::create("./target/test_recover_tx_choice.persy").unwrap();
let id;
let id_1;
let id_pers;
let id_pers_update;
let val;
let val_1;
let tx_id = vec![10; 5];
let tx_id_1 = vec![10; 10];
{
val = String::from("aaa").into_bytes();
let persy = Persy::open("./target/test_recover_tx_choice.persy", Config::new()).unwrap();
let mut tx = persy.begin().expect("error on transaction begin");
tx.create_segment("def").expect("error on segment creation");
id_pers = tx.insert("def", &val).expect("error on insert value");
id_pers_update = tx.insert("def", &val).expect("error on insert value");
let fin = tx.prepare().expect("error on commit prepare");
fin.commit().expect("error on commit");
let mut tx = persy
.begin_with(TransactionConfig::new().set_transaction_id(tx_id.clone()))
.expect("error on transaction begin");
id = tx.insert("def", &val).expect("error on insert value");
let mut prepared = tx.prepare().expect("error on commit prepare");
let _replaced = prepared.finalize.take();
let mut tx = persy
.begin_with(TransactionConfig::new().set_transaction_id(tx_id_1.clone()))
.expect("error on transaction begin");
id_1 = tx.insert("def", &val).expect("error on insert value");
tx.delete("def", &id_pers).expect("delete record works");
val_1 = String::from("bbb").into_bytes();
tx.update("def", &id_pers_update, &val_1).expect("delete record works");
let prepared = tx.prepare().expect("error on commit prepare");
prepared.leak();
}
{
let mut recover = Persy::recover("./target/test_recover_tx_choice.persy", Config::new()).unwrap();
assert!(recover.list_transactions().len() >= 2);
recover.rollback(tx_id_1);
recover.commit(tx_id);
let persy = recover.finalize().expect("recover correctly");
assert_eq!(persy.read("def", &id).expect("error reading record"), Some(val.clone()));
assert_eq!(persy.read("def", &id_1).expect("error reading record"), None);
assert_eq!(
persy.read("def", &id_pers).expect("error reading record"),
Some(val.clone())
);
assert_eq!(
persy.read("def", &id_pers_update).expect("error reading record"),
Some(val)
);
}
fs::remove_file("./target/test_recover_tx_choice.persy").unwrap();
}
#[test]
pub fn test_recover_prepared_and_cleaned_tx() {
Persy::create("./target/test_recover_prepared_and_cleaned.persy").unwrap();
{
let persy = Persy::open("./target/test_recover_prepared_and_cleaned.persy", Config::new()).unwrap();
let mut tx = persy.begin().expect("error on transaction begin");
tx.create_segment("def").expect("error on segment creation");
let fin = tx.prepare().expect("error on commit prepare");
fin.commit().expect("error on commit");
let mut tx = persy.begin().expect("error on transaction begin");
for i in 0..100 {
let val = format!("aaa{}", i).into_bytes();
tx.insert("def", &val).expect("error on insert value");
}
let mut tx2 = persy.begin().expect("error on transaction begin");
for i in 100..150 {
let val = format!("aaa{}", i).into_bytes();
tx2.insert("def", &val).expect("error on insert value");
}
for i in 150..250 {
let val = format!("aaa{}", i).into_bytes();
tx.insert("def", &val).expect("error on insert value");
}
let prepared = tx.prepare().expect("error on commit prepare");
prepared.commit().unwrap();
for i in 250..300 {
let val = format!("aaa{}", i).into_bytes();
tx2.insert("def", &val).expect("error on insert value");
}
let prepared = tx2.prepare().expect("error on commit prepare");
prepared.leak();
}
{
let persy = Persy::open("./target/test_recover_prepared_and_cleaned.persy", Config::new()).unwrap();
let mut count = 0;
let mut set_exp = std::collections::BTreeSet::new();
let mut set_is = std::collections::BTreeSet::new();
for (_, rec) in persy.scan("def").expect("error reading record") {
let val = format!("aaa{}", count);
set_exp.insert(val);
set_is.insert(String::from_utf8(rec).unwrap());
count += 1;
}
assert_eq!(set_exp, set_is);
assert_eq!(persy.scan("def").expect("error reading record").count(), 300);
}
fs::remove_file("./target/test_recover_prepared_and_cleaned.persy").unwrap();
}
#[test]
pub fn test_double_recover_prepared_and_cleaned_tx() {
Persy::create("./target/test_double_recover_prepared_and_cleaned.persy").unwrap();
{
let persy = Persy::open("./target/test_double_recover_prepared_and_cleaned.persy", Config::new()).unwrap();
let mut tx = persy.begin().expect("error on transaction begin");
tx.create_segment("def").expect("error on segment creation");
let fin = tx.prepare().expect("error on commit prepare");
fin.commit().expect("error on commit");
let mut tx = persy.begin().expect("error on transaction begin");
for i in 0..100 {
let val = format!("aaa{}", i).into_bytes();
tx.insert("def", &val).expect("error on insert value");
}
let mut tx2 = persy.begin().expect("error on transaction begin");
for i in 100..150 {
let val = format!("aaa{}", i).into_bytes();
tx2.insert("def", &val).expect("error on insert value");
}
for i in 150..250 {
let val = format!("aaa{}", i).into_bytes();
tx.insert("def", &val).expect("error on insert value");
}
let prepared = tx.prepare().expect("error on commit prepare");
prepared.commit().unwrap();
for i in 250..300 {
let val = format!("aaa{}", i).into_bytes();
tx2.insert("def", &val).expect("error on insert value");
}
let prepared = tx2.prepare().expect("error on commit prepare");
prepared.leak();
}
{
let persy = Persy::open("./target/test_double_recover_prepared_and_cleaned.persy", Config::new()).unwrap();
let mut set_exp = std::collections::BTreeSet::new();
for count in 0..300 {
set_exp.insert(format!("aaa{}", count));
}
let mut set_is = std::collections::BTreeSet::new();
for (_, rec) in persy.scan("def").expect("error reading record") {
set_is.insert(String::from_utf8(rec).unwrap());
}
assert_eq!(
set_exp
.difference(&set_is)
.map(|x| x.to_owned())
.collect::<Vec<String>>(),
Vec::<String>::new()
);
assert_eq!(persy.scan("def").expect("error reading record").count(), 300);
let mut tx = persy.begin().expect("error on transaction begin");
for i in 300..500 {
let val = format!("aaa{}", i).into_bytes();
tx.insert("def", &val).expect("error on insert value");
}
let prepared = tx.prepare().expect("error on commit prepare");
prepared.leak();
}
{
let persy = Persy::open("./target/test_double_recover_prepared_and_cleaned.persy", Config::new()).unwrap();
let mut set_exp = std::collections::BTreeSet::new();
for count in 0..500 {
set_exp.insert(format!("aaa{}", count));
}
let mut set_is = std::collections::BTreeSet::new();
for (_, rec) in persy.scan("def").expect("error reading record") {
set_is.insert(String::from_utf8(rec).unwrap());
}
assert_eq!(
set_exp
.difference(&set_is)
.map(|x| x.to_owned())
.collect::<Vec<String>>(),
Vec::<String>::new()
);
assert_eq!(set_exp, set_is);
assert_eq!(persy.scan("def").expect("error reading record").count(), 500);
}
fs::remove_file("./target/test_double_recover_prepared_and_cleaned.persy").unwrap();
}
#[test]
pub fn test_double_recover_prepared_and_cleaned_forget() {
Persy::create("./target/test_double_recover_prepared_and_cleaned_forget.persy").unwrap();
{
let persy = Persy::open(
"./target/test_double_recover_prepared_and_cleaned_forget.persy",
Config::new(),
)
.unwrap();
let mut tx = persy
.begin_with(TransactionConfig::new())
.expect("error on transaction begin");
tx.create_segment("def").expect("error on segment creation");
let fin = tx.prepare().expect("error on commit prepare");
fin.commit().expect("error on commit");
let mut tx = persy
.begin_with(TransactionConfig::new())
.expect("error on transaction begin");
for i in 0..100 {
let val = format!("aaa{}", i).into_bytes();
tx.insert("def", &val).expect("error on insert value");
}
let mut tx2 = persy
.begin_with(TransactionConfig::new())
.expect("error on transaction begin");
for i in 100..150 {
let val = format!("aaa{}", i).into_bytes();
tx2.insert("def", &val).expect("error on insert value");
}
for i in 150..250 {
let val = format!("aaa{}", i).into_bytes();
tx.insert("def", &val).expect("error on insert value");
}
let prepared = tx.prepare().expect("error on commit prepare");
prepared.commit().unwrap();
for i in 250..300 {
let val = format!("aaa{}", i).into_bytes();
tx2.insert("def", &val).expect("error on insert value");
}
let prepared = tx2.prepare().expect("error on commit prepare");
prepared.commit().unwrap();
persy.free_file_lock().unwrap();
std::mem::forget(persy);
}
{
let persy = Persy::open(
"./target/test_double_recover_prepared_and_cleaned_forget.persy",
Config::new(),
)
.unwrap();
let mut set_exp = std::collections::BTreeSet::new();
for count in 0..300 {
set_exp.insert(format!("aaa{}", count));
}
let mut set_is = std::collections::BTreeSet::new();
for (_, rec) in persy.scan("def").expect("error reading record") {
set_is.insert(String::from_utf8(rec).unwrap());
}
assert_eq!(
set_exp
.difference(&set_is)
.map(|x| x.to_owned())
.collect::<Vec<String>>(),
Vec::<String>::new()
);
assert_eq!(persy.scan("def").expect("error reading record").count(), 300);
let mut tx = persy
.begin_with(TransactionConfig::new())
.expect("error on transaction begin");
for i in 300..500 {
let val = format!("aaa{}", i).into_bytes();
tx.insert("def", &val).expect("error on insert value");
}
let prepared = tx.prepare().expect("error on commit prepare");
prepared.commit().unwrap();
persy.free_file_lock().unwrap();
std::mem::forget(persy);
}
{
let persy = Persy::open(
"./target/test_double_recover_prepared_and_cleaned_forget.persy",
Config::new(),
)
.unwrap();
let mut set_exp = std::collections::BTreeSet::new();
for count in 0..500 {
set_exp.insert(format!("aaa{}", count));
}
let mut set_is = std::collections::BTreeSet::new();
for (_, rec) in persy.scan("def").expect("error reading record") {
set_is.insert(String::from_utf8(rec).unwrap());
}
assert_eq!(
set_exp
.difference(&set_is)
.map(|x| x.to_owned())
.collect::<Vec<String>>(),
Vec::<String>::new()
);
assert_eq!(set_exp, set_is);
assert_eq!(persy.scan("def").expect("error reading record").count(), 500);
}
fs::remove_file("./target/test_double_recover_prepared_and_cleaned_forget.persy").unwrap();
}
#[cfg(feature = "background_ops")]
mod tests_background {
use crate::{Config, Persy, TransactionConfig};
use std::fs;
#[test]
pub fn test_recover_prepared_tx() {
Persy::create("./target/test_recover_prepared_bg.persy").unwrap();
let id;
let val;
{
let persy = Persy::open("./target/test_recover_prepared_bg.persy", Config::new()).unwrap();
let mut tx = persy
.begin_with(TransactionConfig::new().set_background_sync(true))
.expect("error on transaction begin");
tx.create_segment("def").expect("error on segment creation");
let fin = tx.prepare().expect("error on commit prepare");
fin.commit().expect("error on commit");
let mut tx = persy
.begin_with(TransactionConfig::new().set_background_sync(true))
.expect("error on transaction begin");
val = String::from("aaa").into_bytes();
id = tx.insert("def", &val).expect("error on insert value");
let prepared = tx.prepare().expect("error on commit prepare");
prepared.leak();
}
{
let persy = Persy::open("./target/test_recover_prepared_bg.persy", Config::new()).unwrap();
assert_eq!(persy.read("def", &id).expect("error reading record"), Some(val));
}
fs::remove_file("./target/test_recover_prepared_bg.persy").unwrap();
}
#[test]
pub fn test_double_recover_prepared_tx() {
Persy::create("./target/test_double_recover_prepared_bg.persy").unwrap();
let id;
let id1;
let val;
let val1;
{
let persy = Persy::open("./target/test_double_recover_prepared_bg.persy", Config::new()).unwrap();
let mut tx = persy
.begin_with(TransactionConfig::new().set_background_sync(true))
.expect("error on transaction begin");
tx.create_segment("def").expect("error on segment creation");
let fin = tx.prepare().expect("error on commit prepare");
fin.commit().expect("error on commit");
let mut tx = persy
.begin_with(TransactionConfig::new().set_background_sync(true))
.expect("error on transaction begin");
val = String::from("aaa").into_bytes();
id = tx.insert("def", &val).expect("error on insert value");
let prepared = tx.prepare().expect("error on commit prepare");
prepared.leak();
}
{
let persy = Persy::open("./target/test_double_recover_prepared_bg.persy", Config::new()).unwrap();
assert_eq!(persy.read("def", &id).expect("error reading record"), Some(val.clone()));
let mut tx = persy
.begin_with(TransactionConfig::new().set_background_sync(true))
.expect("error on transaction begin");
val1 = String::from("bbbb").into_bytes();
id1 = tx.insert("def", &val1).expect("error on insert value");
let prepared = tx.prepare().expect("error on commit prepare");
prepared.leak();
}
{
let persy = Persy::open("./target/test_double_recover_prepared_bg.persy", Config::new()).unwrap();
assert_eq!(persy.read("def", &id).expect("error reading record"), Some(val));
assert_eq!(persy.read("def", &id1).expect("error reading record",), Some(val1));
}
fs::remove_file("./target/test_double_recover_prepared_bg.persy").unwrap();
}
#[test]
pub fn test_recover_tx_id() {
Persy::create("./target/test_recover_tx_id_bg.persy").unwrap();
let id;
let id_pers;
let id_pers_update;
let val;
let val_1;
let tx_id = vec![10; 5];
{
val = String::from("aaa").into_bytes();
let persy = Persy::open("./target/test_recover_tx_id_bg.persy", Config::new()).unwrap();
let mut tx = persy
.begin_with(TransactionConfig::new().set_background_sync(true))
.expect("error on transaction begin");
tx.create_segment("def").expect("error on segment creation");
id_pers = tx.insert("def", &val).expect("error on insert value");
id_pers_update = tx.insert("def", &val).expect("error on insert value");
let fin = tx.prepare().expect("error on commit prepare");
fin.commit().expect("error on commit");
let mut tx = persy
.begin_with(
TransactionConfig::new()
.set_background_sync(true)
.set_transaction_id(tx_id.clone()),
)
.expect("error on transaction begin");
id = tx.insert("def", &val).expect("error on insert value");
tx.delete("def", &id_pers).expect("delete record works");
val_1 = String::from("bbb").into_bytes();
tx.update("def", &id_pers_update, &val_1).expect("delete record works");
let prepared = tx.prepare().expect("error on commit prepare");
prepared.leak();
}
{
let persy = Persy::open_with_recover("./target/test_recover_tx_id_bg.persy", Config::new(), |t_id| {
assert_eq!(&tx_id, t_id);
true
})
.unwrap();
assert_eq!(persy.read("def", &id).expect("error reading record"), Some(val));
assert_eq!(persy.read("def", &id_pers).expect("error reading record"), None);
assert_eq!(
persy.read("def", &id_pers_update).expect("error reading record"),
Some(val_1)
);
}
fs::remove_file("./target/test_recover_tx_id_bg.persy").unwrap();
}
#[test]
pub fn test_recover_tx_choice() {
Persy::create("./target/test_recover_tx_choice_bg.persy").unwrap();
let id;
let id_1;
let id_pers;
let id_pers_update;
let val;
let val_1;
let tx_id = vec![10; 5];
let tx_id_1 = vec![10; 10];
{
val = String::from("aaa").into_bytes();
let persy = Persy::open("./target/test_recover_tx_choice_bg.persy", Config::new()).unwrap();
let mut tx = persy
.begin_with(TransactionConfig::new().set_background_sync(true))
.expect("error on transaction begin");
tx.create_segment("def").expect("error on segment creation");
id_pers = tx.insert("def", &val).expect("error on insert value");
id_pers_update = tx.insert("def", &val).expect("error on insert value");
let fin = tx.prepare().expect("error on commit prepare");
fin.commit().expect("error on commit");
let mut tx = persy
.begin_with(
TransactionConfig::new()
.set_background_sync(true)
.set_transaction_id(tx_id.clone()),
)
.expect("error on transaction begin");
id = tx.insert("def", &val).expect("error on insert value");
let prepared = tx.prepare().expect("error on commit prepare");
prepared.leak();
let mut tx = persy
.begin_with(
TransactionConfig::new()
.set_background_sync(true)
.set_transaction_id(tx_id_1.clone()),
)
.expect("error on transaction begin");
id_1 = tx.insert("def", &val).expect("error on insert value");
tx.delete("def", &id_pers).expect("delete record works");
val_1 = String::from("bbb").into_bytes();
tx.update("def", &id_pers_update, &val_1).expect("delete record works");
let prepared = tx.prepare().expect("error on commit prepare");
prepared.leak();
}
{
let mut recover = Persy::recover("./target/test_recover_tx_choice_bg.persy", Config::new()).unwrap();
assert!(recover.list_transactions().len() >= 2);
recover.rollback(tx_id_1);
recover.commit(tx_id);
let persy = recover.finalize().expect("recover correctly");
assert_eq!(persy.read("def", &id).expect("error reading record"), Some(val.clone()));
assert_eq!(persy.read("def", &id_1).expect("error reading record"), None);
assert_eq!(
persy.read("def", &id_pers).expect("error reading record"),
Some(val.clone())
);
assert_eq!(
persy.read("def", &id_pers_update).expect("error reading record"),
Some(val)
);
}
fs::remove_file("./target/test_recover_tx_choice_bg.persy").unwrap();
}
#[test]
pub fn test_recover_prepared_and_cleaned_tx() {
Persy::create("./target/test_recover_prepared_and_cleaned_bg.persy").unwrap();
{
let persy = Persy::open("./target/test_recover_prepared_and_cleaned_bg.persy", Config::new()).unwrap();
let mut tx = persy
.begin_with(TransactionConfig::new().set_background_sync(true))
.expect("error on transaction begin");
tx.create_segment("def").expect("error on segment creation");
let fin = tx.prepare().expect("error on commit prepare");
fin.commit().expect("error on commit");
let mut tx = persy
.begin_with(TransactionConfig::new().set_background_sync(true))
.expect("error on transaction begin");
for i in 0..100 {
let val = format!("aaa{}", i).into_bytes();
tx.insert("def", &val).expect("error on insert value");
}
let mut tx2 = persy
.begin_with(TransactionConfig::new().set_background_sync(true))
.expect("error on transaction begin");
for i in 100..150 {
let val = format!("aaa{}", i).into_bytes();
tx2.insert("def", &val).expect("error on insert value");
}
for i in 150..250 {
let val = format!("aaa{}", i).into_bytes();
tx.insert("def", &val).expect("error on insert value");
}
let prepared = tx.prepare().expect("error on commit prepare");
prepared.commit().unwrap();
for i in 250..300 {
let val = format!("aaa{}", i).into_bytes();
tx2.insert("def", &val).expect("error on insert value");
}
let prepared = tx2.prepare().expect("error on commit prepare");
prepared.leak();
}
{
let persy = Persy::open("./target/test_recover_prepared_and_cleaned_bg.persy", Config::new()).unwrap();
let mut count = 0;
let mut set_exp = std::collections::BTreeSet::new();
let mut set_is = std::collections::BTreeSet::new();
for (_, rec) in persy.scan("def").expect("error reading record") {
let val = format!("aaa{}", count);
set_exp.insert(val);
set_is.insert(String::from_utf8(rec).unwrap());
count += 1;
}
assert_eq!(set_exp, set_is);
assert_eq!(persy.scan("def").expect("error reading record").count(), 300);
}
fs::remove_file("./target/test_recover_prepared_and_cleaned_bg.persy").unwrap();
}
#[test]
pub fn test_double_recover_prepared_and_cleaned_tx() {
Persy::create("./target/test_double_recover_prepared_and_cleaned_bg.persy").unwrap();
{
let persy = Persy::open(
"./target/test_double_recover_prepared_and_cleaned_bg.persy",
Config::new(),
)
.unwrap();
let mut tx = persy
.begin_with(TransactionConfig::new().set_background_sync(true))
.expect("error on transaction begin");
tx.create_segment("def").expect("error on segment creation");
let fin = tx.prepare().expect("error on commit prepare");
fin.commit().expect("error on commit");
let mut tx = persy
.begin_with(TransactionConfig::new().set_background_sync(true))
.expect("error on transaction begin");
for i in 0..100 {
let val = format!("aaa{}", i).into_bytes();
tx.insert("def", &val).expect("error on insert value");
}
let mut tx2 = persy
.begin_with(TransactionConfig::new().set_background_sync(true))
.expect("error on transaction begin");
for i in 100..150 {
let val = format!("aaa{}", i).into_bytes();
tx2.insert("def", &val).expect("error on insert value");
}
for i in 150..250 {
let val = format!("aaa{}", i).into_bytes();
tx.insert("def", &val).expect("error on insert value");
}
let prepared = tx.prepare().expect("error on commit prepare");
prepared.commit().unwrap();
for i in 250..300 {
let val = format!("aaa{}", i).into_bytes();
tx2.insert("def", &val).expect("error on insert value");
}
let prepared = tx2.prepare().expect("error on commit prepare");
prepared.leak();
}
{
let persy = Persy::open(
"./target/test_double_recover_prepared_and_cleaned_bg.persy",
Config::new(),
)
.unwrap();
let mut set_exp = std::collections::BTreeSet::new();
for count in 0..300 {
set_exp.insert(format!("aaa{}", count));
}
let mut set_is = std::collections::BTreeSet::new();
for (_, rec) in persy.scan("def").expect("error reading record") {
set_is.insert(String::from_utf8(rec).unwrap());
}
assert_eq!(
set_exp
.difference(&set_is)
.map(|x| x.to_owned())
.collect::<Vec<String>>(),
Vec::<String>::new()
);
assert_eq!(persy.scan("def").expect("error reading record").count(), 300);
let mut tx = persy
.begin_with(TransactionConfig::new().set_background_sync(true))
.expect("error on transaction begin");
for i in 300..500 {
let val = format!("aaa{}", i).into_bytes();
tx.insert("def", &val).expect("error on insert value");
}
let prepared = tx.prepare().expect("error on commit prepare");
prepared.leak();
}
{
let persy = Persy::open(
"./target/test_double_recover_prepared_and_cleaned_bg.persy",
Config::new(),
)
.unwrap();
let mut set_exp = std::collections::BTreeSet::new();
for count in 0..500 {
set_exp.insert(format!("aaa{}", count));
}
let mut set_is = std::collections::BTreeSet::new();
for (_, rec) in persy.scan("def").expect("error reading record") {
set_is.insert(String::from_utf8(rec).unwrap());
}
assert_eq!(
set_exp
.difference(&set_is)
.map(|x| x.to_owned())
.collect::<Vec<String>>(),
Vec::<String>::new()
);
assert_eq!(set_exp, set_is);
assert_eq!(persy.scan("def").expect("error reading record").count(), 500);
}
fs::remove_file("./target/test_double_recover_prepared_and_cleaned_bg.persy").unwrap();
}
}