Adding the block module
[?]
Nov 25, 2020, 6:43 PM
ERV3644QELKOHAVNMZGRWYCPPN3XELTAH4PPFR6QKGWW73XBOOKQCDependencies
- [2]
SXEYMYF7Fixing the bad changes in history (unfortunately, by rebooting).
Change contents
- file addition: block.rs[2.525229]
use super::*;/// Find the key where a position is.pub(crate) fn find_block<'db, 'txn: 'db, T: TxnT>(txn: &'txn T,channel: &'db Channel<T>,p: Position<ChangeId>,) -> Result<Vertex<ChangeId>, crate::Error> {if p.change.is_root() {return Ok(Vertex::ROOT);}let key = Vertex {change: p.change,start: p.pos,end: p.pos,};debug!(target: "libpijul::find_block", "find_block {:?}", key);let mut cursor = txn.cursor_graph(&channel.graph, Some((key, None)));let mut k = if let Some((k, _)) = cursor.next() {k} else {return Err(crate::Error::WrongBlock { block: p });};debug!("k = {:?}", k);// The only guarantee here is that k is either the first key// >= `key`, or the key just before that. We might need to// rewind by one step if key is strictly larger than the// result (i.e. if `p` is in the middle of the key).while k.change > p.change || (k.change == p.change && k.start > p.pos) {debug!(target: "libpijul::find_block", "find_block while {:?}", k);if let Some((k_, _)) = cursor.prev() {k = k_} else {break;}}loop {debug!(target: "libpijul::find_block", "find_block loop {:?}", k);if k.change == p.change && k.start <= p.pos {if k.end > p.pos || (k.start == k.end && k.end == p.pos) {return Ok(k);}} else if k.change > p.change {return Err(crate::Error::WrongBlock { block: p });}if let Some((k_, _)) = cursor.next() {k = k_} else {break;}}debug!(target: "libpijul::find_block", "find_block None, {:?}", k);Err(crate::Error::WrongBlock { block: p })}/// Find the key ending at a position.pub(crate) fn find_block_end<'db, 'txn: 'db, T: TxnT>(txn: &'txn T,channel: &'db Channel<T>,p: Position<ChangeId>,) -> Result<Vertex<ChangeId>, crate::Error> {if p.change.is_root() {return Ok(Vertex::ROOT);}let key = Vertex {change: p.change,start: p.pos,end: p.pos,};debug!(target: "libpijul::find_block_end", "find_block_end {:?}, p.change.0 = {:?}", key, p.change.0);let mut cursor = txn.cursor_graph(&channel.graph, Some((key, None)));let mut k = if let Some((k, _)) = cursor.next() {k} else {return Err(crate::Error::WrongBlock { block: p });};// The only guarantee here is that k is either the first key// before `key`, or the key just before that.loop {debug!(target: "libpijul::find_block_end", "find_block_end loop {:?} k.change.0 = {:?}", k, k.change.0);if k.change < p.change {break;} else if k.change == p.change {// Here we want to create an edge pointing between `p`// and its successor. If k.start == p.pos, the only// case where that's what we want is if k.start ==// k.end.if k.start == p.pos && k.end == p.pos {break;} else if k.start < p.pos {break;}}if let Some((k_, _)) = cursor.prev() {k = k_} else {break;}}// We also want k.end >= p.pos, so we just call next() until// we have that.debug!(target: "libpijul::find_block_end", "find_block_end k(0) = {:?} k.change.0 = {:?}", k, k.change.0);while k.change < p.change || (k.change == p.change && p.pos > k.end) {if let Some((k_, _)) = cursor.next() {k = k_} else {break;}}debug!(target: "libpijul::find_block_end", "find_block_end k(1) = {:?}, k.change.0 = {:?}", k, k.change.0);if k.change == p.change && k.start <= p.pos && p.pos <= k.end {Ok(k)} else {Err(crate::Error::WrongBlock { block: p })}}