Commit 46a79406 authored by Christopher Silva's avatar Christopher Silva

add references graph and start of process_changes

parent bed2d627
......@@ -52,6 +52,11 @@ name = "fake-simd"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fixedbitset"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "generic-array"
version = "0.12.3"
......@@ -140,6 +145,11 @@ name = "opaque-debug"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ordermap"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "pest"
version = "2.1.2"
......@@ -179,6 +189,15 @@ dependencies = [
"sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "petgraph"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro2"
version = "1.0.6"
......@@ -228,6 +247,7 @@ dependencies = [
"anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"pest 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
"rust_decimal 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
......@@ -265,6 +285,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
"checksum maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
"checksum num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf4825417e1e1406b3782a8ce92f4d53f26ec055e3622e1881ca8e9f5f9e08db"
......@@ -275,10 +296,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum num-rational 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2885278d5fe2adc2f75ced642d52d879bffaceb5a2e0b1d4309ffdfb239b454"
"checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4"
"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
"checksum pest 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e4fb201c5c22a55d8b24fef95f78be52738e5e1361129be1b5e862ecdb6894a"
"checksum pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0"
"checksum pest_generator 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b9fcf299b5712d06ee128a556c94709aaa04512c4dffb8ead07c5c998447fc0"
"checksum pest_meta 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "df43fd99896fd72c485fe47542c7b500e4ac1e8700bf995544d1317a60ded547"
"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f"
"checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27"
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
"checksum rust_decimal 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f7a28ded8f10361cefb69a8d8e1d195acf59344150534c165c401d6611cf013d"
......
......@@ -11,3 +11,4 @@ rust_decimal = "1.0.3"
anyhow = "1.0.25"
pest = "2.1.2"
pest_derive = "2.1.0"
petgraph = "0.4.13"
......@@ -13,7 +13,7 @@ fn main() {
println!("inserting cells");
for i in 0..200 {
for j in 0..200 {
sheet.write_text(i, j, format!("text {} {}", i, j));
sheet.write_text(i, j, format!("text {} {}", i, j)).unwrap();
}
}
......
......@@ -2,6 +2,7 @@ use std::collections::HashMap;
use std::str::FromStr;
use anyhow::Result;
use petgraph::graphmap::DiGraphMap;
use rust_decimal::Decimal;
use crate::cell::Cell;
......@@ -16,6 +17,7 @@ pub type RenderedRange = Vec<Vec<String>>;
enum Change {
Create((usize, usize), Cell),
Update((usize, usize), Cell),
Reference((usize, usize)),
Delete((usize, usize))
}
use Change::*;
......@@ -25,12 +27,24 @@ pub struct Sheet {
name: String,
cells: HashMap<(usize, usize), Cell>,
changes: Vec<Change>,
references: DiGraphMap<(usize, usize), usize>,
}
macro_rules! write_func {
($name:ident, $closure:expr) => {
($name:ident, true, $closure:expr) => {
pub fn $name(&mut self, r: usize, c: usize, value: String) -> Result<()> {
let cell = $closure(self, value)?;
let cell = $closure(self, r, c, value)?;
self.changes.push(match self.cells.contains_key(&(r, c)) {
true => Update((r, c), cell.clone()),
false => Create((r, c), cell.clone()),
});
self.cells.insert((r, c), cell);
Ok(())
}
};
($name:ident, false, $closure:expr) => {
pub fn $name(&mut self, r: usize, c: usize, value: String) -> Result<()> {
let cell = $closure(value)?;
self.changes.push(match self.cells.contains_key(&(r, c)) {
true => Update((r, c), cell.clone()),
false => Create((r, c), cell.clone()),
......@@ -47,6 +61,7 @@ impl Sheet {
name,
cells: HashMap::new(),
changes: Vec::new(),
references: DiGraphMap::new(),
}
}
......@@ -54,19 +69,26 @@ impl Sheet {
self.cells.len()
}
write_func!(write_number, |_sheet: &Sheet, value: String| -> Result<Cell> {
write_func!(write_number, false, |value: String| -> Result<Cell> {
let decimal = Decimal::from_str(&value[..])?;
Ok(Number(decimal))
});
write_func!(write_text, |_sheet: &Sheet, value: String| -> Result<Cell> {
write_func!(write_text, false, |value: String| -> Result<Cell> {
Ok(Text(value))
});
write_func!(write_formula, |sheet: &Sheet, value: String| -> Result<Cell> {
write_func!(write_formula, true, |sheet: &mut Sheet, r: usize, c: usize, value: String| -> Result<Cell> {
let call = formula::parse(value.clone())?;
let range = sheet.range(call.r, call.c, call.h, call.w);
let result = function::call(call.function, range);
for i in call.r..call.r+call.h {
for j in call.c..call.c+call.w {
if !sheet.references.contains_edge((i, j), (r, c)) {
sheet.references.add_edge((i, j), (r, c), 0);
}
}
}
Ok(Formula(value, Box::new(result)))
});
......@@ -77,12 +99,43 @@ impl Sheet {
}
pub fn process_changes(&mut self) {
let changes = self.changes.clone();
self.changes = Vec::new();
println!("processing {} changes", changes.len());
// for change in changes {
// print!(".");
// }
while self.changes.len() != 0 {
let changes = self.changes.clone();
self.changes = Vec::new();
println!("processing {} changes", changes.len());
for change in changes {
// get index of changed cell
let (r, c) = match change.clone() {
Create(index, _) => index,
Update(index, _) => index,
Reference(index) => index,
Delete(index) => index,
};
// do update for current cell if needed (should just be for formulas?)
// get its neighbors and push reference updates to them
// many cells might be changed at once and a cell would
// get multiple reference changes, should the queue be
// changed to a hashmap?
// could this cause issues with syncing the modified cells with formulas?
let neighbors = self.references.neighbors((r, c));
for neighbor in neighbors {
self.changes.push(Reference(neighbor));
}
// remove node from references if change was a delete
// but only if there are no other nodes that reference it right?
// otherewise a cell that is referenced could be cleared then written to
// and the thing that references it wouldn't get that data
match change {
Create(_, _) => {},
Update(_, _) => {},
Reference(_) => {},
Delete(_) => {},
}
}
}
println!("done");
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment