From c0ddc2ca7020bbe0d29aa3e2b72e27006191c6b4 Mon Sep 17 00:00:00 2001 From: Grisha Kruglov Date: Fri, 29 Jun 2018 22:31:25 -0400 Subject: [PATCH] Part 1: Make `Partition` include explicit `end` range bound. It's helpful to have the full range when syncing. --- db/src/bootstrap.rs | 10 +++++----- db/src/db.rs | 10 +++++----- db/src/types.rs | 10 ++++++++-- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/db/src/bootstrap.rs b/db/src/bootstrap.rs index a070b9e4..7d745347 100644 --- a/db/src/bootstrap.rs +++ b/db/src/bootstrap.rs @@ -85,10 +85,10 @@ lazy_static! { ] }; - static ref V1_PARTS: [(symbols::Keyword, i64, i64); 3] = { - [(ns_keyword!("db.part", "db"), 0, (1 + V1_IDENTS.len()) as i64), - (ns_keyword!("db.part", "user"), USER0, USER0), - (ns_keyword!("db.part", "tx"), TX0, TX0), + pub static ref V1_PARTS: [(symbols::Keyword, i64, i64, i64); 3] = { + [(ns_keyword!("db.part", "db"), 0, USER0 - 1, (1 + V1_IDENTS.len()) as i64), + (ns_keyword!("db.part", "user"), USER0, TX0 - 1, USER0), + (ns_keyword!("db.part", "tx"), TX0, i64::max_value(), TX0), ] }; @@ -277,7 +277,7 @@ fn symbolic_schema_to_assertions(symbolic_schema: &Value) -> Result> pub(crate) fn bootstrap_partition_map() -> PartitionMap { V1_PARTS.iter() - .map(|&(ref part, start, index)| (part.to_string(), Partition::new(start, index))) + .map(|&(ref part, start, end, index)| (part.to_string(), Partition::new(start, end, index))) .collect() } diff --git a/db/src/db.rs b/db/src/db.rs index 8ad0cc60..47b2057a 100644 --- a/db/src/db.rs +++ b/db/src/db.rs @@ -247,7 +247,7 @@ lazy_static! { r#"CREATE TABLE schema (e INTEGER NOT NULL, a SMALLINT NOT NULL, v BLOB NOT NULL, value_type_tag SMALLINT NOT NULL)"#, r#"CREATE INDEX idx_schema_unique ON schema (e, a, v, value_type_tag)"#, // TODO: store entid instead of ident for partition name. - r#"CREATE TABLE parts (part TEXT NOT NULL PRIMARY KEY, start INTEGER NOT NULL, idx INTEGER NOT NULL)"#, + r#"CREATE TABLE parts (part TEXT NOT NULL PRIMARY KEY, start INTEGER NOT NULL, end INTEGER NOT NULL, idx INTEGER NOT NULL)"#, ] }; } @@ -299,7 +299,7 @@ pub fn create_current_version(conn: &mut rusqlite::Connection) -> Result { // This is necessary: `transact` will only UPDATE parts, not INSERT them if they're missing. for (part, partition) in db.partition_map.iter() { // TODO: Convert "keyword" part to SQL using Value conversion. - tx.execute("INSERT INTO parts VALUES (?, ?, ?)", &[part, &partition.start, &partition.index])?; + tx.execute("INSERT INTO parts (part, start, end, idx) VALUES (?, ?, ?, ?)", &[part, &partition.start, &partition.end, &partition.index])?; } // TODO: return to transact_internal to self-manage the encompassing SQLite transaction. @@ -441,9 +441,9 @@ fn read_materialized_view(conn: &rusqlite::Connection, table: &str) -> Result Result { - let mut stmt: rusqlite::Statement = conn.prepare("SELECT part, start, idx FROM parts")?; + let mut stmt: rusqlite::Statement = conn.prepare("SELECT part, start, end, idx FROM parts")?; let m = stmt.query_and_then(&[], |row| -> Result<(String, Partition)> { - Ok((row.get_checked(0)?, Partition::new(row.get_checked(1)?, row.get_checked(2)?))) + Ok((row.get_checked(0)?, Partition::new(row.get_checked(1)?, row.get_checked(2)?, row.get_checked(3)?))) })?.collect(); m } @@ -1280,7 +1280,7 @@ mod tests { // Add a fake partition to allow tests to do things like // [:db/add 111 :foo/bar 222] { - let fake_partition = Partition { start: 100, index: 1000 }; + let fake_partition = Partition { start: 100, end: 2000, index: 1000 }; parts.insert(":db.part/fake".into(), fake_partition); } diff --git a/db/src/types.rs b/db/src/types.rs index 138dd66b..39d221eb 100644 --- a/db/src/types.rs +++ b/db/src/types.rs @@ -41,19 +41,25 @@ use errors; pub struct Partition { /// The first entid in the partition. pub start: i64, + /// Maximum allowed entid in the partition. + pub end: i64, /// The next entid to be allocated in the partition. pub index: i64, } impl Partition { - pub fn new(start: i64, next: i64) -> Partition { + pub fn new(start: i64, end: i64, next: i64) -> Partition { assert!(start <= next, "A partition represents a monotonic increasing sequence of entids."); - Partition { start: start, index: next } + Partition { start: start, end: end, index: next } } pub fn contains_entid(&self, e: i64) -> bool { (e >= self.start) && (e < self.index) } + + pub fn allows_entid(&self, e: i64) -> bool { + (e >= self.start) && (e <= self.end) + } } /// Map partition names to `Partition` instances.