[thin_explore] display ranges where possible
This commit is contained in:
parent
8493cf7081
commit
bcfb9a73a1
@ -271,12 +271,120 @@ fn read_node<V: Unpack>(engine: &dyn IoEngine, loc: u64) -> Result<btree::Node<V
|
|||||||
|
|
||||||
//------------------------------------
|
//------------------------------------
|
||||||
|
|
||||||
struct NodeWidget<'a, V: Unpack> {
|
// For types that have the concept of adjacency, but not of a distance
|
||||||
|
// between values. For instance with a BlockTime there is no delta that
|
||||||
|
// will get between two values with different times.
|
||||||
|
trait Adjacent {
|
||||||
|
fn adjacent(&self, rhs: &Self) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Adjacent for u64 {
|
||||||
|
fn adjacent(&self, rhs: &Self) -> bool {
|
||||||
|
(*self + 1) == *rhs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Adjacent for BlockTime {
|
||||||
|
fn adjacent(&self, rhs: &Self) -> bool {
|
||||||
|
if self.time != rhs.time {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.block + 1 == rhs.block
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<X: Adjacent, Y: Adjacent> Adjacent for (X, Y) {
|
||||||
|
fn adjacent(&self, rhs: &Self) -> bool {
|
||||||
|
self.0.adjacent(&rhs.0) && self.1.adjacent(&rhs.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn adjacent_runs<V: Adjacent + Copy>(mut ns: Vec<V>) -> Vec<(V, usize)> {
|
||||||
|
let mut result = Vec::new();
|
||||||
|
|
||||||
|
if ns.len() == 0 {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse so we can pop without cloning the value.
|
||||||
|
ns.reverse();
|
||||||
|
|
||||||
|
let mut base = ns.pop().unwrap();
|
||||||
|
let mut current = base;
|
||||||
|
let mut len = 1;
|
||||||
|
while let Some(v) = ns.pop() {
|
||||||
|
if current.adjacent(&v) {
|
||||||
|
current = v;
|
||||||
|
len += 1;
|
||||||
|
} else {
|
||||||
|
result.push((base.clone(), len));
|
||||||
|
base = v.clone();
|
||||||
|
current = v.clone();
|
||||||
|
len = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.push((base.clone(), len));
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mk_runs<V: Adjacent + Sized + Copy>(keys: &[u64], values: &[V]) -> Vec<((u64, V), usize)> {
|
||||||
|
let mut pairs = Vec::new();
|
||||||
|
for (k, v) in keys.iter().zip(values.iter()) {
|
||||||
|
pairs.push((k.clone(), v.clone()));
|
||||||
|
}
|
||||||
|
|
||||||
|
adjacent_runs(pairs)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NodeWidget<'a, V: Unpack + Adjacent + Clone> {
|
||||||
title: String,
|
title: String,
|
||||||
node: &'a btree::Node<V>,
|
node: &'a btree::Node<V>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, V: Unpack + fmt::Display> StatefulWidget for NodeWidget<'a, V> {
|
fn mk_item<'a, V: fmt::Display>(k: u64, v: &V, len: usize) -> ListItem<'a> {
|
||||||
|
if len > 1 {
|
||||||
|
ListItem::new(Span::raw(format!(
|
||||||
|
"[{}..{}] -> {}",
|
||||||
|
k, k + len as u64, v
|
||||||
|
)))
|
||||||
|
} else {
|
||||||
|
ListItem::new(Span::raw(format!("{} -> {}", k, v)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mk_items<'a, V>(keys: &[u64], values: &[V], selected: usize) -> (Vec<ListItem<'a>>, usize)
|
||||||
|
where
|
||||||
|
V: Adjacent + Copy + fmt::Display
|
||||||
|
{
|
||||||
|
let mut items = Vec::new();
|
||||||
|
let bkeys = &keys[0..selected];
|
||||||
|
let key = keys[selected];
|
||||||
|
let akeys = &keys[(selected + 1)..];
|
||||||
|
|
||||||
|
let bvalues = &values[0..selected];
|
||||||
|
let value = values[selected];
|
||||||
|
let avalues = &values[(selected + 1)..];
|
||||||
|
|
||||||
|
let bruns = mk_runs(bkeys, bvalues);
|
||||||
|
let aruns = mk_runs(akeys, avalues);
|
||||||
|
let i = bruns.len();
|
||||||
|
|
||||||
|
for ((k, v), len) in bruns {
|
||||||
|
items.push(mk_item(k, &v, len));
|
||||||
|
}
|
||||||
|
|
||||||
|
items.push(ListItem::new(Span::raw(format!("{} -> {}", key, value))));
|
||||||
|
|
||||||
|
for ((k, v), len) in aruns {
|
||||||
|
items.push(mk_item(k, &v, len));
|
||||||
|
}
|
||||||
|
|
||||||
|
(items, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, V: Unpack + fmt::Display + Adjacent + Copy> StatefulWidget for NodeWidget<'a, V> {
|
||||||
type State = ListState;
|
type State = ListState;
|
||||||
|
|
||||||
fn render(self, area: Rect, buf: &mut Buffer, state: &mut ListState) {
|
fn render(self, area: Rect, buf: &mut Buffer, state: &mut ListState) {
|
||||||
@ -291,20 +399,24 @@ impl<'a, V: Unpack + fmt::Display> StatefulWidget for NodeWidget<'a, V> {
|
|||||||
};
|
};
|
||||||
hdr.render(chunks[0], buf);
|
hdr.render(chunks[0], buf);
|
||||||
|
|
||||||
let mut items: Vec<ListItem> = Vec::new();
|
let mut items: Vec<ListItem>;
|
||||||
|
let i: usize;
|
||||||
|
let selected = state.selected().unwrap();
|
||||||
|
let mut state = ListState::default();
|
||||||
|
|
||||||
match self.node {
|
match self.node {
|
||||||
btree::Node::Internal { keys, values, .. } => {
|
btree::Node::Internal { keys, values, .. } => {
|
||||||
for (k, v) in keys.iter().zip(values.iter()) {
|
let (items_, i_) = mk_items(keys, values, selected);
|
||||||
items.push(ListItem::new(Span::raw(format!("{} -> {}", k, v))));
|
items = items_;
|
||||||
}
|
i = i_;
|
||||||
}
|
}
|
||||||
btree::Node::Leaf { keys, values, .. } => {
|
btree::Node::Leaf { keys, values, .. } => {
|
||||||
for (k, v) in keys.iter().zip(values.iter()) {
|
let (items_, i_) = mk_items(keys, values, selected);
|
||||||
items.push(ListItem::new(Span::raw(format!("{} -> {}", k, v))));
|
items = items_;
|
||||||
}
|
i = i_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
state.select(Some(i));
|
||||||
|
|
||||||
let items = List::new(items)
|
let items = List::new(items)
|
||||||
.block(Block::default().borders(Borders::ALL).title("Entries"))
|
.block(Block::default().borders(Borders::ALL).title("Entries"))
|
||||||
@ -314,7 +426,7 @@ impl<'a, V: Unpack + fmt::Display> StatefulWidget for NodeWidget<'a, V> {
|
|||||||
.add_modifier(Modifier::BOLD),
|
.add_modifier(Modifier::BOLD),
|
||||||
);
|
);
|
||||||
|
|
||||||
StatefulWidget::render(items, chunks[1], buf, state);
|
StatefulWidget::render(items, chunks[1], buf, &mut state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ use crate::pdata::unpack::*;
|
|||||||
|
|
||||||
//------------------------------------------
|
//------------------------------------------
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct BlockTime {
|
pub struct BlockTime {
|
||||||
pub block: u64,
|
pub block: u64,
|
||||||
pub time: u32,
|
pub time: u32,
|
||||||
|
Loading…
Reference in New Issue
Block a user