mirror of
https://github.com/hinto-janai/cuprate.git
synced 2024-12-22 19:49:33 +00:00
update call-sites
This commit is contained in:
parent
dd2f7e083d
commit
4f12612abc
8 changed files with 83 additions and 47 deletions
|
@ -28,10 +28,10 @@ pub fn update_alt_chain_info(
|
||||||
Err(e) => return Err(e),
|
Err(e) => return Err(e),
|
||||||
};
|
};
|
||||||
|
|
||||||
// try update the info if one exists for this chain.
|
tables
|
||||||
let update = tables
|
|
||||||
.alt_chain_infos_mut()
|
.alt_chain_infos_mut()
|
||||||
.update(&alt_block_height.chain_id, |mut info| {
|
.entry(&alt_block_height.chain_id)?
|
||||||
|
.and_update(|info| {
|
||||||
if info.chain_height < alt_block_height.height + 1 {
|
if info.chain_height < alt_block_height.height + 1 {
|
||||||
// If the chain height is increasing we only need to update the chain height.
|
// If the chain height is increasing we only need to update the chain height.
|
||||||
info.chain_height = alt_block_height.height + 1;
|
info.chain_height = alt_block_height.height + 1;
|
||||||
|
@ -43,25 +43,12 @@ pub fn update_alt_chain_info(
|
||||||
}
|
}
|
||||||
|
|
||||||
info.chain_height = alt_block_height.height + 1;
|
info.chain_height = alt_block_height.height + 1;
|
||||||
Some(info)
|
})?
|
||||||
});
|
.or_insert_with(|| AltChainInfo {
|
||||||
|
|
||||||
match update {
|
|
||||||
Ok(()) => return Ok(()),
|
|
||||||
Err(RuntimeError::KeyNotFound) => (),
|
|
||||||
Err(e) => return Err(e),
|
|
||||||
}
|
|
||||||
|
|
||||||
// If one doesn't already exist add it.
|
|
||||||
|
|
||||||
tables.alt_chain_infos_mut().put(
|
|
||||||
&alt_block_height.chain_id,
|
|
||||||
&AltChainInfo {
|
|
||||||
parent_chain: parent_chain.into(),
|
parent_chain: parent_chain.into(),
|
||||||
common_ancestor_height: alt_block_height.height.checked_sub(1).unwrap(),
|
common_ancestor_height: alt_block_height.height.checked_sub(1).unwrap(),
|
||||||
chain_height: alt_block_height.height + 1,
|
chain_height: alt_block_height.height + 1,
|
||||||
},
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the height history of an alt-chain in reverse chronological order.
|
/// Get the height history of an alt-chain in reverse chronological order.
|
||||||
|
|
|
@ -67,14 +67,9 @@ pub fn remove_output(
|
||||||
// `btree_map::Entry`-like API, fix `trait DatabaseRw`.
|
// `btree_map::Entry`-like API, fix `trait DatabaseRw`.
|
||||||
tables
|
tables
|
||||||
.num_outputs_mut()
|
.num_outputs_mut()
|
||||||
.update(&pre_rct_output_id.amount, |num_outputs| {
|
.entry(&pre_rct_output_id.amount)?
|
||||||
// INVARIANT: Should never be 0.
|
.and_remove(|num_outputs| *num_outputs == 1)?
|
||||||
if num_outputs == 1 {
|
.and_update(|num_outputs| *num_outputs -= 1)?;
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(num_outputs - 1)
|
|
||||||
}
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// Delete the output data itself.
|
// Delete the output data itself.
|
||||||
tables.outputs_mut().delete(pre_rct_output_id)
|
tables.outputs_mut().delete(pre_rct_output_id)
|
||||||
|
|
|
@ -189,6 +189,20 @@ impl<T: Table> DatabaseRw<T> for HeedTableRw<'_, '_, T> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn take(&mut self, key: &T::Key) -> DbResult<T::Value> {
|
||||||
|
// LMDB/heed does not return the value on deletion.
|
||||||
|
// So, fetch it first - then delete.
|
||||||
|
let value = get::<T>(&self.db, &self.tx_rw.borrow(), key)?;
|
||||||
|
match self.db.delete(&mut self.tx_rw.borrow_mut(), key) {
|
||||||
|
Ok(true) => Ok(value),
|
||||||
|
Err(e) => Err(e.into()),
|
||||||
|
// We just `get()`'ed the value - it is
|
||||||
|
// incorrect for it to suddenly not exist.
|
||||||
|
Ok(false) => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn pop_first(&mut self) -> DbResult<(T::Key, T::Value)> {
|
fn pop_first(&mut self) -> DbResult<(T::Key, T::Value)> {
|
||||||
let tx_rw = &mut self.tx_rw.borrow_mut();
|
let tx_rw = &mut self.tx_rw.borrow_mut();
|
||||||
|
|
|
@ -293,11 +293,11 @@ fn db_read_write() {
|
||||||
assert_value(value);
|
assert_value(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assert `Entry` returns the correct value.
|
// Assert `take()` works.
|
||||||
{
|
{
|
||||||
let mut key = KEY;
|
let mut key = KEY;
|
||||||
key += 1;
|
key += 1;
|
||||||
let value = table.entry(&key).unwrap().and_remove().unwrap();
|
let value = table.take(&key).unwrap();
|
||||||
assert_eq!(value, VALUE);
|
assert_eq!(value, VALUE);
|
||||||
|
|
||||||
let get = table.get(&KEY);
|
let get = table.get(&KEY);
|
||||||
|
|
|
@ -171,6 +171,14 @@ pub trait DatabaseRw<T: Table>: DatabaseRo<T> + Sized {
|
||||||
/// This will never [`RuntimeError::KeyExists`].
|
/// This will never [`RuntimeError::KeyExists`].
|
||||||
fn delete(&mut self, key: &T::Key) -> DbResult<()>;
|
fn delete(&mut self, key: &T::Key) -> DbResult<()>;
|
||||||
|
|
||||||
|
/// Delete and return a key-value pair in the database.
|
||||||
|
///
|
||||||
|
/// This is the same as [`DatabaseRw::delete`], however,
|
||||||
|
/// it will serialize the `T::Value` and return it.
|
||||||
|
///
|
||||||
|
#[doc = doc_database!()]
|
||||||
|
fn take(&mut self, key: &T::Key) -> DbResult<T::Value>;
|
||||||
|
|
||||||
/// Removes and returns the first `(key, value)` pair in the database.
|
/// Removes and returns the first `(key, value)` pair in the database.
|
||||||
///
|
///
|
||||||
#[doc = doc_database!()]
|
#[doc = doc_database!()]
|
||||||
|
|
|
@ -29,6 +29,16 @@ where
|
||||||
T: Table,
|
T: Table,
|
||||||
D: DatabaseRw<T>,
|
D: DatabaseRw<T>,
|
||||||
{
|
{
|
||||||
|
/// TODO
|
||||||
|
pub const fn is_occupied(&self) -> bool {
|
||||||
|
matches!(self, Self::Occupied(_))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TODO
|
||||||
|
pub const fn is_vacant(&self) -> bool {
|
||||||
|
matches!(self, Self::Vacant(_))
|
||||||
|
}
|
||||||
|
|
||||||
/// Ensures a value is in the entry by inserting the `default` if empty.
|
/// Ensures a value is in the entry by inserting the `default` if empty.
|
||||||
///
|
///
|
||||||
/// This only inserts if the entry is [`VacantEntry`].
|
/// This only inserts if the entry is [`VacantEntry`].
|
||||||
|
@ -44,24 +54,24 @@ where
|
||||||
/// This only inserts if the entry is [`VacantEntry`].
|
/// This only inserts if the entry is [`VacantEntry`].
|
||||||
pub fn or_insert_with<F>(self, default: F) -> DbResult<()>
|
pub fn or_insert_with<F>(self, default: F) -> DbResult<()>
|
||||||
where
|
where
|
||||||
F: FnOnce() -> &'a T::Value,
|
F: FnOnce() -> T::Value,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Self::Occupied(_) => Ok(()),
|
Self::Occupied(_) => Ok(()),
|
||||||
Self::Vacant(entry) => entry.insert(default()),
|
Self::Vacant(entry) => entry.insert(&default()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Same as [`Self::or_insert_with`] but gives access to the key.
|
/// Same as [`Self::or_insert_with`] but gives access to the key.
|
||||||
pub fn or_insert_with_key<F>(self, default: F) -> DbResult<()>
|
pub fn or_insert_with_key<F>(self, default: F) -> DbResult<()>
|
||||||
where
|
where
|
||||||
F: FnOnce(&'a T::Key) -> &'a T::Value,
|
F: FnOnce(&'a T::Key) -> T::Value,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Self::Occupied(_) => Ok(()),
|
Self::Occupied(_) => Ok(()),
|
||||||
Self::Vacant(entry) => {
|
Self::Vacant(entry) => {
|
||||||
let key = entry.key;
|
let key = entry.key;
|
||||||
entry.insert(default(key))
|
entry.insert(&default(key))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,16 +106,24 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`OccupiedEntry::remove`] the value if it already exists, else do nothing.
|
/// Conditionally [`OccupiedEntry::remove`] the value if it already exists.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// This functions does nothing if the entry is [`VacantEntry`].
|
||||||
/// This returns [`RuntimeError::KeyNotFound`] if the entry is [`VacantEntry`].
|
pub fn and_remove<F>(self, f: F) -> DbResult<Self>
|
||||||
pub fn and_remove(self) -> DbResult<T::Value> {
|
where
|
||||||
match self {
|
F: FnOnce(&T::Value) -> bool,
|
||||||
Self::Occupied(entry) => entry.remove(),
|
{
|
||||||
Self::Vacant(_) => Err(RuntimeError::KeyNotFound),
|
Ok(match self {
|
||||||
|
Self::Occupied(entry) => {
|
||||||
|
if f(&entry.value) {
|
||||||
|
entry.remove()?.0
|
||||||
|
} else {
|
||||||
|
Self::Occupied(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Self::Vacant(entry) => Self::Vacant(entry),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// [`OccupiedEntry::update`] the value if it already exists
|
/// [`OccupiedEntry::update`] the value if it already exists
|
||||||
///
|
///
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
use crate::{DatabaseRw, DbResult, Table};
|
use crate::{DatabaseRw, DbResult, Table};
|
||||||
|
|
||||||
|
use super::{Entry, VacantEntry};
|
||||||
|
|
||||||
/// A view into an occupied entry in a [`DatabaseRw`]. It is part of [`crate::entry::Entry`].
|
/// A view into an occupied entry in a [`DatabaseRw`]. It is part of [`crate::entry::Entry`].
|
||||||
pub struct OccupiedEntry<'a, T, D>
|
pub struct OccupiedEntry<'a, T, D>
|
||||||
where
|
where
|
||||||
|
@ -13,7 +15,7 @@ where
|
||||||
pub(crate) value: T::Value,
|
pub(crate) value: T::Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, D> OccupiedEntry<'_, T, D>
|
impl<'a, T, D> OccupiedEntry<'a, T, D>
|
||||||
where
|
where
|
||||||
T: Table,
|
T: Table,
|
||||||
D: DatabaseRw<T>,
|
D: DatabaseRw<T>,
|
||||||
|
@ -52,7 +54,18 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove this entry.
|
/// Remove this entry.
|
||||||
pub fn remove(self) -> DbResult<T::Value> {
|
///
|
||||||
DatabaseRw::delete(self.db, self.key).map(|()| Ok(self.value))?
|
/// The returns values are:
|
||||||
|
/// - An [`Entry::VacantEntry`]
|
||||||
|
/// - The value that was removed
|
||||||
|
pub fn remove(self) -> DbResult<(Entry<'a, T, D>, T::Value)> {
|
||||||
|
DatabaseRw::delete(self.db, self.key)?;
|
||||||
|
Ok((
|
||||||
|
Entry::Vacant(VacantEntry {
|
||||||
|
db: self.db,
|
||||||
|
key: self.key,
|
||||||
|
}),
|
||||||
|
self.value,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,10 +114,11 @@ fn promote(env: &ConcreteEnv, tx_hash: &TransactionHash) -> DbResult<TxpoolWrite
|
||||||
let res = || {
|
let res = || {
|
||||||
let mut tx_infos = env_inner.open_db_rw::<TransactionInfos>(&tx_rw)?;
|
let mut tx_infos = env_inner.open_db_rw::<TransactionInfos>(&tx_rw)?;
|
||||||
|
|
||||||
tx_infos.update(tx_hash, |mut info| {
|
tx_infos.entry(tx_hash)?.and_update(|info| {
|
||||||
info.flags.remove(TxStateFlags::STATE_STEM);
|
info.flags.remove(TxStateFlags::STATE_STEM);
|
||||||
Some(info)
|
})?;
|
||||||
})
|
|
||||||
|
Ok(())
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(e) = res() {
|
if let Err(e) = res() {
|
||||||
|
|
Loading…
Reference in a new issue