[thin_dump (rust)] First pass at thin_dump.
Doesn't include --repair. This includes <def> and <ref> sections for shared regions.
This commit is contained in:
@@ -550,6 +550,11 @@ pub trait NodeVisitor<V: Unpack> {
|
||||
values: &[V],
|
||||
) -> Result<()>;
|
||||
|
||||
// Nodes may be shared and thus visited multiple times. The walker avoids
|
||||
// doing repeated IO, but it does call this method to keep the visitor up to
|
||||
// date.
|
||||
fn visit_again(&self, path: &Vec<u64>, b: u64) -> Result<()>;
|
||||
|
||||
fn end_walk(&self) -> Result<()>;
|
||||
}
|
||||
|
||||
@@ -654,7 +659,11 @@ impl BTreeWalker {
|
||||
// This node has already been checked ...
|
||||
match self.failed(bs[i]) {
|
||||
None => {
|
||||
// ... it was clean so we can ignore.
|
||||
// ... it was clean.
|
||||
if let Err(e) = visitor.visit_again(path, bs[i]) {
|
||||
// ... but the visitor isn't happy
|
||||
errs.push(e.clone());
|
||||
}
|
||||
}
|
||||
Some(e) => {
|
||||
// ... there was an error
|
||||
@@ -773,7 +782,7 @@ impl BTreeWalker {
|
||||
if let Some(e) = self.failed(root) {
|
||||
Err(e.clone())
|
||||
} else {
|
||||
Ok(())
|
||||
visitor.visit_again(path, root)
|
||||
}
|
||||
} else {
|
||||
let root = self.engine.read(root).map_err(|_| io_err(path))?;
|
||||
@@ -878,7 +887,11 @@ where
|
||||
// This node has already been checked ...
|
||||
match w.failed(bs[i]) {
|
||||
None => {
|
||||
// ... it was clean so we can ignore.
|
||||
// ... it was clean.
|
||||
if let Err(e) = visitor.visit_again(path, bs[i]) {
|
||||
// ... but the visitor isn't happy
|
||||
errs.push(e.clone());
|
||||
}
|
||||
}
|
||||
Some(e) => {
|
||||
// ... there was an error
|
||||
@@ -953,7 +966,7 @@ where
|
||||
if let Some(e) = w.failed(root) {
|
||||
Err(e.clone())
|
||||
} else {
|
||||
Ok(())
|
||||
visitor.visit_again(path, root)
|
||||
}
|
||||
} else {
|
||||
let root = w.engine.read(root).map_err(|_| io_err(path))?;
|
||||
@@ -997,6 +1010,10 @@ impl<V: Unpack + Copy> NodeVisitor<V> for ValueCollector<V> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_again(&self, _path: &Vec<u64>, _b: u64) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn end_walk(&self) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
@@ -1060,6 +1077,10 @@ impl<V: Unpack + Clone> NodeVisitor<V> for ValuePathCollector<V> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_again(&self, _path: &Vec<u64>, _b: u64) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn end_walk(&self) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -225,6 +225,10 @@ pub trait SpaceMap {
|
||||
fn get_nr_blocks(&self) -> Result<u64>;
|
||||
fn get_nr_allocated(&self) -> Result<u64>;
|
||||
fn get(&self, b: u64) -> Result<u32>;
|
||||
|
||||
// Returns the old ref count
|
||||
fn set(&mut self, b: u64, v: u32) -> Result<u32>;
|
||||
|
||||
fn inc(&mut self, begin: u64, len: u64) -> Result<()>;
|
||||
}
|
||||
|
||||
@@ -265,6 +269,20 @@ where
|
||||
Ok(self.counts[b as usize].into())
|
||||
}
|
||||
|
||||
fn set(&mut self, b: u64, v: u32) -> Result<u32> {
|
||||
let old = self.counts[b as usize];
|
||||
assert!(v < 0xff); // FIXME: we can't assume this
|
||||
self.counts[b as usize] = V::from(v as u8);
|
||||
|
||||
if old == V::from(0u8) && v != 0 {
|
||||
self.nr_allocated += 1;
|
||||
} else if old != V::from(0u8) && v == 0 {
|
||||
self.nr_allocated -= 1;
|
||||
}
|
||||
|
||||
Ok(old.into())
|
||||
}
|
||||
|
||||
fn inc(&mut self, begin: u64, len: u64) -> Result<()> {
|
||||
for b in begin..(begin + len) {
|
||||
if self.counts[b as usize] == V::from(0u8) {
|
||||
@@ -325,6 +343,24 @@ impl SpaceMap for RestrictedSpaceMap {
|
||||
}
|
||||
}
|
||||
|
||||
fn set(&mut self, b: u64, v: u32) -> Result<u32> {
|
||||
let old = self.counts.contains(b as usize);
|
||||
|
||||
if v > 0 {
|
||||
if !old {
|
||||
self.nr_allocated += 1;
|
||||
}
|
||||
self.counts.insert(b as usize);
|
||||
} else {
|
||||
if old {
|
||||
self.nr_allocated -= 1;
|
||||
}
|
||||
self.counts.set(b as usize, false);
|
||||
}
|
||||
|
||||
Ok(if old {1} else {0})
|
||||
}
|
||||
|
||||
fn inc(&mut self, begin: u64, len: u64) -> Result<()> {
|
||||
for b in begin..(begin + len) {
|
||||
if !self.counts.contains(b as usize) {
|
||||
|
||||
Reference in New Issue
Block a user