diff --git a/bin/sdf/src/main.rs b/bin/sdf/src/main.rs index 5228fe9134..ceafdc8330 100644 --- a/bin/sdf/src/main.rs +++ b/bin/sdf/src/main.rs @@ -137,6 +137,7 @@ async fn async_main() -> Result<()> { ); if let MigrationMode::Run | MigrationMode::RunAndQuit = config.migration_mode() { + dbg!("migration"); Server::migrate_database(&services_context).await?; if let MigrationMode::RunAndQuit = config.migration_mode() { info!( diff --git a/lib/dal-test/src/expand_helpers.rs b/lib/dal-test/src/expand_helpers.rs index f624d0e8e4..796ed5b778 100644 --- a/lib/dal-test/src/expand_helpers.rs +++ b/lib/dal-test/src/expand_helpers.rs @@ -9,7 +9,15 @@ use jwt_simple::claims::Claims; use jwt_simple::prelude::Duration; use tracing_subscriber::{fmt, util::SubscriberInitExt, EnvFilter, Registry}; -use crate::{helpers::generate_fake_name, jwt_private_signing_key, WorkspaceSignup}; +use crate::{ + helpers::create_user, helpers::generate_fake_name, jwt_private_signing_key, WorkspaceSignup, +}; + +/// Creates a user for each test to run as +pub async fn create_user_and_update_ctx(ctx: &mut DalContext) { + let user = create_user(ctx).await.expect("unable to create user"); + ctx.update_history_actor(dal::HistoryActor::User(user.pk())); +} /// This function is used during macro expansion for setting up a [`ChangeSet`] in an integration test. pub async fn create_change_set_and_update_ctx( diff --git a/lib/dal/src/action.rs b/lib/dal/src/action.rs index bc7fc0bb6d..9ed8a03cdb 100644 --- a/lib/dal/src/action.rs +++ b/lib/dal/src/action.rs @@ -317,7 +317,7 @@ impl Action { .await? .get_action_node_weight()?; let mut new_node_weight = - node_weight.new_with_incremented_vector_clock(ctx.change_set()?.vector_clock_id()); + node_weight.new_with_incremented_vector_clock(ctx.vector_clock_id()?); new_node_weight.set_state(state); ctx.workspace_snapshot()? .add_node(NodeWeight::Action(new_node_weight)) @@ -341,11 +341,17 @@ impl Action { action_prototype_id: ActionPrototypeId, maybe_component_id: Option, ) -> ActionResult { - let change_set = ctx.change_set()?; - let new_id: ActionId = change_set.generate_ulid()?.into(); + let vector_clock_id = ctx.vector_clock_id()?; + let new_id: ActionId = ctx.workspace_snapshot()?.generate_ulid().await?.into(); + let lineage_id = ctx.workspace_snapshot()?.generate_ulid().await?; + let originating_change_set_id = ctx.change_set_id(); - let node_weight = - NodeWeight::new_action(change_set, originating_change_set_id, new_id.into())?; + let node_weight = NodeWeight::new_action( + vector_clock_id, + originating_change_set_id, + new_id.into(), + lineage_id, + )?; ctx.workspace_snapshot()?.add_node(node_weight).await?; let action_category_id = ctx @@ -388,7 +394,7 @@ impl Action { pub async fn remove_by_id(ctx: &DalContext, action_id: ActionId) -> ActionResult<()> { ctx.workspace_snapshot()? - .remove_node_by_id(ctx.change_set()?, action_id) + .remove_node_by_id(ctx.vector_clock_id()?, action_id) .await?; Ok(()) } @@ -398,13 +404,13 @@ impl Action { action_prototype_id: ActionPrototypeId, maybe_component_id: Option, ) -> ActionResult<()> { - let change_set = ctx.change_set()?; let snap = ctx.workspace_snapshot()?; if let Some(action_id) = Self::find_equivalent(ctx, action_prototype_id, maybe_component_id).await? { - snap.remove_node_by_id(change_set, action_id).await?; + snap.remove_node_by_id(ctx.vector_clock_id()?, action_id) + .await?; } Ok(()) } diff --git a/lib/dal/src/action/prototype.rs b/lib/dal/src/action/prototype.rs index 9044934f76..3b9f28c728 100644 --- a/lib/dal/src/action/prototype.rs +++ b/lib/dal/src/action/prototype.rs @@ -148,10 +148,17 @@ impl ActionPrototype { schema_variant_id: SchemaVariantId, func_id: FuncId, ) -> ActionPrototypeResult { - let change_set = ctx.change_set()?; - let new_id: ActionPrototypeId = change_set.generate_ulid()?.into(); - let node_weight = - NodeWeight::new_action_prototype(change_set, new_id.into(), kind, name, description)?; + let vector_clock_id = ctx.vector_clock_id()?; + let new_id: ActionPrototypeId = ctx.workspace_snapshot()?.generate_ulid().await?.into(); + let lineage_id = ctx.workspace_snapshot()?.generate_ulid().await?; + let node_weight = NodeWeight::new_action_prototype( + vector_clock_id, + new_id.into(), + lineage_id, + kind, + name, + description, + )?; ctx.workspace_snapshot()?.add_node(node_weight).await?; Self::add_edge_to_func(ctx, new_id, func_id, EdgeWeightKind::new_use()).await?; @@ -422,10 +429,8 @@ impl ActionPrototype { Ok(triggered_actions) } pub async fn remove(ctx: &DalContext, id: ActionPrototypeId) -> ActionPrototypeResult<()> { - let change_set = ctx.change_set()?; - ctx.workspace_snapshot()? - .remove_node_by_id(change_set, id) + .remove_node_by_id(ctx.vector_clock_id()?, id) .await?; Ok(()) diff --git a/lib/dal/src/attribute/prototype.rs b/lib/dal/src/attribute/prototype.rs index bab0faef84..503d956a15 100644 --- a/lib/dal/src/attribute/prototype.rs +++ b/lib/dal/src/attribute/prototype.rs @@ -151,11 +151,15 @@ impl AttributePrototype { ) .await?; - let change_set = ctx.change_set()?; - let id = change_set.generate_ulid()?; - let node_weight = - NodeWeight::new_content(change_set, id, ContentAddress::AttributePrototype(hash))?; let workspace_snapshot = ctx.workspace_snapshot()?; + let id = workspace_snapshot.generate_ulid().await?; + let lineage_id = workspace_snapshot.generate_ulid().await?; + let node_weight = NodeWeight::new_content( + ctx.vector_clock_id()?, + id, + lineage_id, + ContentAddress::AttributePrototype(hash), + )?; let _node_index = workspace_snapshot.add_node(node_weight).await?; let prototype = AttributePrototype::assemble(id.into(), &content); @@ -328,10 +332,9 @@ impl AttributePrototype { attribute_prototype_id, ))?; - let change_set = ctx.change_set()?; workspace_snapshot .remove_edge( - change_set, + ctx.vector_clock_id()?, attribute_prototype_idx, current_func_node_idx, EdgeWeightKindDiscriminants::Use, @@ -462,10 +465,8 @@ impl AttributePrototype { ctx: &DalContext, prototype_id: AttributePrototypeId, ) -> AttributePrototypeResult<()> { - let change_set = ctx.change_set()?; - ctx.workspace_snapshot()? - .remove_node_by_id(change_set, prototype_id) + .remove_node_by_id(ctx.vector_clock_id()?, prototype_id) .await?; Ok(()) diff --git a/lib/dal/src/attribute/prototype/argument.rs b/lib/dal/src/attribute/prototype/argument.rs index e00f7a27b7..abd54b5a7c 100644 --- a/lib/dal/src/attribute/prototype/argument.rs +++ b/lib/dal/src/attribute/prototype/argument.rs @@ -197,9 +197,12 @@ impl AttributePrototypeArgument { prototype_id: AttributePrototypeId, arg_id: FuncArgumentId, ) -> AttributePrototypeArgumentResult { - let change_set = ctx.change_set()?; - let id = change_set.generate_ulid()?; - let node_weight = NodeWeight::new_attribute_prototype_argument(change_set, id, None)?; + let vector_clock_id = ctx.vector_clock_id()?; + let id = ctx.workspace_snapshot()?.generate_ulid().await?; + let lineage_id = ctx.workspace_snapshot()?.generate_ulid().await?; + + let node_weight = + NodeWeight::new_attribute_prototype_argument(vector_clock_id, id, lineage_id, None)?; let workspace_snapshot = ctx.workspace_snapshot()?; @@ -230,11 +233,13 @@ impl AttributePrototypeArgument { destination_component_id: ComponentId, destination_attribute_prototype_id: AttributePrototypeId, ) -> AttributePrototypeArgumentResult { - let change_set = ctx.change_set()?; - let id = change_set.generate_ulid()?; + let vector_clock_id = ctx.vector_clock_id()?; + let id = ctx.workspace_snapshot()?.generate_ulid().await?; + let lineage_id = ctx.workspace_snapshot()?.generate_ulid().await?; let node_weight = NodeWeight::new_attribute_prototype_argument( - change_set, + vector_clock_id, id, + lineage_id, Some(ArgumentTargets { source_component_id, destination_component_id, @@ -382,7 +387,6 @@ impl AttributePrototypeArgument { value_id: Ulid, ) -> AttributePrototypeArgumentResult { let workspace_snapshot = ctx.workspace_snapshot()?; - let change_set = ctx.change_set()?; for existing_value_source in workspace_snapshot .outgoing_targets_for_edge_weight_kind( @@ -394,7 +398,7 @@ impl AttributePrototypeArgument { let self_node_index = workspace_snapshot.get_node_index_by_id(self.id).await?; workspace_snapshot .remove_edge( - change_set, + ctx.vector_clock_id()?, self_node_index, existing_value_source, EdgeWeightKindDiscriminants::PrototypeArgumentValue, @@ -646,7 +650,7 @@ impl AttributePrototypeArgument { // Remove the argument ctx.workspace_snapshot()? - .remove_node_by_id(ctx.change_set()?, self.id) + .remove_node_by_id(ctx.vector_clock_id()?, self.id) .await?; // Enqueue a dependent values update with the destination attribute values diff --git a/lib/dal/src/attribute/prototype/argument/static_value.rs b/lib/dal/src/attribute/prototype/argument/static_value.rs index 9147ab1d9d..0b785beac2 100644 --- a/lib/dal/src/attribute/prototype/argument/static_value.rs +++ b/lib/dal/src/attribute/prototype/argument/static_value.rs @@ -56,10 +56,14 @@ impl StaticArgumentValue { ) .await?; - let change_set = ctx.change_set()?; - let id = change_set.generate_ulid()?; - let node_weight = - NodeWeight::new_content(change_set, id, ContentAddress::StaticArgumentValue(hash))?; + let id = ctx.workspace_snapshot()?.generate_ulid().await?; + let lineage_id = ctx.workspace_snapshot()?.generate_ulid().await?; + let node_weight = NodeWeight::new_content( + ctx.vector_clock_id()?, + id, + lineage_id, + ContentAddress::StaticArgumentValue(hash), + )?; ctx.workspace_snapshot()?.add_node(node_weight).await?; diff --git a/lib/dal/src/attribute/value.rs b/lib/dal/src/attribute/value.rs index ef2393ac1d..7ca166f232 100644 --- a/lib/dal/src/attribute/value.rs +++ b/lib/dal/src/attribute/value.rs @@ -295,9 +295,11 @@ impl AttributeValue { maybe_parent_attribute_value: Option, key: Option, ) -> AttributeValueResult { - let change_set = ctx.change_set()?; - let id = change_set.generate_ulid()?; - let node_weight = NodeWeight::new_attribute_value(change_set, id, None, None)?; + let vector_clock_id = ctx.vector_clock_id()?; + let id = ctx.workspace_snapshot()?.generate_ulid().await?; + let lineage_id = ctx.workspace_snapshot()?.generate_ulid().await?; + let node_weight = + NodeWeight::new_attribute_value(vector_clock_id, id, lineage_id, None, None)?; let is_for = is_for.into(); let ordered = if let Some(prop_id) = is_for.prop_id() { @@ -313,7 +315,7 @@ impl AttributeValue { if ordered { ctx.workspace_snapshot()? - .add_ordered_node(change_set, node_weight.clone()) + .add_ordered_node(vector_clock_id, node_weight.clone()) .await?; } else { ctx.workspace_snapshot()? @@ -1131,7 +1133,7 @@ impl AttributeValue { .id(); workspace_snapshot - .remove_node_by_id(ctx.change_set()?, current_target_id) + .remove_node_by_id(ctx.vector_clock_id()?, current_target_id) .await?; } @@ -1770,7 +1772,7 @@ impl AttributeValue { ctx.workspace_snapshot()? .remove_edge_for_ulids( - ctx.change_set()?, + ctx.vector_clock_id()?, attribute_value_id, prototype_id, EdgeWeightKindDiscriminants::Prototype, @@ -1943,7 +1945,7 @@ impl AttributeValue { .await?; let mut new_av_node_weight = - av_node_weight.new_with_incremented_vector_clock(ctx.change_set()?.vector_clock_id()); + av_node_weight.new_with_incremented_vector_clock(ctx.vector_clock_id()?); new_av_node_weight.set_value(value_address.map(ContentAddress::JsonValue)); new_av_node_weight @@ -2192,10 +2194,10 @@ impl AttributeValue { .ok_or(AttributeValueError::RemovingWhenNotChildOrMapOrArray(id))?; ctx.workspace_snapshot()? - .remove_node_by_id(ctx.change_set()?, id) + .remove_node_by_id(ctx.vector_clock_id()?, id) .await?; ctx.workspace_snapshot()? - .remove_dependent_value_root(ctx.change_set()?, id) + .remove_dependent_value_root(ctx.vector_clock_id()?, id) .await?; ctx.add_dependent_values_and_enqueue(vec![parent_av_id]) diff --git a/lib/dal/src/change_set.rs b/lib/dal/src/change_set.rs index 0fefd5c3d5..e69f5066fc 100644 --- a/lib/dal/src/change_set.rs +++ b/lib/dal/src/change_set.rs @@ -1,12 +1,10 @@ //! The sequel to [`ChangeSets`](crate::ChangeSet). Coming to an SI instance near you! -use std::sync::{Arc, Mutex}; - use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; +use si_events::VectorClockChangeSetId; use si_layer_cache::LayerDbError; use thiserror::Error; -use ulid::Generator; use si_data_pg::{PgError, PgRow}; use si_events::{ulid::Ulid, WorkspaceSnapshotAddress}; @@ -128,9 +126,6 @@ pub struct ChangeSet { pub workspace_snapshot_address: Option, pub workspace_id: Option, pub merge_requested_by_user_id: Option, - - #[serde(skip)] - pub generator: Arc>, } impl TryFrom for ChangeSet { @@ -149,47 +144,23 @@ impl TryFrom for ChangeSet { workspace_snapshot_address: value.try_get("workspace_snapshot_address")?, workspace_id: value.try_get("workspace_id")?, merge_requested_by_user_id: value.try_get("merge_requested_by_user_id")?, - generator: Arc::new(Mutex::new(Default::default())), }) } } impl ChangeSet { - pub fn new_local() -> ChangeSetResult { - let mut generator = Generator::new(); - let id: Ulid = generator.generate()?.into(); - - Ok(Self { - id: id.into(), - created_at: Utc::now(), - updated_at: Utc::now(), - generator: Arc::new(Mutex::new(generator)), - base_change_set_id: None, - workspace_snapshot_address: None, - workspace_id: None, - name: "".to_string(), - status: ChangeSetStatus::Open, - merge_requested_by_user_id: None, - }) - } - - pub fn editing_changeset(&self) -> ChangeSetResult { - let mut new_local = Self::new_local()?; - new_local.base_change_set_id = self.base_change_set_id; - new_local.workspace_snapshot_address = self.workspace_snapshot_address; - new_local.workspace_id = self.workspace_id; - self.name.clone_into(&mut new_local.name); - self.status.clone_into(&mut new_local.status); - Ok(new_local) - } - pub async fn new( ctx: &DalContext, name: impl AsRef, base_change_set_id: Option, workspace_snapshot_address: WorkspaceSnapshotAddress, ) -> ChangeSetResult { - let id: ChangeSetId = Ulid::new().into(); + let id: Ulid = Ulid::new(); + let vector_clock_id = VectorClockId::new( + VectorClockChangeSetId::new(id), + ctx.vector_clock_id()?.actor_id(), + ); + let change_set_id: ChangeSetId = id.into(); let workspace_snapshot = WorkspaceSnapshot::find(ctx, workspace_snapshot_address) .await @@ -200,7 +171,7 @@ impl ChangeSet { // changeset needs to have seen the "to_rebase" or we will treat them as // completely disjoint changesets. let workspace_snapshot_address = workspace_snapshot - .write(ctx, id.into_inner().into()) + .write(ctx, vector_clock_id) .await .map_err(Box::new)?; @@ -212,7 +183,7 @@ impl ChangeSet { .pg() .query_one( "INSERT INTO change_set_pointers (id, name, base_change_set_id, status, workspace_id, workspace_snapshot_address) VALUES ($1, $2, $3, $4, $5, $6) RETURNING *", - &[&id, &name, &base_change_set_id, &ChangeSetStatus::Open.to_string(), &workspace_id, &workspace_snapshot_address], + &[&change_set_id, &name, &base_change_set_id, &ChangeSetStatus::Open.to_string(), &workspace_id, &workspace_snapshot_address], ) .await?; let change_set = Self::try_from(row)?; @@ -259,19 +230,14 @@ impl ChangeSet { Ok(change_set) } - /// Create a [`VectorClockId`] from the [`ChangeSet`]. - pub fn vector_clock_id(&self) -> VectorClockId { - VectorClockId::from(Ulid::from(self.id)) - } - - pub fn generate_ulid(&self) -> ChangeSetResult { - self.generator - .lock() - .map_err(|e| ChangeSetError::Mutex(e.to_string()))? - .generate() - .map(Into::into) - .map_err(Into::into) - } + // pub fn generate_ulid(&self) -> ChangeSetResult { + // self.generator + // .lock() + // .map_err(|e| ChangeSetError::Mutex(e.to_string()))? + // .generate() + // .map(Into::into) + // .map_err(Into::into) + // } pub async fn update_workspace_id( &mut self, @@ -499,7 +465,7 @@ impl ChangeSet { .ok_or(ChangeSetError::NoWorkspaceSnapshot(self.id))?; let rebase_request = RebaseRequest { onto_workspace_snapshot_address, - onto_vector_clock_id: self.vector_clock_id(), + onto_vector_clock_id: ctx.vector_clock_id()?, to_rebase_change_set_id, }; ctx.do_rebase_request(rebase_request).await?; diff --git a/lib/dal/src/component.rs b/lib/dal/src/component.rs index 8b736ba387..6829c67da0 100644 --- a/lib/dal/src/component.rs +++ b/lib/dal/src/component.rs @@ -407,12 +407,13 @@ impl Component { ) .await?; - let change_set = ctx.change_set()?; - let id = change_set.generate_ulid()?; - let node_weight = NodeWeight::new_component(change_set, id, hash)?; + let workspace_snapshot = ctx.workspace_snapshot()?; + let id = workspace_snapshot.generate_ulid().await?; + let lineage_id = workspace_snapshot.generate_ulid().await?; + + let node_weight = NodeWeight::new_component(ctx.vector_clock_id()?, id, lineage_id, hash)?; // Attach component to category and add use edge to schema variant - let workspace_snapshot = ctx.workspace_snapshot()?; workspace_snapshot.add_node(node_weight).await?; // Root --> Component Category --> Component (this) @@ -574,6 +575,7 @@ impl Component { // The update operation orphans deeply nested values, clear them out to // avoid issues downstream ctx.workspace_snapshot()?.cleanup().await?; + let vector_clock_id = ctx.vector_clock_id()?; // Now, walk the attribute value tree and reset all prototypes to the default @@ -595,7 +597,7 @@ impl Component { if is_dependent_func { ctx.workspace_snapshot()? .remove_edge_for_ulids( - ctx.change_set()?, + vector_clock_id, current_av_id, component_prototype_id, EdgeWeightKindDiscriminants::Prototype, @@ -1173,7 +1175,7 @@ impl Component { .await?; ctx.workspace_snapshot()? - .update_content(ctx.change_set()?, id.into(), hash) + .update_content(ctx.vector_clock_id()?, id.into(), hash) .await?; } let (node_weight, content) = Self::get_node_weight_and_content(ctx, id).await?; @@ -1633,7 +1635,7 @@ impl Component { ) -> ComponentResult<()> { ctx.workspace_snapshot()? .remove_edge_for_ulids( - ctx.change_set()?, + ctx.vector_clock_id()?, parent_id, child_id, EdgeWeightKindDiscriminants::FrameContains, @@ -1860,8 +1862,8 @@ impl Component { .get_node_weight(component_idx) .await? .get_component_node_weight()?; - let mut new_component_node_weight = component_node_weight - .new_with_incremented_vector_clock(ctx.change_set()?.vector_clock_id()); + let mut new_component_node_weight = + component_node_weight.new_with_incremented_vector_clock(ctx.vector_clock_id()?); new_component_node_weight.set_to_delete(component.to_delete); ctx.workspace_snapshot()? .add_node(NodeWeight::Component(new_component_node_weight)) @@ -1884,7 +1886,7 @@ impl Component { ) .await?; ctx.workspace_snapshot()? - .update_content(ctx.change_set()?, component.id.into(), hash) + .update_content(ctx.vector_clock_id()?, component.id.into(), hash) .await?; } @@ -1899,7 +1901,7 @@ impl Component { #[instrument(level = "info", skip(ctx))] pub async fn remove(ctx: &DalContext, id: ComponentId) -> ComponentResult<()> { - let change_set = ctx.change_set()?; + let vector_clock_id = ctx.vector_clock_id()?; let component = Self::get_by_id(ctx, id).await?; @@ -1944,7 +1946,7 @@ impl Component { .await?; ctx.workspace_snapshot()? - .remove_node_by_id(change_set, id) + .remove_node_by_id(vector_clock_id, id) .await?; WsEvent::component_deleted(ctx, id) diff --git a/lib/dal/src/context.rs b/lib/dal/src/context.rs index e4ccca689d..314d6badf4 100644 --- a/lib/dal/src/context.rs +++ b/lib/dal/src/context.rs @@ -7,6 +7,8 @@ use si_crypto::SymmetricCryptoService; use si_crypto::VeritechEncryptionKey; use si_data_nats::{NatsClient, NatsError, NatsTxn}; use si_data_pg::{InstrumentedClient, PgError, PgPool, PgPoolError, PgPoolResult, PgTxn}; +use si_events::VectorClockActorId; +use si_events::VectorClockChangeSetId; use si_events::WorkspaceSnapshotAddress; use si_layer_cache::activities::rebase::RebaseStatus; use si_layer_cache::activities::ActivityPayload; @@ -396,7 +398,7 @@ impl DalContext { &self, ) -> Result, TransactionsError> { if let Some(snapshot) = &self.workspace_snapshot { - let vector_clock_id = self.change_set()?.vector_clock_id(); + let vector_clock_id = self.vector_clock_id()?; Ok(Some(snapshot.write(self, vector_clock_id).await.map_err( |err| TransactionsError::WorkspaceSnapshot(Box::new(err)), @@ -410,7 +412,7 @@ impl DalContext { &self, onto_workspace_snapshot_address: WorkspaceSnapshotAddress, ) -> Result { - let vector_clock_id = self.change_set()?.vector_clock_id(); + let vector_clock_id = self.vector_clock_id()?; Ok(RebaseRequest { onto_workspace_snapshot_address, // the vector clock id of the current change set is just the id @@ -509,6 +511,27 @@ impl DalContext { Ok(()) } + pub fn change_set_id(&self) -> ChangeSetId { + self.visibility.change_set_id + } + + pub fn vector_clock_id(&self) -> Result { + let change_set_id = self.visibility.change_set_id.into_inner(); + let actor_id = match self.history_actor { + HistoryActor::SystemInit => self + .tenancy + .workspace_pk() + .unwrap_or(WorkspacePk::NONE) + .into_inner(), + HistoryActor::User(user_pk) => user_pk.into_inner(), + }; + + Ok(VectorClockId::new( + VectorClockChangeSetId::new(change_set_id.into()), + VectorClockActorId::new(actor_id.into()), + )) + } + pub fn change_set(&self) -> Result<&ChangeSet, TransactionsError> { match self.change_set.as_ref() { Some(csp_ref) => Ok(csp_ref), @@ -531,12 +554,7 @@ impl DalContext { // Ulid generator and new vector clock id so that concurrent editing conflicts can be // resolved by the rebaser. This change set is not persisted to the database (the // rebaser will persist a new one if it can) - self.change_set = Some( - change_set - .editing_changeset() - .map_err(|err| TransactionsError::ChangeSet(err.to_string()))?, - ); - + self.change_set = Some(change_set); self.change_set() } @@ -734,7 +752,7 @@ impl DalContext { ) -> Result<(), WorkspaceSnapshotError> { for id in ids { self.workspace_snapshot()? - .add_dependent_value_root(self.change_set()?, id) + .add_dependent_value_root(self.vector_clock_id()?, id) .await?; } @@ -895,11 +913,6 @@ impl DalContext { Ok(is_in_our_tenancy) } - // NOTE(nick,zack,jacob): likely a temporary func to get the change set id from the visibility. - pub fn change_set_id(&self) -> ChangeSetId { - self.visibility.change_set_id - } - pub fn access_builder(&self) -> AccessBuilder { AccessBuilder::new(self.tenancy, self.history_actor) } @@ -1171,6 +1184,8 @@ pub enum TransactionsError { Workspace(String), #[error("workspace not found by pk: {0}")] WorkspaceNotFound(WorkspacePk), + #[error("workspace not set on DalContext")] + WorkspaceNotSet, #[error("workspace snapshot error: {0}")] WorkspaceSnapshot(Box), } @@ -1309,7 +1324,7 @@ async fn rebase( .rebase_and_wait( rebase_request.to_rebase_change_set_id.into(), rebase_request.onto_workspace_snapshot_address, - rebase_request.onto_vector_clock_id.into(), + rebase_request.onto_vector_clock_id, metadata, ) .await?; diff --git a/lib/dal/src/func.rs b/lib/dal/src/func.rs index 35e13f7ee0..00430cc492 100644 --- a/lib/dal/src/func.rs +++ b/lib/dal/src/func.rs @@ -249,10 +249,16 @@ impl Func { let func_kind = FuncKind::new(backend_kind, backend_response_type)?; - let change_set = ctx.change_set()?; - let id = change_set.generate_ulid()?; - let node_weight = - NodeWeight::new_func(change_set, id, name.clone().into(), func_kind, hash)?; + let id = ctx.workspace_snapshot()?.generate_ulid().await?; + let lineage_id = ctx.workspace_snapshot()?.generate_ulid().await?; + let node_weight = NodeWeight::new_func( + ctx.vector_clock_id()?, + id, + lineage_id, + name.clone().into(), + func_kind, + hash, + )?; let workspace_snapshot = ctx.workspace_snapshot()?; workspace_snapshot.add_node(node_weight.clone()).await?; @@ -441,8 +447,7 @@ impl Func { workspace_snapshot .add_node(NodeWeight::Func( - node_weight - .new_with_incremented_vector_clock(ctx.change_set()?.vector_clock_id()), + node_weight.new_with_incremented_vector_clock(ctx.vector_clock_id()?), )) .await?; @@ -464,7 +469,7 @@ impl Func { ) .await?; workspace_snapshot - .update_content(ctx.change_set()?, func.id.into(), hash) + .update_content(ctx.vector_clock_id()?, func.id.into(), hash) .await?; } @@ -508,8 +513,9 @@ impl Func { // Now, we can remove the func. let workspace_snapshot = ctx.workspace_snapshot()?; - let change_set = ctx.change_set()?; - workspace_snapshot.remove_node_by_id(change_set, id).await?; + workspace_snapshot + .remove_node_by_id(ctx.vector_clock_id()?, id) + .await?; Ok(func.name) } diff --git a/lib/dal/src/func/argument.rs b/lib/dal/src/func/argument.rs index e20aa73b90..a40d6c84a3 100644 --- a/lib/dal/src/func/argument.rs +++ b/lib/dal/src/func/argument.rs @@ -201,11 +201,11 @@ impl FuncArgument { ) .await?; - let change_set = ctx.change_set()?; - let id = change_set.generate_ulid()?; - let node_weight = NodeWeight::new_func_argument(change_set, id, name, hash)?; - let workspace_snapshot = ctx.workspace_snapshot()?; + let id = workspace_snapshot.generate_ulid().await?; + let lineage_id = workspace_snapshot.generate_ulid().await?; + let node_weight = + NodeWeight::new_func_argument(ctx.vector_clock_id()?, id, lineage_id, name, hash)?; workspace_snapshot.add_node(node_weight.clone()).await?; Func::add_edge_to_argument(ctx, func_id, id.into(), EdgeWeightKind::new_use()).await?; @@ -387,8 +387,7 @@ impl FuncArgument { workspace_snapshot .add_node(NodeWeight::FuncArgument( - node_weight - .new_with_incremented_vector_clock(ctx.change_set()?.vector_clock_id()), + node_weight.new_with_incremented_vector_clock(ctx.vector_clock_id()?), )) .await?; @@ -410,7 +409,7 @@ impl FuncArgument { ) .await?; workspace_snapshot - .update_content(ctx.change_set()?, func_argument.id.into(), hash) + .update_content(ctx.vector_clock_id()?, func_argument.id.into(), hash) .await?; } @@ -463,9 +462,8 @@ impl FuncArgument { } // Now, we can remove the argument. - let change_set = ctx.change_set()?; ctx.workspace_snapshot()? - .remove_node_by_id(change_set, id) + .remove_node_by_id(ctx.vector_clock_id()?, id) .await?; Ok(()) diff --git a/lib/dal/src/job/definition/dependent_values_update.rs b/lib/dal/src/job/definition/dependent_values_update.rs index ba56abd7f9..c24b7abc9a 100644 --- a/lib/dal/src/job/definition/dependent_values_update.rs +++ b/lib/dal/src/job/definition/dependent_values_update.rs @@ -121,7 +121,7 @@ impl DependentValuesUpdate { let node_ids = ctx .workspace_snapshot()? - .take_dependent_values(ctx.change_set()?) + .take_dependent_values(ctx.vector_clock_id()?) .await?; let mut dependency_graph = DependentValueGraph::new(ctx, node_ids).await?; diff --git a/lib/dal/src/module.rs b/lib/dal/src/module.rs index 1cedce88bf..39ee872a8d 100644 --- a/lib/dal/src/module.rs +++ b/lib/dal/src/module.rs @@ -134,12 +134,16 @@ impl Module { ) .await?; - let change_set = ctx.change_set()?; - let id = change_set.generate_ulid()?; - - let node_weight = NodeWeight::new_content(change_set, id, ContentAddress::Module(hash))?; - let workspace_snapshot = ctx.workspace_snapshot()?; + let id = workspace_snapshot.generate_ulid().await?; + let lineage_id = workspace_snapshot.generate_ulid().await?; + let node_weight = NodeWeight::new_content( + ctx.vector_clock_id()?, + id, + lineage_id, + ContentAddress::Module(hash), + )?; + workspace_snapshot.add_node(node_weight).await?; let schema_module_index_id = workspace_snapshot @@ -148,7 +152,7 @@ impl Module { workspace_snapshot .add_edge( schema_module_index_id, - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use())?, + EdgeWeight::new(ctx.vector_clock_id()?, EdgeWeightKind::new_use())?, id, ) .await?; @@ -214,10 +218,7 @@ impl Module { workspace_snapshot .add_edge( self.id, - EdgeWeight::new( - ctx.change_set()?.vector_clock_id(), - EdgeWeightKind::new_use(), - )?, + EdgeWeight::new(ctx.vector_clock_id()?, EdgeWeightKind::new_use())?, target_id, ) .await?; diff --git a/lib/dal/src/prop.rs b/lib/dal/src/prop.rs index adb2f67637..b31694df34 100644 --- a/lib/dal/src/prop.rs +++ b/lib/dal/src/prop.rs @@ -497,15 +497,16 @@ impl Prop { ) .await?; - let change_set = ctx.change_set()?; - let id = change_set.generate_ulid()?; - let node_weight = NodeWeight::new_prop(change_set, id, kind, name, hash)?; + let vector_clock_id = ctx.vector_clock_id()?; + let workspace_snapshot = ctx.workspace_snapshot()?; + let id = workspace_snapshot.generate_ulid().await?; + let lineage_id = workspace_snapshot.generate_ulid().await?; + let node_weight = NodeWeight::new_prop(vector_clock_id, id, lineage_id, kind, name, hash)?; let prop_node_weight = node_weight.get_prop_node_weight()?; - let workspace_snapshot = ctx.workspace_snapshot()?; if ordered { workspace_snapshot - .add_ordered_node(change_set, node_weight) + .add_ordered_node(vector_clock_id, node_weight) .await?; } else { workspace_snapshot.add_node(node_weight).await?; @@ -1025,7 +1026,7 @@ impl Prop { .await?; ctx.workspace_snapshot()? - .update_content(ctx.change_set()?, prop.id.into(), hash) + .update_content(ctx.vector_clock_id()?, prop.id.into(), hash) .await?; } Ok(prop) diff --git a/lib/dal/src/schema.rs b/lib/dal/src/schema.rs index 523df735b8..1fb016d835 100644 --- a/lib/dal/src/schema.rs +++ b/lib/dal/src/schema.rs @@ -125,11 +125,17 @@ impl Schema { ) .await?; - let change_set = ctx.change_set()?; - let id = change_set.generate_ulid()?; - let node_weight = NodeWeight::new_content(change_set, id, ContentAddress::Schema(hash))?; - let workspace_snapshot = ctx.workspace_snapshot()?; + + let id = workspace_snapshot.generate_ulid().await?; + let lineage_id = workspace_snapshot.generate_ulid().await?; + let node_weight = NodeWeight::new_content( + ctx.vector_clock_id()?, + id, + lineage_id, + ContentAddress::Schema(hash), + )?; + workspace_snapshot.add_node(node_weight).await?; let schema_category_index_id = workspace_snapshot @@ -138,7 +144,7 @@ impl Schema { workspace_snapshot .add_edge( schema_category_index_id, - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use())?, + EdgeWeight::new(ctx.vector_clock_id()?, EdgeWeightKind::new_use())?, id, ) .await?; @@ -215,7 +221,7 @@ impl Schema { // we now need to update that edge to be a Use workspace_snapshot .remove_edge( - ctx.change_set()?, + ctx.vector_clock_id()?, source_index, target_index, edge_weight.kind().into(), @@ -242,7 +248,7 @@ impl Schema { workspace_snapshot .remove_edge( - ctx.change_set()?, + ctx.vector_clock_id()?, source_index, target_index, EdgeWeightKind::new_use().into(), @@ -303,7 +309,7 @@ impl Schema { .await?; ctx.workspace_snapshot()? - .update_content(ctx.change_set()?, schema.id.into(), hash) + .update_content(ctx.vector_clock_id()?, schema.id.into(), hash) .await?; } diff --git a/lib/dal/src/schema/variant.rs b/lib/dal/src/schema/variant.rs index e12bf00aff..50731fa41c 100644 --- a/lib/dal/src/schema/variant.rs +++ b/lib/dal/src/schema/variant.rs @@ -337,10 +337,14 @@ impl SchemaVariant { ) .await?; - let change_set = ctx.change_set()?; - let id = change_set.generate_ulid()?; - let node_weight = - NodeWeight::new_content(change_set, id, ContentAddress::SchemaVariant(hash))?; + let id = workspace_snapshot.generate_ulid().await?; + let lineage_id = workspace_snapshot.generate_ulid().await?; + let node_weight = NodeWeight::new_content( + ctx.vector_clock_id()?, + id, + lineage_id, + ContentAddress::SchemaVariant(hash), + )?; workspace_snapshot.add_node(node_weight).await?; // Schema --Use--> SchemaVariant (this) @@ -377,7 +381,7 @@ impl SchemaVariant { .await?; ctx.workspace_snapshot()? - .update_content(ctx.change_set()?, schema_variant.id.into(), hash) + .update_content(ctx.vector_clock_id()?, schema_variant.id.into(), hash) .await?; } @@ -880,10 +884,9 @@ impl SchemaVariant { func_id: FuncId, schema_variant_id: SchemaVariantId, ) -> SchemaVariantResult<()> { - let change_set = ctx.change_set()?; ctx.workspace_snapshot()? .remove_edge_for_ulids( - change_set, + ctx.vector_clock_id()?, schema_variant_id, func_id, EdgeWeightKindDiscriminants::AuthenticationPrototype, @@ -1692,7 +1695,7 @@ impl SchemaVariant { for (_edge_weight, _source_index, target_index) in maybe_schema_indices { workspace_snapshot .remove_node_by_id( - ctx.change_set()?, + ctx.vector_clock_id()?, workspace_snapshot.get_node_weight(target_index).await?.id(), ) .await?; diff --git a/lib/dal/src/secret.rs b/lib/dal/src/secret.rs index 0d24a91276..63de5b87ac 100644 --- a/lib/dal/src/secret.rs +++ b/lib/dal/src/secret.rs @@ -223,12 +223,12 @@ impl Secret { HistoryActor::User(user_pk) => Some(*user_pk), }; - let change_set = ctx.change_set()?; - let id = change_set.generate_ulid()?; + let id = ctx.workspace_snapshot()?.generate_ulid().await?; + let lineage_id = ctx.workspace_snapshot()?.generate_ulid().await?; let secret_id = id.into(); // Generate a key for the underlying encrypted secret. - let key = Self::generate_key(ctx, secret_id)?; + let key = Self::generate_key(ctx, secret_id).await?; let content = SecretContentV1 { timestamp: Timestamp::now(), @@ -250,7 +250,8 @@ impl Secret { ) .await?; - let node_weight = NodeWeight::new_secret(change_set, id, key, hash)?; + let node_weight = + NodeWeight::new_secret(ctx.vector_clock_id()?, id, lineage_id, key, hash)?; let secret_node_weight = node_weight.get_secret_node_weight()?; let workspace_snapshot = ctx.workspace_snapshot()?; @@ -283,8 +284,11 @@ impl Secret { /// A new key should be assembled anytime an [`EncryptedSecret`] is created or mutated. This /// method is purposefully owned by [`Secret`] to help ensure that we don't generate a key based /// on any encrypted contents or parameters to insert encrypted contents. - fn generate_key(ctx: &DalContext, secret_id: SecretId) -> SecretResult { - let new_ulid = ctx.change_set()?.generate_ulid()?; + async fn generate_key( + ctx: &DalContext, + secret_id: SecretId, + ) -> SecretResult { + let new_ulid = ctx.workspace_snapshot()?.generate_ulid().await?; let mut hasher = EncryptedSecretKey::hasher(); hasher.update(&ctx.tenancy().to_bytes()); @@ -596,7 +600,7 @@ impl Secret { algorithm: SecretAlgorithm, ) -> SecretResult { // Generate a new key and insert a new encrypted secret. - let new_key = Self::generate_key(ctx, self.id)?; + let new_key = Self::generate_key(ctx, self.id).await?; // NOTE(nick): we do not clean up the existing encrypted secret yet. EncryptedSecret::insert(ctx, new_key, crypted, key_pair_pk, version, algorithm).await?; @@ -648,8 +652,7 @@ impl Secret { workspace_snapshot .add_node(NodeWeight::Secret( - secret_node_weight - .new_with_incremented_vector_clock(ctx.change_set()?.vector_clock_id()), + secret_node_weight.new_with_incremented_vector_clock(ctx.vector_clock_id()?), )) .await?; @@ -671,7 +674,7 @@ impl Secret { ) .await?; ctx.workspace_snapshot()? - .update_content(ctx.change_set()?, secret.id.into(), hash) + .update_content(ctx.vector_clock_id()?, secret.id.into(), hash) .await?; } diff --git a/lib/dal/src/socket/input.rs b/lib/dal/src/socket/input.rs index bd7ceb5708..29a377f936 100644 --- a/lib/dal/src/socket/input.rs +++ b/lib/dal/src/socket/input.rs @@ -246,23 +246,25 @@ impl InputSocket { ) .await?; - let change_set = ctx.change_set()?; - let id = change_set.generate_ulid()?; + let workspace_snapshot = ctx.workspace_snapshot()?; + let id = workspace_snapshot.generate_ulid().await?; + let lineage_id = workspace_snapshot.generate_ulid().await?; - { - let workspace_snapshot = ctx.workspace_snapshot()?; - let node_weight = - NodeWeight::new_content(change_set, id, ContentAddress::InputSocket(hash))?; - workspace_snapshot.add_node(node_weight).await?; - SchemaVariant::add_edge_to_input_socket( - ctx, - schema_variant_id, - id.into(), - EdgeWeightKind::Socket, - ) - .await - .map_err(Box::new)?; - } + let node_weight = NodeWeight::new_content( + ctx.vector_clock_id()?, + id, + lineage_id, + ContentAddress::InputSocket(hash), + )?; + workspace_snapshot.add_node(node_weight).await?; + SchemaVariant::add_edge_to_input_socket( + ctx, + schema_variant_id, + id.into(), + EdgeWeightKind::Socket, + ) + .await + .map_err(Box::new)?; let attribute_prototype = AttributePrototype::new(ctx, func_id).await?; diff --git a/lib/dal/src/socket/output.rs b/lib/dal/src/socket/output.rs index 70297816f0..26af8a0e03 100644 --- a/lib/dal/src/socket/output.rs +++ b/lib/dal/src/socket/output.rs @@ -176,12 +176,17 @@ impl OutputSocket { ) .await?; - let change_set = ctx.change_set()?; - let id = change_set.generate_ulid()?; - let node_weight = - NodeWeight::new_content(change_set, id, ContentAddress::OutputSocket(hash))?; - let workspace_snapshot = ctx.workspace_snapshot()?; + + let id = workspace_snapshot.generate_ulid().await?; + let lineage_id = workspace_snapshot.generate_ulid().await?; + let node_weight = NodeWeight::new_content( + ctx.vector_clock_id()?, + id, + lineage_id, + ContentAddress::OutputSocket(hash), + )?; + workspace_snapshot.add_node(node_weight).await?; SchemaVariant::add_edge_to_output_socket( diff --git a/lib/dal/src/standard_connection.rs b/lib/dal/src/standard_connection.rs index fe922801ff..7e7fbb3d56 100644 --- a/lib/dal/src/standard_connection.rs +++ b/lib/dal/src/standard_connection.rs @@ -37,7 +37,7 @@ macro_rules! implement_add_edge_to { ctx.workspace_snapshot()? .add_edge( source_id, - $crate::EdgeWeight::new(ctx.change_set()?.vector_clock_id(), weight)?, + $crate::EdgeWeight::new(ctx.vector_clock_id()?, weight)?, destination_id, ) .await?; @@ -50,11 +50,13 @@ macro_rules! implement_add_edge_to { return Err($crate::HelperError::InvalidEdgeWeight(weight, $discriminant))?; } + let vector_clock_id = ctx.vector_clock_id()?; + ctx.workspace_snapshot()? .add_ordered_edge( - ctx.change_set()?.vector_clock_id(), + vector_clock_id, source_id, - $crate::EdgeWeight::new(ctx.change_set()?.vector_clock_id(), weight)?, + $crate::EdgeWeight::new(vector_clock_id, weight)?, destination_id ) .await?; diff --git a/lib/dal/src/validation.rs b/lib/dal/src/validation.rs index e9b2ff5ac3..26488576fe 100644 --- a/lib/dal/src/validation.rs +++ b/lib/dal/src/validation.rs @@ -159,7 +159,7 @@ impl ValidationOutputNode { .get_content_node_weight_of_kind(ContentAddressDiscriminants::ValidationOutput)?; let mut new_node_weight = - node_weight.new_with_incremented_vector_clock(ctx.change_set()?.vector_clock_id()); + node_weight.new_with_incremented_vector_clock(ctx.vector_clock_id()?); new_node_weight.new_content_hash(hash)?; @@ -170,19 +170,20 @@ impl ValidationOutputNode { id } else { - let change_set = ctx.change_set()?; - let id = change_set.generate_ulid()?; - let node_weight = - NodeWeight::new_content(change_set, id, ContentAddress::ValidationOutput(hash))?; + let id = workspace_snapshot.generate_ulid().await?; + let lineage_id = workspace_snapshot.generate_ulid().await?; + let node_weight = NodeWeight::new_content( + ctx.vector_clock_id()?, + id, + lineage_id, + ContentAddress::ValidationOutput(hash), + )?; workspace_snapshot.add_node(node_weight).await?; workspace_snapshot .add_edge( attribute_value_id, - EdgeWeight::new( - change_set.vector_clock_id(), - EdgeWeightKind::ValidationOutput, - )?, + EdgeWeight::new(ctx.vector_clock_id()?, EdgeWeightKind::ValidationOutput)?, id, ) .await?; @@ -236,6 +237,7 @@ impl ValidationOutputNode { attribute_value_id: AttributeValueId, ) -> ValidationResult<()> { let workspace_snapshot = ctx.workspace_snapshot()?; + let vector_clock_id = ctx.vector_clock_id()?; for validation_idx in workspace_snapshot .outgoing_targets_for_edge_weight_kind( @@ -249,7 +251,7 @@ impl ValidationOutputNode { .await? .id(); workspace_snapshot - .remove_node_by_id(ctx.change_set()?, validation_id) + .remove_node_by_id(vector_clock_id, validation_id) .await?; } diff --git a/lib/dal/src/workspace.rs b/lib/dal/src/workspace.rs index 71c1a42572..8784d666d4 100644 --- a/lib/dal/src/workspace.rs +++ b/lib/dal/src/workspace.rs @@ -3,7 +3,7 @@ use petgraph::Direction; use serde::{Deserialize, Serialize}; use si_data_nats::NatsError; use si_data_pg::{PgError, PgRow}; -use si_events::ContentHash; +use si_events::{ContentHash, VectorClockId}; use si_layer_cache::db::serialize; use si_layer_cache::LayerDbError; use si_pkg::{ @@ -171,8 +171,11 @@ impl Workspace { return Ok(()); } - let initial_change_set = ChangeSet::new_local()?; - let workspace_snapshot = WorkspaceSnapshot::initial(ctx, &initial_change_set).await?; + let initial_vector_clock_id = VectorClockId::new( + WorkspaceId::NONE.into_inner(), + WorkspaceId::NONE.into_inner(), + ); + let workspace_snapshot = WorkspaceSnapshot::initial(ctx, initial_vector_clock_id).await?; // If not, create the builtin workspace with a corresponding base change set and initial // workspace snapshot. @@ -520,10 +523,9 @@ impl Workspace { )?) }; - let local_change_set = ChangeSet::new_local()?; - let new_snap_address = imported_snapshot - .write(ctx, local_change_set.vector_clock_id()) - .await?; + // XXX: fake vector clock here. Figure out the right one + let vector_clock_id = VectorClockId::new(Ulid::new(), Ulid::new()); + let new_snap_address = imported_snapshot.write(ctx, vector_clock_id).await?; let new_change_set = ChangeSet::new( ctx, diff --git a/lib/dal/src/workspace_snapshot.rs b/lib/dal/src/workspace_snapshot.rs index 6bdd270168..430e6d9fbd 100644 --- a/lib/dal/src/workspace_snapshot.rs +++ b/lib/dal/src/workspace_snapshot.rs @@ -52,7 +52,7 @@ use crate::action::{Action, ActionError}; use crate::attribute::prototype::argument::{ AttributePrototypeArgument, AttributePrototypeArgumentError, AttributePrototypeArgumentId, }; -use crate::change_set::{ChangeSet, ChangeSetError, ChangeSetId}; +use crate::change_set::{ChangeSetError, ChangeSetId}; use crate::workspace_snapshot::edge_weight::{ EdgeWeight, EdgeWeightError, EdgeWeightKind, EdgeWeightKindDiscriminants, }; @@ -87,8 +87,8 @@ pub enum WorkspaceSnapshotError { AttributePrototypeArgument(#[from] Box), #[error("could not find category node of kind: {0:?}")] CategoryNodeNotFound(CategoryNodeKind), - #[error("change set error: {0}")] - ChangeSet(#[from] ChangeSetError), + // #[error("change set error: {0}")] + // ChangeSet(#[from] ChangeSetError), #[error("change set {0} has no workspace snapshot address")] ChangeSetMissingWorkspaceSnapshotAddress(ChangeSetId), #[error("edge weight error: {0}")] @@ -109,6 +109,8 @@ pub enum WorkspaceSnapshotError { Pg(#[from] PgError), #[error("postcard error: {0}")] Postcard(#[from] postcard::Error), + #[error("recently seen clocks missing for change set id {0}")] + RecentlySeenClocksMissing(ChangeSetId), #[error("serde json error: {0}")] SerdeJson(#[from] serde_json::Error), #[error("transactions error: {0}")] @@ -254,26 +256,22 @@ pub(crate) fn serde_value_to_string_type(value: &serde_json::Value) -> String { } impl WorkspaceSnapshot { - #[instrument( - name = "workspace_snapshot.initial", - level = "debug", - skip_all, - fields( - si.change_set.id = %change_set.id, - ) - )] + #[instrument(name = "workspace_snapshot.initial", level = "debug", skip_all)] pub async fn initial( ctx: &DalContext, - change_set: &ChangeSet, + vector_clock_id: VectorClockId, ) -> WorkspaceSnapshotResult { - let mut graph: WorkspaceSnapshotGraph = WorkspaceSnapshotGraph::new(change_set)?; + let mut graph: WorkspaceSnapshotGraph = WorkspaceSnapshotGraph::new(vector_clock_id)?; // Create the category nodes under root. for category_node_kind in CategoryNodeKind::iter() { - let category_node_index = graph.add_category_node(change_set, category_node_kind)?; + let id = graph.generate_ulid()?; + let lineage_id = graph.generate_ulid()?; + let category_node_index = + graph.add_category_node(vector_clock_id, id, lineage_id, category_node_kind)?; graph.add_edge( graph.root(), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use())?, + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use())?, category_node_index, )?; } @@ -288,11 +286,25 @@ impl WorkspaceSnapshot { dvu_roots: Arc::new(Mutex::new(HashSet::new())), }; - initial.write(ctx, change_set.vector_clock_id()).await?; + initial.write(ctx, vector_clock_id).await?; Ok(initial) } + pub async fn generate_ulid(&self) -> WorkspaceSnapshotResult { + Ok(self.working_copy_mut().await.generate_ulid()?) + } + + pub async fn max_recently_seen_clock_id_for_change_set( + &self, + change_set_id: ChangeSetId, + ) -> WorkspaceSnapshotResult> { + Ok(self + .working_copy() + .await + .max_recently_seen_clock_id_for_change_set(change_set_id)) + } + /// Enables cycle checks on calls to [`Self::add_edge`]. Does not force /// cycle checks for every [`WorkspaceSnapshotGrpah::add_edge`] operation if /// there is a consumer of [`WorkspaceSnapshotGraph`] that calls add_edge @@ -329,13 +341,6 @@ impl WorkspaceSnapshot { ctx: &DalContext, vector_clock_id: VectorClockId, ) -> WorkspaceSnapshotResult { - let open_change_set_clock_ids: Vec = ChangeSet::list_open(ctx) - .await? - .into_iter() - .map(|cs| cs.id.into_inner().into()) - .chain([vector_clock_id]) - .collect(); - // Pull out the working copy and clean it up. let new_address = { let self_clone = self.clone(); @@ -343,9 +348,10 @@ impl WorkspaceSnapshot { let mut working_copy = executor::block_on(self_clone.working_copy_mut()); working_copy.cleanup(); - working_copy.remove_vector_clock_entries(&open_change_set_clock_ids); + // working_copy.remove_vector_clock_entries(&open_change_set_clock_ids); // Mark everything left as seen. + info!("marking seen with: {:?}", vector_clock_id); working_copy.mark_graph_seen(vector_clock_id)?; Ok::<(), WorkspaceSnapshotGraphError>(()) @@ -456,13 +462,13 @@ impl WorkspaceSnapshot { )] pub async fn add_ordered_node( &self, - change_set: &ChangeSet, + vector_clock_id: VectorClockId, node: NodeWeight, ) -> WorkspaceSnapshotResult { let new_node_index = self .working_copy_mut() .await - .add_ordered_node(change_set, node)?; + .add_ordered_node(vector_clock_id, node)?; Ok(new_node_index) } @@ -474,14 +480,14 @@ impl WorkspaceSnapshot { )] pub async fn update_content( &self, - change_set: &ChangeSet, + vector_clock_id: VectorClockId, id: Ulid, new_content_hash: ContentHash, ) -> WorkspaceSnapshotResult<()> { Ok(self .working_copy_mut() .await - .update_content(change_set, id, new_content_hash)?) + .update_content(vector_clock_id, id, new_content_hash)?) } #[instrument( @@ -990,16 +996,16 @@ impl WorkspaceSnapshot { )] pub async fn remove_all_edges( &self, - change_set: &ChangeSet, + vector_clock_id: VectorClockId, id: impl Into, ) -> WorkspaceSnapshotResult<()> { let id = id.into(); for (edge_weight, source, target) in self.edges_directed(id, Direction::Outgoing).await? { - self.remove_edge(change_set, source, target, edge_weight.kind().into()) + self.remove_edge(vector_clock_id, source, target, edge_weight.kind().into()) .await?; } for (edge_weight, source, target) in self.edges_directed(id, Direction::Incoming).await? { - self.remove_edge(change_set, source, target, edge_weight.kind().into()) + self.remove_edge(vector_clock_id, source, target, edge_weight.kind().into()) .await?; } Ok(()) @@ -1141,7 +1147,7 @@ impl WorkspaceSnapshot { )] pub async fn remove_incoming_edges_of_kind( &self, - change_set: &ChangeSet, + vector_clock_id: VectorClockId, target_id: impl Into, kind: EdgeWeightKindDiscriminants, ) -> WorkspaceSnapshotResult<()> { @@ -1152,7 +1158,7 @@ impl WorkspaceSnapshot { .await?; for source_node_idx in sources { let target_node_idx = self.get_node_index_by_id(target_id).await?; - self.remove_edge(change_set, source_node_idx, target_node_idx, kind) + self.remove_edge(vector_clock_id, source_node_idx, target_node_idx, kind) .await?; } @@ -1190,12 +1196,12 @@ impl WorkspaceSnapshot { )] pub async fn remove_node_by_id( &self, - change_set: &ChangeSet, + vector_clock_id: VectorClockId, id: impl Into, ) -> WorkspaceSnapshotResult<()> { let id: Ulid = id.into(); let node_idx = self.get_node_index_by_id(id).await?; - self.remove_all_edges(change_set, id).await?; + self.remove_all_edges(vector_clock_id, id).await?; self.working_copy_mut().await.remove_node(node_idx); self.working_copy_mut().await.remove_node_id(id); @@ -1210,13 +1216,13 @@ impl WorkspaceSnapshot { )] pub async fn remove_edge( &self, - change_set: &ChangeSet, + vector_clock_id: VectorClockId, source_node_index: NodeIndex, target_node_index: NodeIndex, edge_kind: EdgeWeightKindDiscriminants, ) -> WorkspaceSnapshotResult<()> { Ok(self.working_copy_mut().await.remove_edge( - change_set, + vector_clock_id, source_node_index, target_node_index, edge_kind, @@ -1246,7 +1252,7 @@ impl WorkspaceSnapshot { )] pub async fn remove_edge_for_ulids( &self, - change_set: &ChangeSet, + vector_clock_id: VectorClockId, source_node_id: impl Into, target_node_id: impl Into, edge_kind: EdgeWeightKindDiscriminants, @@ -1259,8 +1265,13 @@ impl WorkspaceSnapshot { .working_copy() .await .get_node_index_by_id(target_node_id)?; - self.remove_edge(change_set, source_node_index, target_node_index, edge_kind) - .await + self.remove_edge( + vector_clock_id, + source_node_index, + target_node_index, + edge_kind, + ) + .await } /// Perform [`Updates`](Update) using [`self`](WorkspaceSnapshot) as the "to rebase" graph and @@ -1273,12 +1284,12 @@ impl WorkspaceSnapshot { )] pub async fn perform_updates( &self, - to_rebase_change_set: &ChangeSet, + to_rebase_vector_clock_id: VectorClockId, onto: &WorkspaceSnapshot, updates: &[Update], ) -> WorkspaceSnapshotResult<()> { Ok(self.working_copy_mut().await.perform_updates( - to_rebase_change_set, + to_rebase_vector_clock_id, &*onto.working_copy().await, updates, )?) @@ -1394,43 +1405,60 @@ impl WorkspaceSnapshot { // under. return Ok(new_component_ids); }; - let conflicts_and_updates = base_snapshot.read_only_graph.detect_conflicts_and_updates( - VectorClockId::from(Ulid::from(base_change_set_id)), - &self.read_only_graph, - VectorClockId::from(Ulid::from(ctx.change_set_id())), - )?; - for update in &conflicts_and_updates.updates { - match update { - Update::RemoveEdge { - source: _, - destination: _, - edge_kind: _, - } - | Update::ReplaceSubgraph { - onto: _, - to_rebase: _, - } - | Update::MergeCategoryNodes { - to_rebase_category_id: _, - onto_category_id: _, - } => { - /* Updates unused for determining if a Component is new with regards to the updates */ - } - Update::NewEdge { - source, - destination, - edge_weight: _, - } => { - if !(source.index == component_category_idx - && destination.node_weight_kind == NodeWeightDiscriminants::Component) - { - // We only care about new edges coming from the Component category node, - // and going to Component nodes, so keep looking. - continue; + let base_vector_clock_id = base_snapshot + .read_only_graph + .max_recently_seen_clock_id_for_change_set(base_change_set_id) + .ok_or(WorkspaceSnapshotError::RecentlySeenClocksMissing( + base_change_set_id, + ))?; + + // If there is no vector clock in this snapshot for the current change + // set, that's because the snapshot has *just* been forked from the base + // change set, and has not been written to yet + if let Some(change_set_vector_clock_id) = self + .read_only_graph + .max_recently_seen_clock_id_for_change_set(ctx.change_set_id()) + { + let conflicts_and_updates = + base_snapshot.read_only_graph.detect_conflicts_and_updates( + base_vector_clock_id, + &self.read_only_graph, + change_set_vector_clock_id, + )?; + + for update in &conflicts_and_updates.updates { + match update { + Update::RemoveEdge { + source: _, + destination: _, + edge_kind: _, + } + | Update::ReplaceSubgraph { + onto: _, + to_rebase: _, } + | Update::MergeCategoryNodes { + to_rebase_category_id: _, + onto_category_id: _, + } => { + /* Updates unused for determining if a Component is new with regards to the updates */ + } + Update::NewEdge { + source, + destination, + edge_weight: _, + } => { + if !(source.index == component_category_idx + && destination.node_weight_kind == NodeWeightDiscriminants::Component) + { + // We only care about new edges coming from the Component category node, + // and going to Component nodes, so keep looking. + continue; + } - new_component_ids.push(ComponentId::from(Ulid::from(destination.id))); + new_component_ids.push(ComponentId::from(Ulid::from(destination.id))); + } } } } @@ -1470,56 +1498,72 @@ impl WorkspaceSnapshot { } let base_snapshot = WorkspaceSnapshot::find_for_change_set(ctx, base_change_set_id).await?; - let conflicts_and_updates = base_snapshot.read_only_graph.detect_conflicts_and_updates( - VectorClockId::from(Ulid::from(base_change_set_id)), - &self.read_only_graph, - VectorClockId::from(Ulid::from(ctx.change_set_id())), - )?; + let base_vector_clock_id = base_snapshot + .read_only_graph + .max_recently_seen_clock_id_for_change_set(base_change_set_id) + .ok_or(WorkspaceSnapshotError::RecentlySeenClocksMissing( + base_change_set_id, + ))?; + + // If there is no vector clock in this snapshot for the current change + // set, that's because the snapshot has *just* been forked from the base + // change set, and has not been written to yet + if let Some(change_set_vector_clock_id) = self + .read_only_graph + .max_recently_seen_clock_id_for_change_set(ctx.change_set_id()) + { + let conflicts_and_updates = + base_snapshot.read_only_graph.detect_conflicts_and_updates( + base_vector_clock_id, + &self.read_only_graph, + change_set_vector_clock_id, + )?; - for update in &conflicts_and_updates.updates { - match update { - Update::RemoveEdge { - source: _, - destination: _, - edge_kind: _, - } - | Update::ReplaceSubgraph { - onto: _, - to_rebase: _, - } - | Update::MergeCategoryNodes { - to_rebase_category_id: _, - onto_category_id: _, - } => { - // Updates unused for determining if a socket to socket connection (in frontend - // terms) is new. - } - Update::NewEdge { - source: _source, - destination, - edge_weight: _, - } => { - if destination.node_weight_kind - != NodeWeightDiscriminants::AttributePrototypeArgument - { - // We're interested in new AttributePrototypeArguments as they represent - // the connection between sockets. (The input socket has the output - // socket as one of its function arguments.) - continue; + for update in &conflicts_and_updates.updates { + match update { + Update::RemoveEdge { + source: _, + destination: _, + edge_kind: _, } + | Update::ReplaceSubgraph { + onto: _, + to_rebase: _, + } + | Update::MergeCategoryNodes { + to_rebase_category_id: _, + onto_category_id: _, + } => { + // Updates unused for determining if a socket to socket connection (in frontend + // terms) is new. + } + Update::NewEdge { + source: _source, + destination, + edge_weight: _, + } => { + if destination.node_weight_kind + != NodeWeightDiscriminants::AttributePrototypeArgument + { + // We're interested in new AttributePrototypeArguments as they represent + // the connection between sockets. (The input socket has the output + // socket as one of its function arguments.) + continue; + } - let prototype_argument = AttributePrototypeArgument::get_by_id( - ctx, - AttributePrototypeArgumentId::from(Ulid::from(destination.id)), - ) - .await - .map_err(Box::new)?; - if prototype_argument.targets().is_some() { - new_attribute_prototype_argument_ids.push(prototype_argument.id()); - } else { - // If the AttributePrototypeArgument doesn't have targets, then it's - // not for a socket to socket connection. - continue; + let prototype_argument = AttributePrototypeArgument::get_by_id( + ctx, + AttributePrototypeArgumentId::from(Ulid::from(destination.id)), + ) + .await + .map_err(Box::new)?; + if prototype_argument.targets().is_some() { + new_attribute_prototype_argument_ids.push(prototype_argument.id()); + } else { + // If the AttributePrototypeArgument doesn't have targets, then it's + // not for a socket to socket connection. + continue; + } } } } @@ -1543,7 +1587,7 @@ impl WorkspaceSnapshot { async fn find_existing_dependent_value_root( &self, - change_set: &ChangeSet, + vector_clock_id: VectorClockId, value_id: Ulid, ) -> WorkspaceSnapshotResult<(Ulid, Option)> { let dv_category_id = match self @@ -1554,11 +1598,17 @@ impl WorkspaceSnapshot { None => { let mut working_copy = self.working_copy_mut().await; let root_idx = working_copy.root(); - let category_node_idx = working_copy - .add_category_node(change_set, CategoryNodeKind::DependentValueRoots)?; + let id = working_copy.generate_ulid()?; + let lineage_id = working_copy.generate_ulid()?; + let category_node_idx = working_copy.add_category_node( + vector_clock_id, + id, + lineage_id, + CategoryNodeKind::DependentValueRoots, + )?; working_copy.add_edge( root_idx, - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use())?, + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use())?, category_node_idx, )?; @@ -1585,7 +1635,7 @@ impl WorkspaceSnapshot { pub async fn add_dependent_value_root( &self, - change_set: &ChangeSet, + vector_clock_id: VectorClockId, value_id: impl Into, ) -> WorkspaceSnapshotResult<()> { let value_id = value_id.into(); @@ -1601,16 +1651,20 @@ impl WorkspaceSnapshot { } let (dv_category_id, _) = self - .find_existing_dependent_value_root(change_set, value_id) + .find_existing_dependent_value_root(vector_clock_id, value_id) .await?; - let new_dependent_value_node = NodeWeight::new_dependent_value_root(change_set, value_id)?; + let id = self.generate_ulid().await?; + let lineage_id = self.generate_ulid().await?; + + let new_dependent_value_node = + NodeWeight::new_dependent_value_root(vector_clock_id, id, lineage_id, value_id)?; let new_dv_node_id = new_dependent_value_node.id(); self.add_node(new_dependent_value_node).await?; self.add_edge( dv_category_id, - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use())?, + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use())?, new_dv_node_id, ) .await?; @@ -1620,16 +1674,16 @@ impl WorkspaceSnapshot { pub async fn remove_dependent_value_root( &self, - change_set: &ChangeSet, + vector_clock_id: VectorClockId, value_id: impl Into, ) -> WorkspaceSnapshotResult<()> { let value_id = value_id.into(); let (_, existing_value_id) = self - .find_existing_dependent_value_root(change_set, value_id) + .find_existing_dependent_value_root(vector_clock_id, value_id) .await?; if let Some(existing_id) = existing_value_id { - self.remove_node_by_id(change_set, existing_id).await?; + self.remove_node_by_id(vector_clock_id, existing_id).await?; } Ok(()) @@ -1656,7 +1710,7 @@ impl WorkspaceSnapshot { /// Removes all the dependent value nodes from the category and returns the value_ids pub async fn take_dependent_values( &self, - change_set: &ChangeSet, + vector_clock_id: VectorClockId, ) -> WorkspaceSnapshotResult> { let dv_category_id = match self .get_category_node(None, CategoryNodeKind::DependentValueRoots) @@ -1684,7 +1738,8 @@ impl WorkspaceSnapshot { } for to_remove_id in pending_removes { - self.remove_node_by_id(change_set, to_remove_id).await?; + self.remove_node_by_id(vector_clock_id, to_remove_id) + .await?; } Ok(value_ids) diff --git a/lib/dal/src/workspace_snapshot/graph.rs b/lib/dal/src/workspace_snapshot/graph.rs index b6c5b64a30..47f374a736 100644 --- a/lib/dal/src/workspace_snapshot/graph.rs +++ b/lib/dal/src/workspace_snapshot/graph.rs @@ -1,6 +1,7 @@ use std::collections::{HashMap, HashSet, VecDeque}; use std::fs::File; use std::io::Write; +use std::sync::{Arc, Mutex}; use chrono::Utc; /// Ensure [`NodeIndex`] is usable by external crates. @@ -14,8 +15,8 @@ use si_events::{ulid::Ulid, ContentHash}; use thiserror::Error; use telemetry::prelude::*; +use ulid::Generator; -use crate::change_set::{ChangeSet, ChangeSetError}; use crate::workspace_snapshot::content_address::ContentAddressDiscriminants; use crate::workspace_snapshot::node_weight::category_node_weight::CategoryNodeKind; use crate::workspace_snapshot::node_weight::{CategoryNodeWeight, NodeWeightDiscriminants}; @@ -28,6 +29,7 @@ use crate::workspace_snapshot::{ update::Update, NodeInformation, }; +use crate::ChangeSetId; use super::edge_weight::DeprecatedEdgeWeight; @@ -41,8 +43,8 @@ pub type LineageId = Ulid; pub enum WorkspaceSnapshotGraphError { #[error("Cannot compare ordering of container elements between ordered, and un-ordered container: {0:?}, {1:?}")] CannotCompareOrderedAndUnorderedContainers(NodeIndex, NodeIndex), - #[error("ChangeSet error: {0}")] - ChangeSet(#[from] ChangeSetError), + // #[error("ChangeSet error: {0}")] + // ChangeSet(#[from] ChangeSetError), #[error("Unable to retrieve content for ContentHash")] ContentMissingForContentHash, #[error("Action would create a graph cycle")] @@ -61,6 +63,10 @@ pub enum WorkspaceSnapshotGraphError { IncompatibleNodeTypes, #[error("Invalid value graph")] InvalidValueGraph, + #[error("monotonic error: {0}")] + Monotonic(#[from] ulid::MonotonicError), + #[error("mutex poisoning: {0}")] + MutexPoison(String), #[error("NodeWeight error: {0}")] NodeWeight(#[from] NodeWeightError), #[error("node weight not found")] @@ -87,6 +93,9 @@ pub struct WorkspaceSnapshotGraph { node_index_by_id: HashMap, node_indices_by_lineage_id: HashMap>, root_index: NodeIndex, + + #[serde(skip)] + ulid_generator: Arc>, } #[derive(Default, Deserialize, Serialize, Clone)] @@ -175,6 +184,7 @@ impl From for WorkspaceSnapshotGraph { node_index_by_id, node_indices_by_lineage_id, root_index, + ulid_generator: Arc::new(Mutex::new(Generator::new())), } } } @@ -190,12 +200,14 @@ impl std::fmt::Debug for WorkspaceSnapshotGraph { } impl WorkspaceSnapshotGraph { - pub fn new(change_set: &ChangeSet) -> WorkspaceSnapshotGraphResult { + pub fn new(vector_clock_id: VectorClockId) -> WorkspaceSnapshotGraphResult { let mut graph: StableDiGraph = StableDiGraph::with_capacity(1024, 1024); + let mut generator = Generator::new(); let root_node = NodeWeight::new_content( - change_set, - change_set.generate_ulid()?, + vector_clock_id, + generator.generate()?.into(), + generator.generate()?.into(), ContentAddress::Root, )?; @@ -206,6 +218,7 @@ impl WorkspaceSnapshotGraph { let mut result = Self { root_index, graph, + ulid_generator: Arc::new(Mutex::new(generator)), ..Default::default() }; @@ -223,6 +236,29 @@ impl WorkspaceSnapshotGraph { &self.graph } + pub fn generate_ulid(&self) -> WorkspaceSnapshotGraphResult { + Ok(self + .ulid_generator + .lock() + .map_err(|e| WorkspaceSnapshotGraphError::MutexPoison(e.to_string()))? + .generate()? + .into()) + } + + pub fn max_recently_seen_clock_id_for_change_set( + &self, + change_set_id: ChangeSetId, + ) -> Option { + self.graph + .node_weight(self.root()) + .and_then(|root_node| { + root_node + .vector_clock_recently_seen() + .max_for_change_set_id(change_set_id) + }) + .map(|(clock_id, _)| clock_id) + } + pub fn get_latest_node_idx_opt( &self, node_idx: NodeIndex, @@ -369,10 +405,12 @@ impl WorkspaceSnapshotGraph { pub fn add_category_node( &mut self, - change_set: &ChangeSet, + vector_clock_id: VectorClockId, + id: Ulid, + lineage_id: Ulid, kind: CategoryNodeKind, ) -> WorkspaceSnapshotGraphResult { - let inner_weight = CategoryNodeWeight::new(change_set, kind)?; + let inner_weight = CategoryNodeWeight::new(id, lineage_id, vector_clock_id, kind)?; let new_node_index = self.add_node(NodeWeight::Category(inner_weight))?; Ok(new_node_index) } @@ -520,15 +558,22 @@ impl WorkspaceSnapshotGraph { pub fn add_ordered_node( &mut self, - change_set: &ChangeSet, + vector_clock_id: VectorClockId, node: NodeWeight, ) -> WorkspaceSnapshotGraphResult { let new_node_index = self.add_node(node)?; - let ordering_node_index = - self.add_node(NodeWeight::Ordering(OrderingNodeWeight::new(change_set)?))?; + + let ordering_node_id = self.generate_ulid()?; + let ordering_node_lineage_id = self.generate_ulid()?; + let ordering_node_index = self.add_node(NodeWeight::Ordering(OrderingNodeWeight::new( + ordering_node_id, + ordering_node_lineage_id, + vector_clock_id, + )?))?; + let edge_index = self.add_edge( new_node_index, - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::Ordering)?, + EdgeWeight::new(vector_clock_id, EdgeWeightKind::Ordering)?, ordering_node_index, )?; let (source, _) = self.edge_endpoints(edge_index)?; @@ -1079,6 +1124,7 @@ impl WorkspaceSnapshotGraph { node_index_by_id, node_indices_by_lineage_id, root_index: new_root?, + ..Default::default() }) } @@ -1802,7 +1848,7 @@ impl WorkspaceSnapshotGraph { /// [`Self::cleanup()`] has run should be considered invalid. pub(crate) fn remove_edge( &mut self, - change_set: &ChangeSet, + vector_clock_id: VectorClockId, source_node_index: NodeIndex, target_node_index: NodeIndex, edge_kind: EdgeWeightKindDiscriminants, @@ -1833,7 +1879,7 @@ impl WorkspaceSnapshotGraph { // We only want to update the ordering of the container if we removed an edge to // one of the ordered relationships. if new_container_ordering_node_weight - .remove_from_order(change_set.vector_clock_id(), element_id)? + .remove_from_order(vector_clock_id, element_id)? { self.inner_remove_edge( previous_container_ordering_node_index, @@ -1965,14 +2011,14 @@ impl WorkspaceSnapshotGraph { pub fn update_content( &mut self, - change_set: &ChangeSet, + vector_clock_id: VectorClockId, id: Ulid, new_content_hash: ContentHash, ) -> WorkspaceSnapshotGraphResult<()> { let original_node_index = self.get_node_index_by_id(id)?; let new_node_index = self.copy_node_by_index(original_node_index)?; let node_weight = self.get_node_weight_mut(new_node_index)?; - node_weight.increment_vector_clocks(change_set.vector_clock_id()); + node_weight.increment_vector_clocks(vector_clock_id); node_weight.new_content_hash(new_content_hash)?; self.replace_references(original_node_index)?; @@ -2104,7 +2150,7 @@ impl WorkspaceSnapshotGraph { /// and a provided graph as the "onto" graph. pub fn perform_updates( &mut self, - to_rebase_change_set: &ChangeSet, + to_rebase_vector_clock_id: VectorClockId, onto: &WorkspaceSnapshotGraph, updates: &[Update], ) -> WorkspaceSnapshotGraphResult<()> { @@ -2129,7 +2175,7 @@ impl WorkspaceSnapshotGraph { let updated_source = self.get_latest_node_idx(source.index)?; let destination = self.get_latest_node_idx(destination.index)?; self.remove_edge( - to_rebase_change_set, + to_rebase_vector_clock_id, updated_source, destination, *edge_kind, diff --git a/lib/dal/src/workspace_snapshot/graph/tests.rs b/lib/dal/src/workspace_snapshot/graph/tests.rs index 7fc74aff1a..ff8b8ea0c0 100644 --- a/lib/dal/src/workspace_snapshot/graph/tests.rs +++ b/lib/dal/src/workspace_snapshot/graph/tests.rs @@ -1,9 +1,9 @@ use std::collections::HashMap; -use si_events::{ulid::Ulid, ContentHash}; +use si_events::{ulid::Ulid, ContentHash, VectorClockId}; use crate::{ - workspace_snapshot::node_weight::NodeWeight, ChangeSet, EdgeWeight, EdgeWeightKind, PropKind, + workspace_snapshot::node_weight::NodeWeight, EdgeWeight, EdgeWeightKind, PropKind, WorkspaceSnapshotGraph, }; @@ -14,17 +14,19 @@ mod rebase; #[allow(dead_code)] fn add_prop_nodes_to_graph<'a, 'b>( graph: &'a mut WorkspaceSnapshotGraph, - change_set: &'a ChangeSet, + vector_clock_id: VectorClockId, nodes: &'a [&'b str], ) -> HashMap<&'b str, Ulid> { let mut node_id_map = HashMap::new(); for node in nodes { // "props" here are just nodes that are easy to create and render the name on the dot // output. there is no domain modeling in this test. - let node_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let node_id = graph.generate_ulid().expect("Unable to generate Ulid"); + let node_lineage_id = graph.generate_ulid().expect("Unable to generate Ulid"); let prop_node_weight = NodeWeight::new_prop( - change_set, + vector_clock_id, node_id, + node_lineage_id, PropKind::Object, node, ContentHash::new(node.as_bytes()), @@ -43,7 +45,7 @@ fn add_prop_nodes_to_graph<'a, 'b>( fn add_edges( graph: &mut WorkspaceSnapshotGraph, node_id_map: &HashMap<&str, Ulid>, - change_set: &ChangeSet, + vector_clock_id: VectorClockId, edges: &[(Option<&str>, &str)], ) { for (source, target) in edges { @@ -71,7 +73,7 @@ fn add_edges( graph .add_edge( source, - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("create edge weight"), target, ) @@ -87,11 +89,11 @@ mod test { use petgraph::Outgoing; use pretty_assertions_sorted::assert_eq; use si_events::merkle_tree_hash::MerkleTreeHash; - use si_events::ContentHash; + use si_events::ulid::Ulid; + use si_events::{ContentHash, VectorClockId}; use std::collections::HashSet; use std::str::FromStr; - use crate::change_set::ChangeSet; use crate::workspace_snapshot::content_address::ContentAddress; use crate::workspace_snapshot::edge_weight::{ EdgeWeight, EdgeWeightKind, EdgeWeightKindDiscriminants, @@ -107,9 +109,8 @@ mod test { #[test] fn new() { - let change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let change_set = &change_set; - let graph = WorkspaceSnapshotGraph::new(change_set) + let vector_clock_id = VectorClockId::new(Ulid::new(), Ulid::new()); + let graph = WorkspaceSnapshotGraph::new(vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); assert!(graph.is_acyclic_directed()); } @@ -119,9 +120,8 @@ mod test { // on a fresh graph (like add_ordered_node) #[test] fn get_root_index_by_root_id_on_fresh_graph() { - let base_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let active_change_set = &base_change_set; - let graph = WorkspaceSnapshotGraph::new(active_change_set) + let vector_clock_id = VectorClockId::new(Ulid::new(), Ulid::new()); + let graph = WorkspaceSnapshotGraph::new(vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); let root_id = graph @@ -180,13 +180,13 @@ mod test { (Some("a"), "b"), ]; - let change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let change_set = &change_set; - let mut graph = WorkspaceSnapshotGraph::new(change_set) + let vector_clock_id = VectorClockId::new(Ulid::new(), Ulid::new()); + + let mut graph = WorkspaceSnapshotGraph::new(vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); - let node_id_map = add_prop_nodes_to_graph(&mut graph, change_set, &nodes); - add_edges(&mut graph, &node_id_map, change_set, &edges); + let node_id_map = add_prop_nodes_to_graph(&mut graph, vector_clock_id, &nodes); + add_edges(&mut graph, &node_id_map, vector_clock_id, &edges); graph.cleanup(); @@ -238,17 +238,18 @@ mod test { #[test] fn add_nodes_and_edges() { - let change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let change_set = &change_set; - let mut graph = WorkspaceSnapshotGraph::new(change_set) + let actor_a = Ulid::new(); + let vector_clock_id = VectorClockId::new(Ulid::new(), actor_a); + let mut graph = WorkspaceSnapshotGraph::new(vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); - let schema_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let schema_id = graph.generate_ulid().expect("Unable to generate Ulid"); let schema_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, schema_id, + Ulid::new(), ContentAddress::Schema(ContentHash::new( SchemaId::generate().to_string().as_bytes(), )), @@ -256,12 +257,13 @@ mod test { .expect("Unable to create NodeWeight"), ) .expect("Unable to add schema"); - let schema_variant_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let schema_variant_id = graph.generate_ulid().expect("Unable to generate Ulid"); let schema_variant_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, schema_variant_id, + Ulid::new(), ContentAddress::SchemaVariant(ContentHash::new( SchemaVariantId::generate().to_string().as_bytes(), )), @@ -269,12 +271,13 @@ mod test { .expect("Unable to create NodeWeight"), ) .expect("Unable to add schema variant"); - let component_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let component_id = graph.generate_ulid().expect("Unable to generate Ulid"); let component_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, component_id, + Ulid::new(), ContentAddress::Component(ContentHash::new( ComponentId::generate().to_string().as_bytes(), )), @@ -286,7 +289,7 @@ mod test { graph .add_edge( graph.root_index, - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), component_index, ) @@ -294,7 +297,7 @@ mod test { graph .add_edge( graph.root_index, - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), schema_index, ) @@ -304,7 +307,7 @@ mod test { graph .get_node_index_by_id(schema_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), schema_variant_index, ) @@ -314,7 +317,7 @@ mod test { graph .get_node_index_by_id(component_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), graph .get_node_index_by_id(schema_variant_id) @@ -322,12 +325,13 @@ mod test { ) .expect("Unable to add component -> schema variant edge"); - let func_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let func_id = graph.generate_ulid().expect("Unable to generate Ulid"); let func_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, func_id, + Ulid::new(), ContentAddress::Func(ContentHash::new( FuncId::generate().to_string().as_bytes(), )), @@ -335,12 +339,13 @@ mod test { .expect("Unable to create NodeWeight"), ) .expect("Unable to add func"); - let prop_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let prop_id = graph.generate_ulid().expect("Unable to generate Ulid"); let prop_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, prop_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( PropId::generate().to_string().as_bytes(), )), @@ -352,7 +357,7 @@ mod test { graph .add_edge( graph.root_index, - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), func_index, ) @@ -362,7 +367,7 @@ mod test { graph .get_node_index_by_id(schema_variant_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), prop_index, ) @@ -372,7 +377,7 @@ mod test { graph .get_node_index_by_id(prop_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), graph .get_node_index_by_id(func_id) @@ -385,17 +390,17 @@ mod test { #[test] fn cyclic_failure() { - let change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let change_set = &change_set; - let mut graph = WorkspaceSnapshotGraph::new(change_set) + let vector_clock_id = VectorClockId::new(Ulid::new(), Ulid::new()); + let mut graph = WorkspaceSnapshotGraph::new(vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); - let schema_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let schema_id = graph.generate_ulid().expect("Unable to generate Ulid"); let initial_schema_node_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, schema_id, + Ulid::new(), ContentAddress::Schema(ContentHash::new( SchemaId::generate().to_string().as_bytes(), )), @@ -403,12 +408,13 @@ mod test { .expect("Unable to create NodeWeight"), ) .expect("Unable to add schema"); - let schema_variant_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let schema_variant_id = graph.generate_ulid().expect("Unable to generate Ulid"); let initial_schema_variant_node_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, schema_variant_id, + Ulid::new(), ContentAddress::SchemaVariant(ContentHash::new( SchemaVariantId::generate().to_string().as_bytes(), )), @@ -416,12 +422,13 @@ mod test { .expect("Unable to create NodeWeight"), ) .expect("Unable to add schema variant"); - let component_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let component_id = graph.generate_ulid().expect("Unable to generate Ulid"); let initial_component_node_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, component_id, + Ulid::new(), ContentAddress::Component(ContentHash::new( ComponentId::generate().to_string().as_bytes(), )), @@ -433,7 +440,7 @@ mod test { graph .add_edge( graph.root_index, - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), initial_component_node_index, ) @@ -441,7 +448,7 @@ mod test { graph .add_edge( graph.root_index, - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), initial_schema_node_index, ) @@ -451,7 +458,7 @@ mod test { graph .get_node_index_by_id(schema_id) .expect("Unable to find NodeIndex"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), initial_schema_variant_node_index, ) @@ -461,7 +468,7 @@ mod test { graph .get_node_index_by_id(component_id) .expect("Unable to find NodeIndex"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), graph .get_node_index_by_id(schema_variant_id) @@ -477,7 +484,7 @@ mod test { graph .get_node_index_by_id(schema_variant_id) .expect("Unable to find NodeIndex"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), graph .get_node_index_by_id(component_id) @@ -490,28 +497,29 @@ mod test { #[test] fn update_content() { - let change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let change_set = &change_set; - let mut graph = WorkspaceSnapshotGraph::new(change_set) + let vector_clock_id = VectorClockId::new(Ulid::new(), Ulid::new()); + let mut graph = WorkspaceSnapshotGraph::new(vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); - let schema_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let schema_id = graph.generate_ulid().expect("Unable to generate Ulid"); let schema_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, schema_id, + Ulid::new(), ContentAddress::Schema(ContentHash::from("Constellation")), ) .expect("Unable to create NodeWeight"), ) .expect("Unable to add schema"); - let schema_variant_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let schema_variant_id = graph.generate_ulid().expect("Unable to generate Ulid"); let schema_variant_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, schema_variant_id, + Ulid::new(), ContentAddress::SchemaVariant(ContentHash::new( "Freestar Collective".as_bytes(), )), @@ -519,12 +527,13 @@ mod test { .expect("Unable to create NodeWeight"), ) .expect("Unable to add schema variant"); - let component_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let component_id = graph.generate_ulid().expect("Unable to generate Ulid"); let component_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, component_id, + Ulid::new(), ContentAddress::Component(ContentHash::from("Crimson Fleet")), ) .expect("Unable to create NodeWeight"), @@ -534,7 +543,7 @@ mod test { graph .add_edge( graph.root_index, - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), component_index, ) @@ -542,7 +551,7 @@ mod test { graph .add_edge( graph.root_index, - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), schema_index, ) @@ -552,7 +561,7 @@ mod test { graph .get_node_index_by_id(schema_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), schema_variant_index, ) @@ -562,7 +571,7 @@ mod test { graph .get_node_index_by_id(component_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), graph .get_node_index_by_id(schema_variant_id) @@ -584,7 +593,7 @@ mod test { let updated_content_hash = ContentHash::from("new_content"); graph - .update_content(change_set, component_id, updated_content_hash) + .update_content(vector_clock_id, component_id, updated_content_hash) .expect("Unable to update Component content hash"); let post_update_root_node_merkle_tree_hash: MerkleTreeHash = @@ -637,17 +646,17 @@ mod test { #[test] fn add_ordered_node() { - let change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let change_set = &change_set; - let mut graph = WorkspaceSnapshotGraph::new(change_set) + let vector_clock_id = VectorClockId::new(Ulid::new(), Ulid::new()); + let mut graph = WorkspaceSnapshotGraph::new(vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); - let schema_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let schema_id = graph.generate_ulid().expect("Unable to generate Ulid"); let schema_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, schema_id, + Ulid::new(), ContentAddress::Schema(ContentHash::new( SchemaId::generate().to_string().as_bytes(), )), @@ -655,12 +664,13 @@ mod test { .expect("Unable to create NodeWeight"), ) .expect("Unable to add schema"); - let schema_variant_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let schema_variant_id = graph.generate_ulid().expect("Unable to generate Ulid"); let schema_variant_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, schema_variant_id, + Ulid::new(), ContentAddress::SchemaVariant(ContentHash::new( SchemaVariantId::generate().to_string().as_bytes(), )), @@ -672,7 +682,7 @@ mod test { graph .add_edge( graph.root_index, - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), schema_index, ) @@ -682,18 +692,19 @@ mod test { graph .get_node_index_by_id(schema_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), schema_variant_index, ) .expect("Unable to add schema -> schema variant edge"); - let func_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let func_id = graph.generate_ulid().expect("Unable to generate Ulid"); let func_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, func_id, + Ulid::new(), ContentAddress::Func(ContentHash::new( FuncId::generate().to_string().as_bytes(), )), @@ -704,19 +715,20 @@ mod test { graph .add_edge( graph.root_index, - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), func_index, ) .expect("Unable to add root -> func edge"); - let prop_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let prop_id = graph.generate_ulid().expect("Unable to generate Ulid"); let prop_index = graph .add_ordered_node( - change_set, + vector_clock_id, NodeWeight::new_content( - change_set, + vector_clock_id, prop_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( PropId::generate().to_string().as_bytes(), )), @@ -729,7 +741,7 @@ mod test { graph .get_node_index_by_id(schema_variant_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), prop_index, ) @@ -739,7 +751,7 @@ mod test { graph .get_node_index_by_id(prop_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), graph .get_node_index_by_id(func_id) @@ -749,12 +761,13 @@ mod test { graph.cleanup(); graph.dot(); - let ordered_prop_1_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let ordered_prop_1_id = graph.generate_ulid().expect("Unable to generate Ulid"); let ordered_prop_1_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, ordered_prop_1_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_1_id.to_string().as_bytes(), )), @@ -764,22 +777,23 @@ mod test { .expect("Unable to add ordered prop"); graph .add_ordered_edge( - change_set.vector_clock_id(), + vector_clock_id, graph .get_node_index_by_id(prop_id) .expect("Unable to get NodeWeight for prop"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create uses edge weight"), ordered_prop_1_index, ) .expect("Unable to add prop -> ordered_prop_1 edge"); - let ordered_prop_2_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let ordered_prop_2_id = graph.generate_ulid().expect("Unable to generate Ulid"); let ordered_prop_2_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, ordered_prop_2_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_2_id.to_string().as_bytes(), )), @@ -789,22 +803,23 @@ mod test { .expect("Unable to add ordered prop"); graph .add_ordered_edge( - change_set.vector_clock_id(), + vector_clock_id, graph .get_node_index_by_id(prop_id) .expect("Unable to get NodeWeight for prop"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create uses edge weight"), ordered_prop_2_index, ) .expect("Unable to add prop -> ordered_prop_2 edge"); - let ordered_prop_3_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let ordered_prop_3_id = graph.generate_ulid().expect("Unable to generate Ulid"); let ordered_prop_3_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, ordered_prop_3_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_3_id.to_string().as_bytes(), )), @@ -814,11 +829,11 @@ mod test { .expect("Unable to add ordered prop"); graph .add_ordered_edge( - change_set.vector_clock_id(), + vector_clock_id, graph .get_node_index_by_id(prop_id) .expect("Unable to get NodeWeight for prop"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create uses edge weight"), ordered_prop_3_index, ) @@ -845,20 +860,19 @@ mod test { #[test] fn add_ordered_node_below_root() { - let base_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let active_change_set = &base_change_set; - let mut graph = WorkspaceSnapshotGraph::new(active_change_set) + let active_vector_clock_id = VectorClockId::new(Ulid::new(), Ulid::new()); + + let mut graph = WorkspaceSnapshotGraph::new(active_vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); - let prop_id = active_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let prop_id = graph.generate_ulid().expect("Unable to generate Ulid"); let prop_index = graph .add_ordered_node( - active_change_set, + active_vector_clock_id, NodeWeight::new_content( - active_change_set, + active_vector_clock_id, prop_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new(prop_id.to_string().as_bytes())), ) .expect("Unable to create NodeWeight"), @@ -868,11 +882,8 @@ mod test { graph .add_edge( graph.root_index, - EdgeWeight::new( - active_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(active_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), prop_index, ) .expect("Unable to add root -> prop edge"); @@ -893,17 +904,18 @@ mod test { #[test] fn reorder_ordered_node() { - let change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let change_set = &change_set; - let mut graph = WorkspaceSnapshotGraph::new(change_set) + let vector_clock_id = VectorClockId::new(Ulid::new(), Ulid::new()); + + let mut graph = WorkspaceSnapshotGraph::new(vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); - let schema_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let schema_id = graph.generate_ulid().expect("Unable to generate Ulid"); let schema_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, schema_id, + Ulid::new(), ContentAddress::Schema(ContentHash::new( SchemaId::generate().to_string().as_bytes(), )), @@ -911,12 +923,13 @@ mod test { .expect("Unable to create NodeWeight"), ) .expect("Unable to add schema"); - let schema_variant_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let schema_variant_id = graph.generate_ulid().expect("Unable to generate Ulid"); let schema_variant_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, schema_variant_id, + Ulid::new(), ContentAddress::SchemaVariant(ContentHash::new( SchemaVariantId::generate().to_string().as_bytes(), )), @@ -928,7 +941,7 @@ mod test { graph .add_edge( graph.root_index, - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), schema_index, ) @@ -938,18 +951,19 @@ mod test { graph .get_node_index_by_id(schema_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), schema_variant_index, ) .expect("Unable to add schema -> schema variant edge"); - let func_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let func_id = graph.generate_ulid().expect("Unable to generate Ulid"); let func_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, func_id, + Ulid::new(), ContentAddress::Func(ContentHash::new( FuncId::generate().to_string().as_bytes(), )), @@ -960,19 +974,20 @@ mod test { graph .add_edge( graph.root_index, - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), func_index, ) .expect("Unable to add root -> func edge"); - let prop_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let prop_id = graph.generate_ulid().expect("Unable to generate Ulid"); let prop_index = graph .add_ordered_node( - change_set, + vector_clock_id, NodeWeight::new_content( - change_set, + vector_clock_id, prop_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( PropId::generate().to_string().as_bytes(), )), @@ -985,7 +1000,7 @@ mod test { graph .get_node_index_by_id(schema_variant_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), prop_index, ) @@ -995,7 +1010,7 @@ mod test { graph .get_node_index_by_id(prop_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), graph .get_node_index_by_id(func_id) @@ -1005,12 +1020,13 @@ mod test { graph.cleanup(); graph.dot(); - let ordered_prop_1_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let ordered_prop_1_id = graph.generate_ulid().expect("Unable to generate Ulid"); let ordered_prop_1_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, ordered_prop_1_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_1_id.to_string().as_bytes(), )), @@ -1020,22 +1036,23 @@ mod test { .expect("Unable to add ordered prop"); graph .add_ordered_edge( - change_set.vector_clock_id(), + vector_clock_id, graph .get_node_index_by_id(prop_id) .expect("Unable to get NodeWeight for prop"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create uses edge weight"), ordered_prop_1_index, ) .expect("Unable to add prop -> ordered_prop_1 edge"); - let ordered_prop_2_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let ordered_prop_2_id = graph.generate_ulid().expect("Unable to generate Ulid"); let ordered_prop_2_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, ordered_prop_2_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_2_id.to_string().as_bytes(), )), @@ -1045,22 +1062,23 @@ mod test { .expect("Unable to add ordered prop"); graph .add_ordered_edge( - change_set.vector_clock_id(), + vector_clock_id, graph .get_node_index_by_id(prop_id) .expect("Unable to get NodeWeight for prop"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create uses edge weight"), ordered_prop_2_index, ) .expect("Unable to add prop -> ordered_prop_2 edge"); - let ordered_prop_3_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let ordered_prop_3_id = graph.generate_ulid().expect("Unable to generate Ulid"); let ordered_prop_3_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, ordered_prop_3_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_3_id.to_string().as_bytes(), )), @@ -1070,22 +1088,23 @@ mod test { .expect("Unable to add ordered prop"); graph .add_ordered_edge( - change_set.vector_clock_id(), + vector_clock_id, graph .get_node_index_by_id(prop_id) .expect("Unable to get NodeWeight for prop"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create uses edge weight"), ordered_prop_3_index, ) .expect("Unable to add prop -> ordered_prop_3 edge"); - let ordered_prop_4_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let ordered_prop_4_id = graph.generate_ulid().expect("Unable to generate Ulid"); let ordered_prop_4_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, ordered_prop_4_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_4_id.to_string().as_bytes(), )), @@ -1095,11 +1114,11 @@ mod test { .expect("Unable to add ordered prop"); graph .add_ordered_edge( - change_set.vector_clock_id(), + vector_clock_id, graph .get_node_index_by_id(prop_id) .expect("Unable to get NodeWeight for prop"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create uses edge weight"), ordered_prop_4_index, ) @@ -1133,7 +1152,7 @@ mod test { ]; graph - .update_order(change_set.vector_clock_id(), prop_id, new_order) + .update_order(vector_clock_id, prop_id, new_order) .expect("Unable to update order of prop's children"); assert_eq!( @@ -1156,19 +1175,18 @@ mod test { #[test] fn remove_unordered_node_and_detect_edge_removal() { - let initial_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let initial_change_set = &initial_change_set; - let mut graph = WorkspaceSnapshotGraph::new(initial_change_set) + let initial_vector_clock_id = VectorClockId::new(Ulid::new(), Ulid::new()); + + let mut graph = WorkspaceSnapshotGraph::new(initial_vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); - let schema_id = initial_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let schema_id = graph.generate_ulid().expect("Unable to generate Ulid"); let schema_index = graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, schema_id, + Ulid::new(), ContentAddress::Schema(ContentHash::new( SchemaId::generate().to_string().as_bytes(), )), @@ -1176,14 +1194,13 @@ mod test { .expect("Unable to create NodeWeight"), ) .expect("Unable to add schema"); - let schema_variant_id = initial_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let schema_variant_id = graph.generate_ulid().expect("Unable to generate Ulid"); let schema_variant_index = graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, schema_variant_id, + Ulid::new(), ContentAddress::SchemaVariant(ContentHash::new( SchemaVariantId::generate().to_string().as_bytes(), )), @@ -1195,11 +1212,8 @@ mod test { graph .add_edge( graph.root_index, - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), schema_index, ) .expect("Unable to add root -> schema edge"); @@ -1208,23 +1222,19 @@ mod test { graph .get_node_index_by_id(schema_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), schema_variant_index, ) .expect("Unable to add schema -> schema variant edge"); - let schema_variant_2_id = initial_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let schema_variant_2_id = graph.generate_ulid().expect("Unable to generate Ulid"); let schema_variant_2_index = graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, schema_variant_2_id, + Ulid::new(), ContentAddress::SchemaVariant(ContentHash::new( SchemaVariantId::generate().to_string().as_bytes(), )), @@ -1238,11 +1248,8 @@ mod test { graph .get_node_index_by_id(schema_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), schema_variant_2_index, ) .expect("Unable to add schema -> schema variant edge"); @@ -1265,18 +1272,17 @@ mod test { ); graph - .mark_graph_seen(initial_change_set.vector_clock_id()) + .mark_graph_seen(initial_vector_clock_id) .expect("Unable to mark initial graph as seen"); let mut graph_with_deleted_edge = graph.clone(); - let new_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let new_change_set = &new_change_set; + let new_vector_clock_id = VectorClockId::new(Ulid::new(), Ulid::new()); graph_with_deleted_edge.dot(); graph_with_deleted_edge .remove_edge( - new_change_set, + new_vector_clock_id, graph_with_deleted_edge .get_node_index_by_id(schema_id) .expect("Unable to get NodeIndex for schema"), @@ -1304,14 +1310,14 @@ mod test { ); graph_with_deleted_edge - .mark_graph_seen(new_change_set.vector_clock_id()) + .mark_graph_seen(new_vector_clock_id) .expect("Unable to mark new graph as seen"); let ConflictsAndUpdates { conflicts, updates } = graph .detect_conflicts_and_updates( - initial_change_set.vector_clock_id(), + initial_vector_clock_id, &graph_with_deleted_edge, - new_change_set.vector_clock_id(), + new_vector_clock_id, ) .expect("Failed to detect conflicts and updates"); @@ -1326,17 +1332,17 @@ mod test { #[test] fn remove_unordered_node() { - let change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let change_set = &change_set; - let mut graph = WorkspaceSnapshotGraph::new(change_set) + let vector_clock_id = VectorClockId::new(Ulid::new(), Ulid::new()); + let mut graph = WorkspaceSnapshotGraph::new(vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); - let schema_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let schema_id = graph.generate_ulid().expect("Unable to generate Ulid"); let schema_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, schema_id, + Ulid::new(), ContentAddress::Schema(ContentHash::new( SchemaId::generate().to_string().as_bytes(), )), @@ -1344,11 +1350,12 @@ mod test { .expect("Unable to create NodeWeight"), ) .expect("Unable to add schema"); - let schema_variant_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let schema_variant_id = graph.generate_ulid().expect("Unable to generate Ulid"); let schema_variant_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, + Ulid::new(), schema_variant_id, ContentAddress::SchemaVariant(ContentHash::new( SchemaVariantId::generate().to_string().as_bytes(), @@ -1361,7 +1368,7 @@ mod test { graph .add_edge( graph.root_index, - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), schema_index, ) @@ -1371,18 +1378,19 @@ mod test { graph .get_node_index_by_id(schema_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), schema_variant_index, ) .expect("Unable to add schema -> schema variant edge"); - let schema_variant_2_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let schema_variant_2_id = graph.generate_ulid().expect("Unable to generate Ulid"); let schema_variant_2_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, schema_variant_2_id, + Ulid::new(), ContentAddress::SchemaVariant(ContentHash::new( SchemaVariantId::generate().to_string().as_bytes(), )), @@ -1396,7 +1404,7 @@ mod test { graph .get_node_index_by_id(schema_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), schema_variant_2_index, ) @@ -1421,7 +1429,7 @@ mod test { graph .remove_edge( - change_set, + vector_clock_id, graph .get_node_index_by_id(schema_id) .expect("Unable to get NodeIndex for schema"), @@ -1449,17 +1457,17 @@ mod test { #[test] fn remove_ordered_node() { - let change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let change_set = &change_set; - let mut graph = WorkspaceSnapshotGraph::new(change_set) + let vector_clock_id = VectorClockId::new(Ulid::new(), Ulid::new()); + let mut graph = WorkspaceSnapshotGraph::new(vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); - let schema_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let schema_id = graph.generate_ulid().expect("Unable to generate Ulid"); let schema_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, schema_id, + Ulid::new(), ContentAddress::Schema(ContentHash::new( SchemaId::generate().to_string().as_bytes(), )), @@ -1467,12 +1475,13 @@ mod test { .expect("Unable to create NodeWeight"), ) .expect("Unable to add schema"); - let schema_variant_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let schema_variant_id = graph.generate_ulid().expect("Unable to generate Ulid"); let schema_variant_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, schema_variant_id, + Ulid::new(), ContentAddress::SchemaVariant(ContentHash::new( SchemaVariantId::generate().to_string().as_bytes(), )), @@ -1484,7 +1493,7 @@ mod test { graph .add_edge( graph.root_index, - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), schema_index, ) @@ -1494,18 +1503,19 @@ mod test { graph .get_node_index_by_id(schema_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), schema_variant_index, ) .expect("Unable to add schema -> schema variant edge"); - let func_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let func_id = graph.generate_ulid().expect("Unable to generate Ulid"); let func_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, func_id, + Ulid::new(), ContentAddress::Func(ContentHash::new( FuncId::generate().to_string().as_bytes(), )), @@ -1516,19 +1526,20 @@ mod test { graph .add_edge( graph.root_index, - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), func_index, ) .expect("Unable to add root -> func edge"); - let root_prop_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let root_prop_id = graph.generate_ulid().expect("Unable to generate Ulid"); let root_prop_index = graph .add_ordered_node( - change_set, + vector_clock_id, NodeWeight::new_content( - change_set, + vector_clock_id, root_prop_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( PropId::generate().to_string().as_bytes(), )), @@ -1541,7 +1552,7 @@ mod test { graph .get_node_index_by_id(schema_variant_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), root_prop_index, ) @@ -1551,7 +1562,7 @@ mod test { graph .get_node_index_by_id(root_prop_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), graph .get_node_index_by_id(func_id) @@ -1561,12 +1572,13 @@ mod test { graph.cleanup(); graph.dot(); - let ordered_prop_1_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let ordered_prop_1_id = graph.generate_ulid().expect("Unable to generate Ulid"); let ordered_prop_1_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, ordered_prop_1_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_1_id.to_string().as_bytes(), )), @@ -1576,22 +1588,23 @@ mod test { .expect("Unable to add ordered prop"); graph .add_ordered_edge( - change_set.vector_clock_id(), + vector_clock_id, graph .get_node_index_by_id(root_prop_id) .expect("Unable to get NodeWeight for prop"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create uses edge weight"), ordered_prop_1_index, ) .expect("Unable to add prop -> ordered_prop_1 edge"); - let ordered_prop_2_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let ordered_prop_2_id = graph.generate_ulid().expect("Unable to generate Ulid"); let ordered_prop_2_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, ordered_prop_2_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_2_id.to_string().as_bytes(), )), @@ -1601,22 +1614,23 @@ mod test { .expect("Unable to add ordered prop"); graph .add_ordered_edge( - change_set.vector_clock_id(), + vector_clock_id, graph .get_node_index_by_id(root_prop_id) .expect("Unable to get NodeWeight for prop"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create uses edge weight"), ordered_prop_2_index, ) .expect("Unable to add prop -> ordered_prop_2 edge"); - let ordered_prop_3_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let ordered_prop_3_id = graph.generate_ulid().expect("Unable to generate Ulid"); let ordered_prop_3_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, ordered_prop_3_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_3_id.to_string().as_bytes(), )), @@ -1626,22 +1640,23 @@ mod test { .expect("Unable to add ordered prop"); graph .add_ordered_edge( - change_set.vector_clock_id(), + vector_clock_id, graph .get_node_index_by_id(root_prop_id) .expect("Unable to get NodeWeight for prop"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create uses edge weight"), ordered_prop_3_index, ) .expect("Unable to add prop -> ordered_prop_3 edge"); - let ordered_prop_4_id = change_set.generate_ulid().expect("Unable to generate Ulid"); + let ordered_prop_4_id = graph.generate_ulid().expect("Unable to generate Ulid"); let ordered_prop_4_index = graph .add_node( NodeWeight::new_content( - change_set, + vector_clock_id, ordered_prop_4_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_4_id.to_string().as_bytes(), )), @@ -1651,11 +1666,11 @@ mod test { .expect("Unable to add ordered prop"); graph .add_ordered_edge( - change_set.vector_clock_id(), + vector_clock_id, graph .get_node_index_by_id(root_prop_id) .expect("Unable to get NodeWeight for prop"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create uses edge weight"), ordered_prop_4_index, ) @@ -1683,7 +1698,7 @@ mod test { graph .remove_edge( - change_set, + vector_clock_id, graph .get_node_index_by_id(root_prop_id) .expect("Unable to get NodeIndex for prop"), diff --git a/lib/dal/src/workspace_snapshot/graph/tests/detect_conflicts_and_updates.rs b/lib/dal/src/workspace_snapshot/graph/tests/detect_conflicts_and_updates.rs index 88d6395644..2fa58fea52 100644 --- a/lib/dal/src/workspace_snapshot/graph/tests/detect_conflicts_and_updates.rs +++ b/lib/dal/src/workspace_snapshot/graph/tests/detect_conflicts_and_updates.rs @@ -6,6 +6,7 @@ mod test { use pretty_assertions_sorted::assert_eq; use si_events::ulid::Ulid; use si_events::ContentHash; + use si_events::VectorClockId; use std::collections::HashMap; use std::collections::HashSet; @@ -20,7 +21,7 @@ mod test { conflict::Conflict, graph::ConflictsAndUpdates, vector_clock::HasVectorClocks, NodeInformation, }; - use crate::{change_set::ChangeSet, NodeWeightDiscriminants}; + use crate::NodeWeightDiscriminants; use crate::{PropKind, WorkspaceSnapshotGraph}; #[derive(Debug, Eq, PartialEq)] @@ -82,32 +83,34 @@ mod test { #[test] fn detect_conflicts_and_updates_simple_no_conflicts_no_updates_in_base() { - let initial_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let initial_change_set = &initial_change_set; - let mut initial_graph = WorkspaceSnapshotGraph::new(initial_change_set) + let actor_id = Ulid::new(); + let initial_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); + let mut initial_graph = WorkspaceSnapshotGraph::new(initial_vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); - let schema_id = initial_change_set + let schema_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let schema_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, schema_id, + Ulid::new(), ContentAddress::Schema(ContentHash::from("Schema A")), ) .expect("Unable to create NodeWeight"), ) .expect("Unable to add Schema A"); - let schema_variant_id = initial_change_set + let schema_variant_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let schema_variant_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, schema_variant_id, + Ulid::new(), ContentAddress::SchemaVariant(ContentHash::from("Schema Variant A")), ) .expect("Unable to create NodeWeight"), @@ -117,11 +120,8 @@ mod test { initial_graph .add_edge( initial_graph.root_index, - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), schema_index, ) .expect("Unable to add root -> schema edge"); @@ -130,31 +130,26 @@ mod test { initial_graph .get_node_index_by_id(schema_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), schema_variant_index, ) .expect("Unable to add schema -> schema variant edge"); initial_graph - .mark_graph_seen(initial_change_set.vector_clock_id()) + .mark_graph_seen(initial_vector_clock_id) .expect("unable to mark seen"); - let new_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let new_change_set = &new_change_set; + let new_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); let mut new_graph = initial_graph.clone(); - let component_id = new_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let component_id = new_graph.generate_ulid().expect("Unable to generate Ulid"); let component_index = new_graph .add_node( NodeWeight::new_content( - new_change_set, + new_vector_clock_id, component_id, + Ulid::new(), ContentAddress::Schema(ContentHash::from("Component A")), ) .expect("Unable to create NodeWeight"), @@ -163,7 +158,7 @@ mod test { new_graph .add_edge( new_graph.root_index, - EdgeWeight::new(new_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(new_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), component_index, ) @@ -173,7 +168,7 @@ mod test { new_graph .get_node_index_by_id(component_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(new_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(new_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), new_graph .get_node_index_by_id(schema_variant_id) @@ -182,14 +177,14 @@ mod test { .expect("Unable to add component -> schema variant edge"); new_graph - .mark_graph_seen(new_change_set.vector_clock_id()) + .mark_graph_seen(new_vector_clock_id) .expect("unable to mark seen"); let conflicts_and_updates = new_graph .detect_conflicts_and_updates( - new_change_set.vector_clock_id(), + new_vector_clock_id, &initial_graph, - initial_change_set.vector_clock_id(), + initial_vector_clock_id, ) .expect("Unable to detect conflicts and updates"); @@ -204,32 +199,31 @@ mod test { #[test] fn detect_conflicts_and_updates_simple_no_conflicts_with_purely_new_content_in_base() { - let initial_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let base_change_set = &initial_change_set; - let mut base_graph = WorkspaceSnapshotGraph::new(base_change_set) + let actor_id = Ulid::new(); + let initial_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); + + let mut base_graph = WorkspaceSnapshotGraph::new(initial_vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); - let schema_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let schema_id = base_graph.generate_ulid().expect("Unable to generate Ulid"); let schema_index = base_graph .add_node( NodeWeight::new_content( - base_change_set, + initial_vector_clock_id, schema_id, + Ulid::new(), ContentAddress::Schema(ContentHash::from("Schema A")), ) .expect("Unable to create NodeWeight"), ) .expect("Unable to add Schema A"); - let schema_variant_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let schema_variant_id = base_graph.generate_ulid().expect("Unable to generate Ulid"); let schema_variant_index = base_graph .add_node( NodeWeight::new_content( - base_change_set, + initial_vector_clock_id, schema_variant_id, + Ulid::new(), ContentAddress::SchemaVariant(ContentHash::from("Schema Variant A")), ) .expect("Unable to create NodeWeight"), @@ -239,7 +233,7 @@ mod test { base_graph .add_edge( base_graph.root_index, - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), schema_index, ) @@ -249,7 +243,7 @@ mod test { base_graph .get_node_index_by_id(schema_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), schema_variant_index, ) @@ -257,21 +251,19 @@ mod test { base_graph.dot(); base_graph - .mark_graph_seen(initial_change_set.vector_clock_id()) + .mark_graph_seen(initial_vector_clock_id) .expect("unable to mark graph seen"); - let new_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let new_change_set = &new_change_set; + let new_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); let mut new_graph = base_graph.clone(); - let new_onto_component_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let new_onto_component_id = new_graph.generate_ulid().expect("Unable to generate Ulid"); let new_onto_component_index = base_graph .add_node( NodeWeight::new_content( - base_change_set, + initial_vector_clock_id, new_onto_component_id, + Ulid::new(), ContentAddress::Component(ContentHash::from("Component B")), ) .expect("Unable to create NodeWeight"), @@ -280,7 +272,7 @@ mod test { let _new_onto_root_component_edge_index = base_graph .add_edge( base_graph.root_index, - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), new_onto_component_index, ) @@ -290,7 +282,7 @@ mod test { base_graph .get_node_index_by_id(new_onto_component_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), base_graph .get_node_index_by_id(schema_variant_id) @@ -300,15 +292,11 @@ mod test { base_graph.dot(); new_graph - .mark_graph_seen(new_change_set.vector_clock_id()) + .mark_graph_seen(new_vector_clock_id) .expect("unable to mark seen"); let conflicts_and_updates = new_graph - .detect_conflicts_and_updates( - new_change_set.vector_clock_id(), - &base_graph, - base_change_set.vector_clock_id(), - ) + .detect_conflicts_and_updates(new_vector_clock_id, &base_graph, initial_vector_clock_id) .expect("Unable to detect conflicts and updates"); assert!(conflicts_and_updates.conflicts.is_empty()); @@ -332,19 +320,19 @@ mod test { #[test] fn detect_conflicts_and_updates_with_purely_new_content_in_new_graph() { - let initial_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let base_change_set = &initial_change_set; - let mut base_graph = WorkspaceSnapshotGraph::new(base_change_set) + let actor_id = Ulid::new(); + let initial_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); + + let mut base_graph = WorkspaceSnapshotGraph::new(initial_vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); - let component_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let component_id = base_graph.generate_ulid().expect("Unable to generate Ulid"); let component_index = base_graph .add_node( NodeWeight::new_content( - base_change_set, + initial_vector_clock_id, component_id, + Ulid::new(), ContentAddress::Component(ContentHash::from("Component A")), ) .expect("Unable to create NodeWeight"), @@ -353,7 +341,7 @@ mod test { base_graph .add_edge( base_graph.root_index, - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), component_index, ) @@ -362,21 +350,19 @@ mod test { base_graph.cleanup(); base_graph.dot(); base_graph - .mark_graph_seen(initial_change_set.vector_clock_id()) + .mark_graph_seen(initial_vector_clock_id) .expect("unable to mark seen"); - let new_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let new_change_set = &new_change_set; + let new_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); let mut new_graph = base_graph.clone(); - let new_component_id = new_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let new_component_id = new_graph.generate_ulid().expect("Unable to generate Ulid"); let new_component_index = new_graph .add_node( NodeWeight::new_content( - new_change_set, + new_vector_clock_id, new_component_id, + Ulid::new(), ContentAddress::Component(ContentHash::from("Component B")), ) .expect("Unable to create NodeWeight"), @@ -385,7 +371,7 @@ mod test { new_graph .add_edge( new_graph.root_index, - EdgeWeight::new(new_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(new_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), new_component_index, ) @@ -394,26 +380,18 @@ mod test { new_graph.cleanup(); new_graph.dot(); new_graph - .mark_graph_seen(new_change_set.vector_clock_id()) + .mark_graph_seen(new_vector_clock_id) .expect("unable to mark seen"); let conflicts_and_updates = new_graph - .detect_conflicts_and_updates( - new_change_set.vector_clock_id(), - &base_graph, - base_change_set.vector_clock_id(), - ) + .detect_conflicts_and_updates(new_vector_clock_id, &base_graph, initial_vector_clock_id) .expect("Unable to detect conflicts and updates"); assert!(conflicts_and_updates.updates.is_empty()); assert!(conflicts_and_updates.conflicts.is_empty()); let conflicts_and_updates = base_graph - .detect_conflicts_and_updates( - base_change_set.vector_clock_id(), - &new_graph, - new_change_set.vector_clock_id(), - ) + .detect_conflicts_and_updates(initial_vector_clock_id, &new_graph, new_vector_clock_id) .expect("Unable to detect conflicts and updates"); assert!(conflicts_and_updates.conflicts.is_empty()); @@ -434,32 +412,30 @@ mod test { #[test] fn detect_conflicts_and_updates_simple_no_conflicts_with_updates_on_both_sides() { - let initial_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let base_change_set = &initial_change_set; - let mut base_graph = WorkspaceSnapshotGraph::new(base_change_set) + let actor_id = Ulid::new(); + let initial_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); + let mut base_graph = WorkspaceSnapshotGraph::new(initial_vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); - let schema_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let schema_id = base_graph.generate_ulid().expect("Unable to generate Ulid"); let schema_index = base_graph .add_node( NodeWeight::new_content( - base_change_set, + initial_vector_clock_id, schema_id, + Ulid::new(), ContentAddress::Schema(ContentHash::from("Schema A")), ) .expect("Unable to create NodeWeight"), ) .expect("Unable to add Schema A"); - let schema_variant_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let schema_variant_id = base_graph.generate_ulid().expect("Unable to generate Ulid"); let schema_variant_index = base_graph .add_node( NodeWeight::new_content( - base_change_set, + initial_vector_clock_id, schema_variant_id, + Ulid::new(), ContentAddress::SchemaVariant(ContentHash::from("Schema Variant A")), ) .expect("Unable to create NodeWeight"), @@ -469,7 +445,7 @@ mod test { base_graph .add_edge( base_graph.root_index, - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), schema_index, ) @@ -479,7 +455,7 @@ mod test { base_graph .get_node_index_by_id(schema_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), schema_variant_index, ) @@ -487,21 +463,19 @@ mod test { base_graph.dot(); base_graph - .mark_graph_seen(initial_change_set.vector_clock_id()) + .mark_graph_seen(initial_vector_clock_id) .expect("unable to mark seen"); - let new_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let new_change_set = &new_change_set; + let new_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); let mut new_graph = base_graph.clone(); - let component_id = new_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let component_id = new_graph.generate_ulid().expect("Unable to generate Ulid"); let component_index = new_graph .add_node( NodeWeight::new_content( - new_change_set, + new_vector_clock_id, component_id, + Ulid::new(), ContentAddress::Component(ContentHash::from("Component A")), ) .expect("Unable to create NodeWeight"), @@ -510,7 +484,7 @@ mod test { new_graph .add_edge( new_graph.root_index, - EdgeWeight::new(new_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(new_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), component_index, ) @@ -520,7 +494,7 @@ mod test { new_graph .get_node_index_by_id(component_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(new_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(new_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), new_graph .get_node_index_by_id(schema_variant_id) @@ -530,17 +504,16 @@ mod test { new_graph.dot(); new_graph - .mark_graph_seen(new_change_set.vector_clock_id()) + .mark_graph_seen(new_vector_clock_id) .expect("unable to mark graph seen"); - let new_onto_component_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let new_onto_component_id = new_graph.generate_ulid().expect("Unable to generate Ulid"); let new_onto_component_index = base_graph .add_node( NodeWeight::new_content( - base_change_set, + initial_vector_clock_id, new_onto_component_id, + Ulid::new(), ContentAddress::Component(ContentHash::from("Component B")), ) .expect("Unable to create NodeWeight"), @@ -549,7 +522,7 @@ mod test { base_graph .add_edge( base_graph.root_index, - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), new_onto_component_index, ) @@ -559,7 +532,7 @@ mod test { base_graph .get_node_index_by_id(new_onto_component_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), base_graph .get_node_index_by_id(schema_variant_id) @@ -569,15 +542,11 @@ mod test { base_graph.dot(); base_graph - .mark_graph_seen(initial_change_set.vector_clock_id()) + .mark_graph_seen(initial_vector_clock_id) .expect("unable to mark graph seen"); let conflicts_and_updates = new_graph - .detect_conflicts_and_updates( - new_change_set.vector_clock_id(), - &base_graph, - base_change_set.vector_clock_id(), - ) + .detect_conflicts_and_updates(new_vector_clock_id, &base_graph, initial_vector_clock_id) .expect("Unable to detect conflicts and updates"); assert!(conflicts_and_updates.conflicts.is_empty()); @@ -601,32 +570,30 @@ mod test { #[test] fn detect_conflicts_and_updates_simple_with_content_conflict() { - let initial_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let base_change_set = &initial_change_set; - let mut base_graph = WorkspaceSnapshotGraph::new(base_change_set) + let actor_id = Ulid::new(); + let initial_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); + let mut base_graph = WorkspaceSnapshotGraph::new(initial_vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); - let schema_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let schema_id = base_graph.generate_ulid().expect("Unable to generate Ulid"); let schema_index = base_graph .add_node( NodeWeight::new_content( - base_change_set, + initial_vector_clock_id, schema_id, + Ulid::new(), ContentAddress::Schema(ContentHash::from("Schema A")), ) .expect("Unable to create NodeWeight"), ) .expect("Unable to add Schema A"); - let schema_variant_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let schema_variant_id = base_graph.generate_ulid().expect("Unable to generate Ulid"); let schema_variant_index = base_graph .add_node( NodeWeight::new_content( - base_change_set, + initial_vector_clock_id, schema_variant_id, + Ulid::new(), ContentAddress::SchemaVariant(ContentHash::from("Schema Variant A")), ) .expect("Unable to create NodeWeight"), @@ -636,7 +603,7 @@ mod test { base_graph .add_edge( base_graph.root_index, - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), schema_index, ) @@ -646,20 +613,19 @@ mod test { base_graph .get_node_index_by_id(schema_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), schema_variant_index, ) .expect("Unable to add schema -> schema variant edge"); - let component_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let component_id = base_graph.generate_ulid().expect("Unable to generate Ulid"); let component_index = base_graph .add_node( NodeWeight::new_content( - base_change_set, + initial_vector_clock_id, component_id, + Ulid::new(), ContentAddress::Component(ContentHash::from("Component A")), ) .expect("Unable to create NodeWeight"), @@ -668,7 +634,7 @@ mod test { base_graph .add_edge( base_graph.root_index, - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), component_index, ) @@ -678,7 +644,7 @@ mod test { base_graph .get_node_index_by_id(component_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), base_graph .get_node_index_by_id(schema_variant_id) @@ -689,16 +655,15 @@ mod test { base_graph.cleanup(); base_graph.dot(); base_graph - .mark_graph_seen(initial_change_set.vector_clock_id()) + .mark_graph_seen(initial_vector_clock_id) .expect("mark graph seen"); - let new_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let new_change_set = &new_change_set; + let new_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); let mut new_graph = base_graph.clone(); new_graph .update_content( - new_change_set, + new_vector_clock_id, component_id, ContentHash::from("Updated Component A"), ) @@ -707,12 +672,12 @@ mod test { new_graph.cleanup(); new_graph.dot(); new_graph - .mark_graph_seen(new_change_set.vector_clock_id()) + .mark_graph_seen(new_vector_clock_id) .expect("mark graph seen"); base_graph .update_content( - base_change_set, + initial_vector_clock_id, component_id, ContentHash::from("Base Updated Component A"), ) @@ -721,15 +686,11 @@ mod test { base_graph.cleanup(); base_graph.dot(); base_graph - .mark_graph_seen(initial_change_set.vector_clock_id()) + .mark_graph_seen(initial_vector_clock_id) .expect("mark graph seen"); let conflicts_and_updates = new_graph - .detect_conflicts_and_updates( - new_change_set.vector_clock_id(), - &base_graph, - base_change_set.vector_clock_id(), - ) + .detect_conflicts_and_updates(new_vector_clock_id, &base_graph, initial_vector_clock_id) .expect("Unable to detect conflicts and updates"); assert_eq!( @@ -756,32 +717,30 @@ mod test { #[test] fn detect_conflicts_and_updates_simple_with_modify_removed_item_conflict() { - let initial_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let base_change_set = &initial_change_set; - let mut base_graph = WorkspaceSnapshotGraph::new(base_change_set) + let actor_id = Ulid::new(); + let initial_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); + let mut base_graph = WorkspaceSnapshotGraph::new(initial_vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); - let schema_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let schema_id = base_graph.generate_ulid().expect("Unable to generate Ulid"); let schema_index = base_graph .add_node( NodeWeight::new_content( - base_change_set, + initial_vector_clock_id, schema_id, + Ulid::new(), ContentAddress::Schema(ContentHash::from("Schema A")), ) .expect("Unable to create NodeWeight"), ) .expect("Unable to add Schema A"); - let schema_variant_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let schema_variant_id = base_graph.generate_ulid().expect("Unable to generate Ulid"); let schema_variant_index = base_graph .add_node( NodeWeight::new_content( - base_change_set, + initial_vector_clock_id, schema_variant_id, + Ulid::new(), ContentAddress::SchemaVariant(ContentHash::from("Schema Variant A")), ) .expect("Unable to create NodeWeight"), @@ -791,7 +750,7 @@ mod test { base_graph .add_edge( base_graph.root_index, - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), schema_index, ) @@ -801,20 +760,19 @@ mod test { base_graph .get_node_index_by_id(schema_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), schema_variant_index, ) .expect("Unable to add schema -> schema variant edge"); - let component_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let component_id = base_graph.generate_ulid().expect("Unable to generate Ulid"); let component_index = base_graph .add_node( NodeWeight::new_content( - base_change_set, + initial_vector_clock_id, component_id, + Ulid::new(), ContentAddress::Component(ContentHash::from("Component A")), ) .expect("Unable to create NodeWeight"), @@ -823,7 +781,7 @@ mod test { base_graph .add_edge( base_graph.root_index, - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), component_index, ) @@ -833,7 +791,7 @@ mod test { base_graph .get_node_index_by_id(component_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), base_graph .get_node_index_by_id(schema_variant_id) @@ -844,16 +802,15 @@ mod test { base_graph.cleanup(); base_graph.dot(); base_graph - .mark_graph_seen(initial_change_set.vector_clock_id()) + .mark_graph_seen(initial_vector_clock_id) .expect("mark graph seen"); - let new_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let new_change_set = &new_change_set; + let new_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); let mut new_graph = base_graph.clone(); base_graph .remove_edge( - base_change_set, + initial_vector_clock_id, base_graph.root_index, base_graph .get_node_index_by_id(component_id) @@ -865,12 +822,12 @@ mod test { base_graph.cleanup(); base_graph.dot(); base_graph - .mark_graph_seen(initial_change_set.vector_clock_id()) + .mark_graph_seen(initial_vector_clock_id) .expect("mark graph seen"); new_graph .update_content( - new_change_set, + new_vector_clock_id, component_id, ContentHash::from("Updated Component A"), ) @@ -879,15 +836,11 @@ mod test { new_graph.cleanup(); new_graph.dot(); new_graph - .mark_graph_seen(new_change_set.vector_clock_id()) + .mark_graph_seen(new_vector_clock_id) .expect("unable to mark graph seen"); let conflicts_and_updates = new_graph - .detect_conflicts_and_updates( - new_change_set.vector_clock_id(), - &base_graph, - base_change_set.vector_clock_id(), - ) + .detect_conflicts_and_updates(new_vector_clock_id, &base_graph, initial_vector_clock_id) .expect("Unable to detect conflicts and updates"); assert_eq!( @@ -905,23 +858,24 @@ mod test { #[test] fn detect_conflicts_and_updates_add_unordered_child_to_ordered_container() { - let base_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let active_change_set = &base_change_set; - let mut base_graph = WorkspaceSnapshotGraph::new(active_change_set) + let actor_id = Ulid::new(); + let initial_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); + let mut base_graph = WorkspaceSnapshotGraph::new(initial_vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); let active_graph = &mut base_graph; // Create base prop node let base_prop_id = { - let prop_id = active_change_set + let prop_id = active_graph .generate_ulid() .expect("Unable to generate Ulid"); let prop_index = active_graph .add_ordered_node( - active_change_set, + initial_vector_clock_id, NodeWeight::new_content( - active_change_set, + initial_vector_clock_id, prop_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new(prop_id.to_string().as_bytes())), ) .expect("Unable to create NodeWeight"), @@ -931,11 +885,8 @@ mod test { active_graph .add_edge( active_graph.root_index, - EdgeWeight::new( - active_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), prop_index, ) .expect("Unable to add sv -> prop edge"); @@ -947,14 +898,15 @@ mod test { // Create two prop nodes children of base prop let ordered_prop_1_index = { - let ordered_prop_id = active_change_set + let ordered_prop_id = active_graph .generate_ulid() .expect("Unable to generate Ulid"); let ordered_prop_index = active_graph .add_node( NodeWeight::new_content( - active_change_set, + initial_vector_clock_id, ordered_prop_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_id.to_string().as_bytes(), )), @@ -964,15 +916,12 @@ mod test { .expect("Unable to add ordered prop"); active_graph .add_ordered_edge( - active_change_set.vector_clock_id(), + initial_vector_clock_id, active_graph .get_node_index_by_id(base_prop_id) .expect("Unable to get prop NodeIndex"), - EdgeWeight::new( - active_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create uses edge weight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create uses edge weight"), ordered_prop_index, ) .expect("Unable to add prop -> ordered_prop_1 edge"); @@ -983,14 +932,15 @@ mod test { active_graph.cleanup(); let attribute_prototype_id = { - let node_id = active_change_set + let node_id = active_graph .generate_ulid() .expect("Unable to generate Ulid"); let node_index = active_graph .add_node( NodeWeight::new_content( - active_change_set, + initial_vector_clock_id, node_id, + Ulid::new(), ContentAddress::AttributePrototype(ContentHash::new( node_id.to_string().as_bytes(), )), @@ -1002,11 +952,8 @@ mod test { active_graph .add_edge( active_graph.root_index, - EdgeWeight::new( - active_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), node_index, ) .expect("Unable to add root -> prototype edge"); @@ -1016,54 +963,46 @@ mod test { active_graph.cleanup(); active_graph - .mark_graph_seen(active_change_set.vector_clock_id()) + .mark_graph_seen(initial_vector_clock_id) .expect("unable to mark graph seen"); // Get new graph - let new_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let active_change_set = &new_change_set; + let new_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); let mut new_graph = base_graph.clone(); - let active_graph = &mut new_graph; + let new_graph = &mut new_graph; // Connect Prototype to Prop - active_graph + new_graph .add_edge( - active_graph + new_graph .get_node_index_by_id(base_prop_id) .expect("Unable to get prop NodeIndex"), - EdgeWeight::new( - active_change_set.vector_clock_id(), - EdgeWeightKind::Prototype(None), - ) - .expect("Unable to create EdgeWeight"), - active_graph + EdgeWeight::new(new_vector_clock_id, EdgeWeightKind::Prototype(None)) + .expect("Unable to create EdgeWeight"), + new_graph .get_node_index_by_id(attribute_prototype_id) .expect("Unable to get prop NodeIndex"), ) .expect("Unable to add sv -> prop edge"); - active_graph.cleanup(); - let base_prop_node_index = active_graph + new_graph.cleanup(); + let base_prop_node_index = new_graph .get_node_index_by_id(base_prop_id) .expect("Unable to get base prop NodeIndex"); assert_eq!( vec![ordered_prop_1_index,], - active_graph + new_graph .ordered_children_for_node(base_prop_node_index) .expect("Unable to find ordered children for node") .expect("Node is not an ordered node") ); - active_graph - .mark_graph_seen(active_change_set.vector_clock_id()) + new_graph + .mark_graph_seen(new_vector_clock_id) .expect("unable to mark graph seen"); // Assert that the new edge to the prototype gets created let ConflictsAndUpdates { conflicts, updates } = base_graph - .detect_conflicts_and_updates( - base_change_set.vector_clock_id(), - &new_graph, - new_change_set.vector_clock_id(), - ) + .detect_conflicts_and_updates(initial_vector_clock_id, new_graph, new_vector_clock_id) .expect("Unable to detect conflicts and updates"); assert!(conflicts.is_empty()); @@ -1094,20 +1033,19 @@ mod test { #[test] fn detect_conflicts_and_updates_complex() { - let initial_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let base_change_set = &initial_change_set; - let mut base_graph = WorkspaceSnapshotGraph::new(base_change_set) + let actor_id = Ulid::new(); + let initial_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); + let mut base_graph = WorkspaceSnapshotGraph::new(initial_vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); // Docker Image Schema - let docker_image_schema_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let docker_image_schema_id = base_graph.generate_ulid().expect("Unable to generate Ulid"); let docker_image_schema_index = base_graph .add_node( NodeWeight::new_content( - base_change_set, + initial_vector_clock_id, docker_image_schema_id, + Ulid::new(), ContentAddress::Schema(ContentHash::from("first")), ) .expect("Unable to create NodeWeight"), @@ -1116,7 +1054,7 @@ mod test { base_graph .add_edge( base_graph.root_index, - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), docker_image_schema_index, ) @@ -1125,14 +1063,14 @@ mod test { println!("Add edge from root to {} in onto", docker_image_schema_id); // Docker Image Schema Variant - let docker_image_schema_variant_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let docker_image_schema_variant_id = + base_graph.generate_ulid().expect("Unable to generate Ulid"); let docker_image_schema_variant_index = base_graph .add_node( NodeWeight::new_content( - base_change_set, + initial_vector_clock_id, docker_image_schema_variant_id, + Ulid::new(), ContentAddress::SchemaVariant(ContentHash::from("first")), ) .expect("Unable to create NodeWeight"), @@ -1143,7 +1081,7 @@ mod test { base_graph .get_node_index_by_id(docker_image_schema_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), docker_image_schema_variant_index, ) @@ -1155,14 +1093,14 @@ mod test { ); // Nginx Docker Image Component - let nginx_docker_image_component_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let nginx_docker_image_component_id = + base_graph.generate_ulid().expect("Unable to generate Ulid"); let nginx_docker_image_component_index = base_graph .add_node( NodeWeight::new_content( - base_change_set, + initial_vector_clock_id, nginx_docker_image_component_id, + Ulid::new(), ContentAddress::Component(ContentHash::from("first")), ) .expect("Unable to create NodeWeight"), @@ -1171,7 +1109,7 @@ mod test { base_graph .add_edge( base_graph.root_index, - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), nginx_docker_image_component_index, ) @@ -1187,7 +1125,7 @@ mod test { base_graph .get_node_index_by_id(nginx_docker_image_component_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), base_graph .get_node_index_by_id(docker_image_schema_variant_id) @@ -1201,14 +1139,13 @@ mod test { ); // Alpine Component - let alpine_component_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let alpine_component_id = base_graph.generate_ulid().expect("Unable to generate Ulid"); let alpine_component_index = base_graph .add_node( NodeWeight::new_content( - base_change_set, + initial_vector_clock_id, alpine_component_id, + Ulid::new(), ContentAddress::Component(ContentHash::from("first")), ) .expect("Unable to create NodeWeight"), @@ -1217,7 +1154,7 @@ mod test { base_graph .add_edge( base_graph.root_index, - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), alpine_component_index, ) @@ -1230,7 +1167,7 @@ mod test { base_graph .get_node_index_by_id(alpine_component_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), base_graph .get_node_index_by_id(docker_image_schema_variant_id) @@ -1244,14 +1181,13 @@ mod test { ); // Butane Schema - let butane_schema_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let butane_schema_id = base_graph.generate_ulid().expect("Unable to generate Ulid"); let butane_schema_index = base_graph .add_node( NodeWeight::new_content( - base_change_set, + initial_vector_clock_id, butane_schema_id, + Ulid::new(), ContentAddress::Schema(ContentHash::from("first")), ) .expect("Unable to create NodeWeight"), @@ -1260,7 +1196,7 @@ mod test { base_graph .add_edge( base_graph.root_index, - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), butane_schema_index, ) @@ -1269,14 +1205,13 @@ mod test { println!("Add edge from root to {} in onto", butane_schema_id); // Butane Schema Variant - let butane_schema_variant_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let butane_schema_variant_id = base_graph.generate_ulid().expect("Unable to generate Ulid"); let butane_schema_variant_index = base_graph .add_node( NodeWeight::new_content( - base_change_set, + initial_vector_clock_id, butane_schema_variant_id, + Ulid::new(), ContentAddress::SchemaVariant(ContentHash::from("first")), ) .expect("Unable to create NodeWeight"), @@ -1287,7 +1222,7 @@ mod test { base_graph .get_node_index_by_id(butane_schema_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), butane_schema_variant_index, ) @@ -1299,14 +1234,14 @@ mod test { ); // Nginx Butane Component - let nginx_butane_component_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let nginx_butane_component_id = + base_graph.generate_ulid().expect("Unable to generate Ulid"); let nginx_butane_node_index = base_graph .add_node( NodeWeight::new_content( - base_change_set, + initial_vector_clock_id, nginx_butane_component_id, + Ulid::new(), ContentAddress::Component(ContentHash::from("first")), ) .expect("Unable to create NodeWeight"), @@ -1315,7 +1250,7 @@ mod test { base_graph .add_edge( base_graph.root_index, - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), nginx_butane_node_index, ) @@ -1331,7 +1266,7 @@ mod test { base_graph .get_node_index_by_id(nginx_butane_component_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), base_graph .get_node_index_by_id(butane_schema_variant_id) @@ -1347,12 +1282,11 @@ mod test { base_graph.cleanup(); //base_graph.dot(); base_graph - .mark_graph_seen(base_change_set.vector_clock_id()) + .mark_graph_seen(initial_vector_clock_id) .expect("unable to mark graph seen"); // Create a new change set to cause some problems! - let new_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let new_change_set = &new_change_set; + let new_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); let mut new_graph = base_graph.clone(); println!("fork onto into to_rebase"); @@ -1360,7 +1294,7 @@ mod test { // Create a modify removed item conflict. base_graph .remove_edge( - base_change_set, + initial_vector_clock_id, base_graph.root_index, base_graph .get_node_index_by_id(nginx_butane_component_id) @@ -1376,7 +1310,7 @@ mod test { new_graph .update_content( - new_change_set, + new_vector_clock_id, nginx_butane_component_id, ContentHash::from("second"), ) @@ -1390,7 +1324,7 @@ mod test { // Create a node content conflict. base_graph .update_content( - base_change_set, + initial_vector_clock_id, docker_image_schema_variant_id, ContentHash::from("oopsie"), ) @@ -1403,7 +1337,7 @@ mod test { new_graph .update_content( - new_change_set, + new_vector_clock_id, docker_image_schema_variant_id, ContentHash::from("poopsie"), ) @@ -1417,7 +1351,7 @@ mod test { // Create a pure update. base_graph .update_content( - base_change_set, + initial_vector_clock_id, docker_image_schema_id, ContentHash::from("bg3"), ) @@ -1427,22 +1361,18 @@ mod test { new_graph.cleanup(); new_graph - .mark_graph_seen(new_change_set.vector_clock_id()) + .mark_graph_seen(new_vector_clock_id) .expect("unable to mark graph seen"); base_graph.cleanup(); base_graph - .mark_graph_seen(base_change_set.vector_clock_id()) + .mark_graph_seen(initial_vector_clock_id) .expect("unable to mark graph seen"); // new_graph.tiny_dot_to_file(Some("to_rebase")); // base_graph.tiny_dot_to_file(Some("onto")); let ConflictsAndUpdates { conflicts, updates } = new_graph - .detect_conflicts_and_updates( - new_change_set.vector_clock_id(), - &base_graph, - base_change_set.vector_clock_id(), - ) + .detect_conflicts_and_updates(new_vector_clock_id, &base_graph, initial_vector_clock_id) .expect("Unable to detect conflicts and updates"); // base_graph.dot(); @@ -1501,32 +1431,34 @@ mod test { #[test] fn detect_conflicts_and_updates_simple_ordering_no_conflicts_no_updates_in_base() { - let initial_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let initial_change_set = &initial_change_set; - let mut initial_graph = WorkspaceSnapshotGraph::new(initial_change_set) + let actor_id = Ulid::new(); + let initial_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); + let mut initial_graph = WorkspaceSnapshotGraph::new(initial_vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); - let schema_id = initial_change_set + let schema_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let schema_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, schema_id, + Ulid::new(), ContentAddress::Schema(ContentHash::from("Schema A")), ) .expect("Unable to create NodeWeight"), ) .expect("Unable to add Schema A"); - let schema_variant_id = initial_change_set + let schema_variant_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let schema_variant_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, schema_variant_id, + Ulid::new(), ContentAddress::SchemaVariant(ContentHash::from("Schema Variant A")), ) .expect("Unable to create NodeWeight"), @@ -1536,11 +1468,8 @@ mod test { initial_graph .add_edge( initial_graph.root_index, - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), schema_index, ) .expect("Unable to add root -> schema edge"); @@ -1549,24 +1478,22 @@ mod test { initial_graph .get_node_index_by_id(schema_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), schema_variant_index, ) .expect("Unable to add schema -> schema variant edge"); - let container_prop_id = initial_change_set + let container_prop_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let container_prop_index = initial_graph .add_ordered_node( - initial_change_set, + initial_vector_clock_id, NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, container_prop_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( container_prop_id.to_string().as_bytes(), )), @@ -1579,23 +1506,21 @@ mod test { initial_graph .get_node_index_by_id(schema_variant_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), container_prop_index, ) .expect("Unable to add schema variant -> container prop edge"); - let ordered_prop_1_id = initial_change_set + let ordered_prop_1_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let ordered_prop_1_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, ordered_prop_1_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_1_id.to_string().as_bytes(), )), @@ -1605,27 +1530,25 @@ mod test { .expect("Unable to add ordered prop 1"); initial_graph .add_ordered_edge( - initial_change_set.vector_clock_id(), + initial_vector_clock_id, initial_graph .get_node_index_by_id(container_prop_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), ordered_prop_1_index, ) .expect("Unable to add container prop -> ordered prop 1 edge"); - let ordered_prop_2_id = initial_change_set + let ordered_prop_2_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let ordered_prop_2_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, ordered_prop_2_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_2_id.to_string().as_bytes(), )), @@ -1635,27 +1558,25 @@ mod test { .expect("Unable to add ordered prop 2"); initial_graph .add_ordered_edge( - initial_change_set.vector_clock_id(), + initial_vector_clock_id, initial_graph .get_node_index_by_id(container_prop_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), ordered_prop_2_index, ) .expect("Unable to add container prop -> ordered prop 2 edge"); - let ordered_prop_3_id = initial_change_set + let ordered_prop_3_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let ordered_prop_3_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, ordered_prop_3_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_3_id.to_string().as_bytes(), )), @@ -1665,27 +1586,25 @@ mod test { .expect("Unable to add ordered prop 3"); initial_graph .add_ordered_edge( - initial_change_set.vector_clock_id(), + initial_vector_clock_id, initial_graph .get_node_index_by_id(container_prop_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), ordered_prop_3_index, ) .expect("Unable to add container prop -> ordered prop 3 edge"); - let ordered_prop_4_id = initial_change_set + let ordered_prop_4_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let ordered_prop_4_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, ordered_prop_4_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_4_id.to_string().as_bytes(), )), @@ -1695,15 +1614,12 @@ mod test { .expect("Unable to add ordered prop 4"); initial_graph .add_ordered_edge( - initial_change_set.vector_clock_id(), + initial_vector_clock_id, initial_graph .get_node_index_by_id(container_prop_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), ordered_prop_4_index, ) .expect("Unable to add container prop -> ordered prop 4 edge"); @@ -1712,21 +1628,19 @@ mod test { initial_graph.dot(); initial_graph - .mark_graph_seen(initial_change_set.vector_clock_id()) + .mark_graph_seen(initial_vector_clock_id) .expect("unable to mark graph seen"); - let new_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let new_change_set = &new_change_set; + let new_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); let mut new_graph = initial_graph.clone(); - let ordered_prop_5_id = new_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let ordered_prop_5_id = new_graph.generate_ulid().expect("Unable to generate Ulid"); let ordered_prop_5_index = new_graph .add_node( NodeWeight::new_content( - new_change_set, + new_vector_clock_id, ordered_prop_5_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_5_id.to_string().as_bytes(), )), @@ -1736,11 +1650,11 @@ mod test { .expect("Unable to add ordered prop 5"); new_graph .add_ordered_edge( - new_change_set.vector_clock_id(), + new_vector_clock_id, new_graph .get_node_index_by_id(container_prop_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new(new_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(new_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create EdgeWeight"), ordered_prop_5_index, ) @@ -1749,14 +1663,14 @@ mod test { new_graph.cleanup(); new_graph.dot(); new_graph - .mark_graph_seen(new_change_set.vector_clock_id()) + .mark_graph_seen(new_vector_clock_id) .expect("unable to mark graph seen"); let ConflictsAndUpdates { conflicts, updates } = new_graph .detect_conflicts_and_updates( - new_change_set.vector_clock_id(), + new_vector_clock_id, &initial_graph, - initial_change_set.vector_clock_id(), + initial_vector_clock_id, ) .expect("Unable to detect conflicts and updates"); @@ -1766,32 +1680,34 @@ mod test { #[test] fn detect_conflicts_and_updates_simple_ordering_no_conflicts_with_updates_in_base() { - let initial_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let initial_change_set = &initial_change_set; - let mut initial_graph = WorkspaceSnapshotGraph::new(initial_change_set) + let actor_id = Ulid::new(); + let initial_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); + let mut initial_graph = WorkspaceSnapshotGraph::new(initial_vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); - let schema_id = initial_change_set + let schema_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let schema_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, schema_id, + Ulid::new(), ContentAddress::Schema(ContentHash::from("Schema A")), ) .expect("Unable to create NodeWeight"), ) .expect("Unable to add Schema A"); - let schema_variant_id = initial_change_set + let schema_variant_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let schema_variant_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, schema_variant_id, + Ulid::new(), ContentAddress::SchemaVariant(ContentHash::from("Schema Variant A")), ) .expect("Unable to create NodeWeight"), @@ -1801,11 +1717,8 @@ mod test { initial_graph .add_edge( initial_graph.root_index, - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), schema_index, ) .expect("Unable to add root -> schema edge"); @@ -1814,24 +1727,22 @@ mod test { initial_graph .get_node_index_by_id(schema_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), schema_variant_index, ) .expect("Unable to add schema -> schema variant edge"); - let container_prop_id = initial_change_set + let container_prop_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let container_prop_index = initial_graph .add_ordered_node( - initial_change_set, + initial_vector_clock_id, NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, container_prop_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( container_prop_id.to_string().as_bytes(), )), @@ -1844,23 +1755,21 @@ mod test { initial_graph .get_node_index_by_id(schema_variant_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), container_prop_index, ) .expect("Unable to add schema variant -> container prop edge"); - let ordered_prop_1_id = initial_change_set + let ordered_prop_1_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let ordered_prop_1_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, ordered_prop_1_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_1_id.to_string().as_bytes(), )), @@ -1870,27 +1779,25 @@ mod test { .expect("Unable to add ordered prop 1"); initial_graph .add_ordered_edge( - initial_change_set.vector_clock_id(), + initial_vector_clock_id, initial_graph .get_node_index_by_id(container_prop_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), ordered_prop_1_index, ) .expect("Unable to add container prop -> ordered prop 1 edge"); - let ordered_prop_2_id = initial_change_set + let ordered_prop_2_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let ordered_prop_2_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, ordered_prop_2_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_2_id.to_string().as_bytes(), )), @@ -1900,27 +1807,25 @@ mod test { .expect("Unable to add ordered prop 2"); initial_graph .add_ordered_edge( - initial_change_set.vector_clock_id(), + initial_vector_clock_id, initial_graph .get_node_index_by_id(container_prop_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), ordered_prop_2_index, ) .expect("Unable to add container prop -> ordered prop 2 edge"); - let ordered_prop_3_id = initial_change_set + let ordered_prop_3_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let ordered_prop_3_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, ordered_prop_3_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_3_id.to_string().as_bytes(), )), @@ -1930,27 +1835,25 @@ mod test { .expect("Unable to add ordered prop 3"); initial_graph .add_ordered_edge( - initial_change_set.vector_clock_id(), + initial_vector_clock_id, initial_graph .get_node_index_by_id(container_prop_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), ordered_prop_3_index, ) .expect("Unable to add container prop -> ordered prop 3 edge"); - let ordered_prop_4_id = initial_change_set + let ordered_prop_4_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let ordered_prop_4_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, ordered_prop_4_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_4_id.to_string().as_bytes(), )), @@ -1960,36 +1863,33 @@ mod test { .expect("Unable to add ordered prop 4"); initial_graph .add_ordered_edge( - initial_change_set.vector_clock_id(), + initial_vector_clock_id, initial_graph .get_node_index_by_id(container_prop_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), ordered_prop_4_index, ) .expect("Unable to add container prop -> ordered prop 4 edge"); initial_graph.dot(); initial_graph - .mark_graph_seen(initial_change_set.vector_clock_id()) + .mark_graph_seen(initial_vector_clock_id) .expect("unable to mark graph seen"); - let new_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let new_change_set = &new_change_set; + let new_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); let mut new_graph = initial_graph.clone(); - let ordered_prop_5_id = initial_change_set + let ordered_prop_5_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let ordered_prop_5_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, ordered_prop_5_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_5_id.to_string().as_bytes(), )), @@ -1997,14 +1897,11 @@ mod test { .expect("Unable to create NodeWeight"), ) .expect("Unable to add ordered prop 5"); - let new_edge_weight = EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"); + let new_edge_weight = EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"); let (_, maybe_ordinal_edge_information) = initial_graph .add_ordered_edge( - initial_change_set.vector_clock_id(), + initial_vector_clock_id, initial_graph .get_node_index_by_id(container_prop_id) .expect("Unable to get NodeIndex"), @@ -2031,19 +1928,19 @@ mod test { .expect("could not get node weight") .id(); initial_graph - .mark_graph_seen(initial_change_set.vector_clock_id()) + .mark_graph_seen(initial_vector_clock_id) .expect("unable to mark graph seen"); new_graph - .mark_graph_seen(new_change_set.vector_clock_id()) + .mark_graph_seen(new_vector_clock_id) .expect("unable to mark graph seen"); new_graph.dot(); let ConflictsAndUpdates { conflicts, updates } = new_graph .detect_conflicts_and_updates( - new_change_set.vector_clock_id(), + new_vector_clock_id, &initial_graph, - initial_change_set.vector_clock_id(), + initial_vector_clock_id, ) .expect("Unable to detect conflicts and updates"); @@ -2128,32 +2025,34 @@ mod test { #[test] fn detect_conflicts_and_updates_simple_ordering_with_conflicting_ordering_updates() { - let initial_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let initial_change_set = &initial_change_set; - let mut initial_graph = WorkspaceSnapshotGraph::new(initial_change_set) + let actor_id = Ulid::new(); + let initial_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); + let mut initial_graph = WorkspaceSnapshotGraph::new(initial_vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); - let schema_id = initial_change_set + let schema_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let schema_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, schema_id, + Ulid::new(), ContentAddress::Schema(ContentHash::from("Schema A")), ) .expect("Unable to create NodeWeight"), ) .expect("Unable to add Schema A"); - let schema_variant_id = initial_change_set + let schema_variant_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let schema_variant_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, schema_variant_id, + Ulid::new(), ContentAddress::SchemaVariant(ContentHash::from("Schema Variant A")), ) .expect("Unable to create NodeWeight"), @@ -2163,11 +2062,8 @@ mod test { initial_graph .add_edge( initial_graph.root_index, - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), schema_index, ) .expect("Unable to add root -> schema edge"); @@ -2176,24 +2072,22 @@ mod test { initial_graph .get_node_index_by_id(schema_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), schema_variant_index, ) .expect("Unable to add schema -> schema variant edge"); - let container_prop_id = initial_change_set + let container_prop_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let container_prop_index = initial_graph .add_ordered_node( - initial_change_set, + initial_vector_clock_id, NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, container_prop_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( container_prop_id.to_string().as_bytes(), )), @@ -2206,23 +2100,21 @@ mod test { initial_graph .get_node_index_by_id(schema_variant_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), container_prop_index, ) .expect("Unable to add schema variant -> container prop edge"); - let ordered_prop_1_id = initial_change_set + let ordered_prop_1_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let ordered_prop_1_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, ordered_prop_1_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_1_id.to_string().as_bytes(), )), @@ -2232,27 +2124,25 @@ mod test { .expect("Unable to add ordered prop 1"); initial_graph .add_ordered_edge( - initial_change_set.vector_clock_id(), + initial_vector_clock_id, initial_graph .get_node_index_by_id(container_prop_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), ordered_prop_1_index, ) .expect("Unable to add container prop -> ordered prop 1 edge"); - let ordered_prop_2_id = initial_change_set + let ordered_prop_2_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let ordered_prop_2_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, ordered_prop_2_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_2_id.to_string().as_bytes(), )), @@ -2262,27 +2152,25 @@ mod test { .expect("Unable to add ordered prop 2"); initial_graph .add_ordered_edge( - initial_change_set.vector_clock_id(), + initial_vector_clock_id, initial_graph .get_node_index_by_id(container_prop_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), ordered_prop_2_index, ) .expect("Unable to add container prop -> ordered prop 2 edge"); - let ordered_prop_3_id = initial_change_set + let ordered_prop_3_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let ordered_prop_3_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, ordered_prop_3_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_3_id.to_string().as_bytes(), )), @@ -2292,27 +2180,25 @@ mod test { .expect("Unable to add ordered prop 3"); initial_graph .add_ordered_edge( - initial_change_set.vector_clock_id(), + initial_vector_clock_id, initial_graph .get_node_index_by_id(container_prop_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), ordered_prop_3_index, ) .expect("Unable to add container prop -> ordered prop 3 edge"); - let ordered_prop_4_id = initial_change_set + let ordered_prop_4_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let ordered_prop_4_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, ordered_prop_4_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_4_id.to_string().as_bytes(), )), @@ -2322,26 +2208,22 @@ mod test { .expect("Unable to add ordered prop 4"); initial_graph .add_ordered_edge( - initial_change_set.vector_clock_id(), + initial_vector_clock_id, initial_graph .get_node_index_by_id(container_prop_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), ordered_prop_4_index, ) .expect("Unable to add container prop -> ordered prop 4 edge"); initial_graph.dot(); initial_graph - .mark_graph_seen(initial_change_set.vector_clock_id()) + .mark_graph_seen(initial_vector_clock_id) .expect("unable to mark graph seen"); - let new_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let new_change_set = &new_change_set; + let new_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); let mut new_graph = initial_graph.clone(); let new_order = vec![ @@ -2351,21 +2233,18 @@ mod test { ordered_prop_3_id, ]; new_graph - .update_order( - new_change_set.vector_clock_id(), - container_prop_id, - new_order, - ) + .update_order(new_vector_clock_id, container_prop_id, new_order) .expect("Unable to update order of container prop's children"); - let ordered_prop_5_id = initial_change_set + let ordered_prop_5_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let ordered_prop_5_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, ordered_prop_5_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_5_id.to_string().as_bytes(), )), @@ -2373,14 +2252,11 @@ mod test { .expect("Unable to create NodeWeight"), ) .expect("Unable to add ordered prop 5"); - let new_edge_weight = EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"); + let new_edge_weight = EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"); let (_, maybe_ordinal_edge_information) = initial_graph .add_ordered_edge( - initial_change_set.vector_clock_id(), + initial_vector_clock_id, initial_graph .get_node_index_by_id(container_prop_id) .expect("Unable to get NodeIndex"), @@ -2408,20 +2284,20 @@ mod test { .id(); initial_graph - .mark_graph_seen(initial_change_set.vector_clock_id()) + .mark_graph_seen(initial_vector_clock_id) .expect("unable to mark graph seen"); new_graph.cleanup(); new_graph - .mark_graph_seen(new_change_set.vector_clock_id()) + .mark_graph_seen(new_vector_clock_id) .expect("unable to mark graph seen"); new_graph.dot(); let ConflictsAndUpdates { conflicts, updates } = new_graph .detect_conflicts_and_updates( - new_change_set.vector_clock_id(), + new_vector_clock_id, &initial_graph, - initial_change_set.vector_clock_id(), + initial_vector_clock_id, ) .expect("Unable to detect conflicts and updates"); @@ -2513,32 +2389,34 @@ mod test { #[test] fn detect_conflicts_and_updates_simple_ordering_with_no_conflicts_add_in_onto_remove_in_to_rebase( ) { - let initial_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let initial_change_set = &initial_change_set; - let mut initial_graph = WorkspaceSnapshotGraph::new(initial_change_set) + let actor_id = Ulid::new(); + let initial_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); + let mut initial_graph = WorkspaceSnapshotGraph::new(initial_vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); - let schema_id = initial_change_set + let schema_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let schema_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, schema_id, + Ulid::new(), ContentAddress::Schema(ContentHash::from("Schema A")), ) .expect("Unable to create NodeWeight"), ) .expect("Unable to add Schema A"); - let schema_variant_id = initial_change_set + let schema_variant_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let schema_variant_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, schema_variant_id, + Ulid::new(), ContentAddress::SchemaVariant(ContentHash::from("Schema Variant A")), ) .expect("Unable to create NodeWeight"), @@ -2548,11 +2426,8 @@ mod test { initial_graph .add_edge( initial_graph.root_index, - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), schema_index, ) .expect("Unable to add root -> schema edge"); @@ -2561,24 +2436,22 @@ mod test { initial_graph .get_node_index_by_id(schema_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), schema_variant_index, ) .expect("Unable to add schema -> schema variant edge"); - let container_prop_id = initial_change_set + let container_prop_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let container_prop_index = initial_graph .add_ordered_node( - initial_change_set, + initial_vector_clock_id, NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, container_prop_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( container_prop_id.to_string().as_bytes(), )), @@ -2591,23 +2464,21 @@ mod test { initial_graph .get_node_index_by_id(schema_variant_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), container_prop_index, ) .expect("Unable to add schema variant -> container prop edge"); - let ordered_prop_1_id = initial_change_set + let ordered_prop_1_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let ordered_prop_1_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, ordered_prop_1_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_1_id.to_string().as_bytes(), )), @@ -2617,29 +2488,27 @@ mod test { .expect("Unable to add ordered prop 1"); initial_graph .add_ordered_edge( - initial_change_set.vector_clock_id(), + initial_vector_clock_id, initial_graph .get_node_index_by_id(container_prop_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), ordered_prop_1_index, ) .expect("Unable to add container prop -> ordered prop 1 edge"); println!("added ordered edge from {container_prop_id} to {ordered_prop_1_id} in onto"); - let ordered_prop_2_id = initial_change_set + let ordered_prop_2_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let ordered_prop_2_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, ordered_prop_2_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_2_id.to_string().as_bytes(), )), @@ -2649,29 +2518,27 @@ mod test { .expect("Unable to add ordered prop 2"); initial_graph .add_ordered_edge( - initial_change_set.vector_clock_id(), + initial_vector_clock_id, initial_graph .get_node_index_by_id(container_prop_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), ordered_prop_2_index, ) .expect("Unable to add container prop -> ordered prop 2 edge"); println!("added ordered edge from {container_prop_id} to {ordered_prop_2_id} in onto"); - let ordered_prop_3_id = initial_change_set + let ordered_prop_3_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let ordered_prop_3_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, ordered_prop_3_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_3_id.to_string().as_bytes(), )), @@ -2681,29 +2548,27 @@ mod test { .expect("Unable to add ordered prop 3"); initial_graph .add_ordered_edge( - initial_change_set.vector_clock_id(), + initial_vector_clock_id, initial_graph .get_node_index_by_id(container_prop_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), ordered_prop_3_index, ) .expect("Unable to add container prop -> ordered prop 3 edge"); println!("added ordered edge from {container_prop_id} to {ordered_prop_3_id} in onto"); - let ordered_prop_4_id = initial_change_set + let ordered_prop_4_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let ordered_prop_4_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, ordered_prop_4_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_4_id.to_string().as_bytes(), )), @@ -2713,15 +2578,12 @@ mod test { .expect("Unable to add ordered prop 4"); initial_graph .add_ordered_edge( - initial_change_set.vector_clock_id(), + initial_vector_clock_id, initial_graph .get_node_index_by_id(container_prop_id) .expect("Unable to get NodeIndex"), - EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"), + EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"), ordered_prop_4_index, ) .expect("Unable to add container prop -> ordered prop 4 edge"); @@ -2730,17 +2592,17 @@ mod test { initial_graph.cleanup(); initial_graph - .mark_graph_seen(initial_change_set.vector_clock_id()) + .mark_graph_seen(initial_vector_clock_id) .expect("Unable to update recently seen information"); // initial_graph.dot(); - let new_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let new_change_set = &new_change_set; + let new_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); + let mut new_graph = initial_graph.clone(); new_graph .remove_edge( - new_change_set, + new_vector_clock_id, new_graph .get_node_index_by_id(container_prop_id) .expect("Unable to get container NodeIndex"), @@ -2751,14 +2613,15 @@ mod test { println!("removed edge from {container_prop_id} to {ordered_prop_2_id} in to_rebase"); - let ordered_prop_5_id = initial_change_set + let ordered_prop_5_id = initial_graph .generate_ulid() .expect("Unable to generate Ulid"); let ordered_prop_5_index = initial_graph .add_node( NodeWeight::new_content( - initial_change_set, + initial_vector_clock_id, ordered_prop_5_id, + Ulid::new(), ContentAddress::Prop(ContentHash::new( ordered_prop_5_id.to_string().as_bytes(), )), @@ -2767,14 +2630,11 @@ mod test { ) .expect("Unable to add ordered prop 5"); - let new_edge_weight = EdgeWeight::new( - initial_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("Unable to create EdgeWeight"); + let new_edge_weight = EdgeWeight::new(initial_vector_clock_id, EdgeWeightKind::new_use()) + .expect("Unable to create EdgeWeight"); let (_, maybe_ordinal_edge_information) = initial_graph .add_ordered_edge( - initial_change_set.vector_clock_id(), + initial_vector_clock_id, initial_graph .get_node_index_by_id(container_prop_id) .expect("Unable to get NodeIndex"), @@ -2805,13 +2665,13 @@ mod test { initial_graph.cleanup(); //initial_graph.dot(); initial_graph - .mark_graph_seen(initial_change_set.vector_clock_id()) + .mark_graph_seen(initial_vector_clock_id) .expect("unable mark graph seen"); new_graph.cleanup(); //new_graph.dot(); new_graph - .mark_graph_seen(new_change_set.vector_clock_id()) + .mark_graph_seen(new_vector_clock_id) .expect("unable to mark graph seen"); // initial_graph.tiny_dot_to_file(Some("onto")); @@ -2819,9 +2679,9 @@ mod test { let ConflictsAndUpdates { conflicts, updates } = new_graph .detect_conflicts_and_updates( - new_change_set.vector_clock_id(), + new_vector_clock_id, &initial_graph, - initial_change_set.vector_clock_id(), + initial_vector_clock_id, ) .expect("Unable to detect conflicts and updates"); @@ -2874,10 +2734,10 @@ mod test { fn detect_conflicts_and_updates_single_removal_update() { let nodes = ["a", "b", "c"]; let edges = [(None, "a"), (None, "b"), (Some("a"), "c"), (Some("c"), "b")]; + let actor_id = Ulid::new(); - let base_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let base_change_set = &base_change_set; - let mut base_graph = WorkspaceSnapshotGraph::new(base_change_set) + let base_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); + let mut base_graph = WorkspaceSnapshotGraph::new(base_vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); // Add all nodes from the slice and store their references in a hash map. @@ -2885,12 +2745,11 @@ mod test { for node in nodes { // "props" here are just nodes that are easy to create and render the name on the dot // output. there is no domain modeling in this test. - let node_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let node_id = base_graph.generate_ulid().expect("Unable to generate Ulid"); let prop_node_weight = NodeWeight::new_prop( - base_change_set, + base_vector_clock_id, node_id, + Ulid::new(), PropKind::Object, node, ContentHash::new(node.as_bytes()), @@ -2929,7 +2788,7 @@ mod test { base_graph .add_edge( source, - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(base_vector_clock_id, EdgeWeightKind::new_use()) .expect("create edge weight"), target, ) @@ -2987,11 +2846,11 @@ mod test { // Prepare the graph for "forking" and fork it. Create a new change set after. base_graph - .mark_graph_seen(base_change_set.vector_clock_id()) + .mark_graph_seen(base_vector_clock_id) .expect("could not mark as seen"); let mut new_graph = base_graph.clone(); - let new_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let new_change_set = &new_change_set; + + let new_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); // Remove the first edge involving "c". let a_idx = new_graph @@ -3002,7 +2861,7 @@ mod test { .expect("could not get node index by id"); new_graph .remove_edge( - new_change_set, + new_vector_clock_id, a_idx, c_idx, EdgeWeightKindDiscriminants::Use, @@ -3018,7 +2877,7 @@ mod test { .expect("could not get node index by id"); new_graph .remove_edge( - new_change_set, + new_vector_clock_id, c_idx, b_idx, EdgeWeightKindDiscriminants::Use, @@ -3031,7 +2890,7 @@ mod test { // Prepare for conflicts and updates detection new_graph - .mark_graph_seen(new_change_set.vector_clock_id()) + .mark_graph_seen(new_vector_clock_id) .expect("could not mark graph seen"); new_graph.cleanup(); @@ -3039,11 +2898,7 @@ mod test { // new_graph.tiny_dot_to_file(Some("onto")); let ConflictsAndUpdates { conflicts, updates } = base_graph - .detect_conflicts_and_updates( - base_change_set.vector_clock_id(), - &new_graph, - new_change_set.vector_clock_id(), - ) + .detect_conflicts_and_updates(base_vector_clock_id, &new_graph, new_vector_clock_id) .expect("Unable to detect conflicts and updates"); assert_eq!( @@ -3067,24 +2922,28 @@ mod test { #[test] fn detect_exclusive_edge_conflict() { - let base_change_set = ChangeSet::new_local().expect("Unable to create local change set"); - let base_change_set = &base_change_set; + let actor_id = Ulid::new(); + let base_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); let mut base_graph = - WorkspaceSnapshotGraph::new(base_change_set).expect("Unable to make base graph"); + WorkspaceSnapshotGraph::new(base_vector_clock_id).expect("Unable to make base graph"); - let av_id = base_change_set - .generate_ulid() - .expect("Unable to generate Ulid"); + let av_id = base_graph.generate_ulid().expect("Unable to generate Ulid"); base_graph .add_node( - NodeWeight::new_attribute_value(base_change_set, av_id, None, None) - .expect("Unable to create AttributeValue"), + NodeWeight::new_attribute_value( + base_vector_clock_id, + av_id, + Ulid::new(), + None, + None, + ) + .expect("Unable to create AttributeValue"), ) .expect("Unable to add AttributeValue"); base_graph .add_edge( base_graph.root_index, - EdgeWeight::new(base_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(base_vector_clock_id, EdgeWeightKind::new_use()) .expect("Unable to create edge weight"), base_graph .get_node_index_by_id(av_id) @@ -3093,21 +2952,21 @@ mod test { .expect("Unable to add root -> AV Use edge"); base_graph.cleanup(); base_graph - .mark_graph_seen(base_change_set.vector_clock_id()) + .mark_graph_seen(base_vector_clock_id) .expect("Unable to mark base graph as seen"); - let new_change_set = ChangeSet::new_local().expect("Unable to create local change set"); - let new_change_set = &new_change_set; + let new_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); let mut new_changes_graph = base_graph.clone(); - let prototype_a_id = new_change_set + let prototype_a_id = new_changes_graph .generate_ulid() .expect("Unable to generate Ulid"); new_changes_graph .add_node( NodeWeight::new_content( - new_change_set, + new_vector_clock_id, prototype_a_id, + Ulid::new(), ContentAddress::AttributePrototype(ContentHash::new( "Prototype A".to_string().as_bytes(), )), @@ -3120,11 +2979,8 @@ mod test { new_changes_graph .get_node_index_by_id(av_id) .expect("Unable to get AV node index"), - EdgeWeight::new( - new_change_set.vector_clock_id(), - EdgeWeightKind::Prototype(None), - ) - .expect("Unable to create edge weight"), + EdgeWeight::new(new_vector_clock_id, EdgeWeightKind::Prototype(None)) + .expect("Unable to create edge weight"), new_changes_graph .get_node_index_by_id(prototype_a_id) .expect("Unable to get node index for AttributePrototype"), @@ -3132,7 +2988,7 @@ mod test { .expect("Unable to add AV -> AttributePrototype Prototype edge"); new_changes_graph.cleanup(); new_changes_graph - .mark_graph_seen(new_change_set.vector_clock_id()) + .mark_graph_seen(new_vector_clock_id) .expect("Unable to mark new changes graph as seen"); let ConflictsAndUpdates { @@ -3140,27 +2996,26 @@ mod test { updates: _, } = base_graph .detect_conflicts_and_updates( - base_change_set.vector_clock_id(), + base_vector_clock_id, &new_changes_graph, - new_change_set.vector_clock_id(), + new_vector_clock_id, ) .expect("able to detect conflicts and updates"); assert_eq!(Vec::::new(), conflicts); - let conflicting_change_set = - ChangeSet::new_local().expect("Unable to create local change set"); - let conflicting_change_set = &conflicting_change_set; + let conflicting_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); let mut conflicting_graph = new_changes_graph.clone(); - let prototype_b_id = conflicting_change_set + let prototype_b_id = conflicting_graph .generate_ulid() .expect("Unable to generate Ulid"); conflicting_graph .add_node( NodeWeight::new_content( - conflicting_change_set, + conflicting_vector_clock_id, prototype_b_id, + Ulid::new(), ContentAddress::AttributePrototype(ContentHash::new( "Prototype B".to_string().as_bytes(), )), @@ -3173,11 +3028,8 @@ mod test { conflicting_graph .get_node_index_by_id(av_id) .expect("Unable to get AV node index"), - EdgeWeight::new( - conflicting_change_set.vector_clock_id(), - EdgeWeightKind::Prototype(None), - ) - .expect("Unable to create edge weight"), + EdgeWeight::new(conflicting_vector_clock_id, EdgeWeightKind::Prototype(None)) + .expect("Unable to create edge weight"), conflicting_graph .get_node_index_by_id(prototype_b_id) .expect("Unable to get node index for AttributePrototype"), @@ -3186,7 +3038,7 @@ mod test { conflicting_graph.cleanup(); conflicting_graph - .mark_graph_seen(conflicting_change_set.vector_clock_id()) + .mark_graph_seen(conflicting_vector_clock_id) .expect("Unable to mark conflicting graph as seen"); let ConflictsAndUpdates { @@ -3194,9 +3046,9 @@ mod test { updates: _, } = new_changes_graph .detect_conflicts_and_updates( - new_change_set.vector_clock_id(), + new_vector_clock_id, &conflicting_graph, - conflicting_change_set.vector_clock_id(), + conflicting_vector_clock_id, ) .expect("able to detect conflicts and updates"); @@ -3226,9 +3078,9 @@ mod test { updates: _, } = base_graph .detect_conflicts_and_updates( - base_change_set.vector_clock_id(), + base_vector_clock_id, &conflicting_graph, - conflicting_change_set.vector_clock_id(), + conflicting_vector_clock_id, ) .expect("able to detect conflicts and updates"); @@ -3278,14 +3130,17 @@ mod test { #[test] fn detect_conflicts_and_updates_remove_edge_simple() { - let to_rebase_change_set = ChangeSet::new_local().expect("create cset"); - let mut to_rebase_graph = WorkspaceSnapshotGraph::new(&to_rebase_change_set) + let actor_id = Ulid::new(); + let to_rebase_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); + + let mut to_rebase_graph = WorkspaceSnapshotGraph::new(to_rebase_vector_clock_id) .expect("unable to make to_rebase_graph"); - let prototype_node_id = to_rebase_change_set.generate_ulid().expect("gen ulid"); + let prototype_node_id = to_rebase_graph.generate_ulid().expect("gen ulid"); let prototype_node = NodeWeight::new_content( - &to_rebase_change_set, + to_rebase_vector_clock_id, prototype_node_id, + Ulid::new(), ContentAddress::AttributePrototype(ContentHash::from("prototype")), ) .expect("unable to create prototype node weight"); @@ -3296,11 +3151,8 @@ mod test { to_rebase_graph .add_edge( to_rebase_graph.root(), - EdgeWeight::new( - to_rebase_change_set.vector_clock_id(), - EdgeWeightKind::Prototype(None), - ) - .expect("make edge weight"), + EdgeWeight::new(to_rebase_vector_clock_id, EdgeWeightKind::Prototype(None)) + .expect("make edge weight"), to_rebase_graph .get_node_index_by_id(prototype_node_id) .expect("get_node_index_by_id"), @@ -3310,16 +3162,16 @@ mod test { // "write" the graph to_rebase_graph.cleanup(); to_rebase_graph - .mark_graph_seen(to_rebase_change_set.vector_clock_id()) + .mark_graph_seen(to_rebase_vector_clock_id) .expect("mark_graph_seen"); // "fork" a working changeset from the current one - let onto_change_set = ChangeSet::new_local().expect("new_local"); + let onto_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); let mut onto_graph = to_rebase_graph.clone(); onto_graph .remove_edge( - &onto_change_set, + onto_vector_clock_id, onto_graph.root(), to_rebase_graph .get_node_index_by_id(prototype_node_id) @@ -3330,14 +3182,14 @@ mod test { onto_graph.cleanup(); onto_graph - .mark_graph_seen(onto_change_set.vector_clock_id()) + .mark_graph_seen(onto_vector_clock_id) .expect("mark_graph_seen"); let ConflictsAndUpdates { conflicts, updates } = to_rebase_graph .detect_conflicts_and_updates( - to_rebase_change_set.vector_clock_id(), + to_rebase_vector_clock_id, &onto_graph, - onto_change_set.vector_clock_id(), + onto_vector_clock_id, ) .expect("detect_conflicts_and_updates"); @@ -3354,14 +3206,16 @@ mod test { #[test] fn detect_conflicts_and_updates_remove_modified_item_conflict() { - let to_rebase_change_set = ChangeSet::new_local().expect("create cset"); - let mut to_rebase_graph = WorkspaceSnapshotGraph::new(&to_rebase_change_set) + let actor_id = Ulid::new(); + let to_rebase_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); + let mut to_rebase_graph = WorkspaceSnapshotGraph::new(to_rebase_vector_clock_id) .expect("unable to make to_rebase_graph"); - let prototype_node_id = to_rebase_change_set.generate_ulid().expect("gen ulid"); + let prototype_node_id = to_rebase_graph.generate_ulid().expect("gen ulid"); let prototype_node = NodeWeight::new_content( - &to_rebase_change_set, + to_rebase_vector_clock_id, prototype_node_id, + Ulid::new(), ContentAddress::AttributePrototype(ContentHash::from("prototype")), ) .expect("unable to create prototype node weight"); @@ -3372,11 +3226,8 @@ mod test { to_rebase_graph .add_edge( to_rebase_graph.root(), - EdgeWeight::new( - to_rebase_change_set.vector_clock_id(), - EdgeWeightKind::Prototype(None), - ) - .expect("make edge weight"), + EdgeWeight::new(to_rebase_vector_clock_id, EdgeWeightKind::Prototype(None)) + .expect("make edge weight"), to_rebase_graph .get_node_index_by_id(prototype_node_id) .expect("get_node_index_by_id"), @@ -3386,17 +3237,17 @@ mod test { // "write" the graph to_rebase_graph.cleanup(); to_rebase_graph - .mark_graph_seen(to_rebase_change_set.vector_clock_id()) + .mark_graph_seen(to_rebase_vector_clock_id) .expect("mark_graph_seen"); // "fork" a working changeset from the current one - let onto_change_set = ChangeSet::new_local().expect("new_local"); + let onto_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); let mut onto_graph = to_rebase_graph.clone(); // After the fork, remove the edge in to_rebase, but modify the edge in onto to_rebase_graph .remove_edge( - &onto_change_set, + onto_vector_clock_id, onto_graph.root(), to_rebase_graph .get_node_index_by_id(prototype_node_id) @@ -3406,7 +3257,7 @@ mod test { .expect("remove_edge"); to_rebase_graph.cleanup(); to_rebase_graph - .mark_graph_seen(to_rebase_change_set.vector_clock_id()) + .mark_graph_seen(to_rebase_vector_clock_id) .expect("mark_graph_seen"); let onto_content_node_idx = onto_graph @@ -3424,7 +3275,7 @@ mod test { content_node .new_content_hash(ContentHash::from("prototype_change")) .expect("update_content_hash"); - content_node.increment_vector_clocks(onto_change_set.vector_clock_id()); + content_node.increment_vector_clocks(onto_vector_clock_id); onto_graph .add_node(NodeWeight::Content(content_node)) .expect("add_node"); @@ -3433,14 +3284,14 @@ mod test { .expect("replace_references"); onto_graph.cleanup(); onto_graph - .mark_graph_seen(onto_change_set.vector_clock_id()) + .mark_graph_seen(onto_vector_clock_id) .expect("mark_graph_seen"); let ConflictsAndUpdates { conflicts, updates } = to_rebase_graph .detect_conflicts_and_updates( - to_rebase_change_set.vector_clock_id(), + to_rebase_vector_clock_id, &onto_graph, - onto_change_set.vector_clock_id(), + onto_vector_clock_id, ) .expect("detect_conflicts_and_updates"); @@ -3481,19 +3332,25 @@ mod test { #[test] fn test_merge_dependent_value_roots() { - let to_rebase_change_set = ChangeSet::new_local().expect("create cset"); - let mut to_rebase_graph = WorkspaceSnapshotGraph::new(&to_rebase_change_set) + let actor_id = Ulid::new(); + let to_rebase_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); + let mut to_rebase_graph = WorkspaceSnapshotGraph::new(to_rebase_vector_clock_id) .expect("unable to make to_rebase_graph"); to_rebase_graph - .mark_graph_seen(to_rebase_change_set.vector_clock_id()) + .mark_graph_seen(to_rebase_vector_clock_id) .expect("unable to mark graph seen"); - let onto_change_set = ChangeSet::new_local().expect("new_local"); + let onto_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); let mut onto_graph = to_rebase_graph.clone(); let cat_node_idx = to_rebase_graph - .add_category_node(&to_rebase_change_set, DependentValueRoots) + .add_category_node( + to_rebase_vector_clock_id, + Ulid::new(), + Ulid::new(), + DependentValueRoots, + ) .expect("able to add dvu root cat node"); let to_rebase_cat_node_orig_weight = to_rebase_graph .get_node_weight(cat_node_idx) @@ -3502,49 +3359,47 @@ mod test { to_rebase_graph .add_edge( to_rebase_graph.root_index, - EdgeWeight::new( - to_rebase_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("unable to make edge weigh"), + EdgeWeight::new(to_rebase_vector_clock_id, EdgeWeightKind::new_use()) + .expect("unable to make edge weigh"), cat_node_idx, ) .expect("unable add edge "); let cat_node_idx = onto_graph - .add_category_node(&onto_change_set, DependentValueRoots) + .add_category_node( + onto_vector_clock_id, + Ulid::new(), + Ulid::new(), + DependentValueRoots, + ) .expect("unable to add dvu root cat node"); onto_graph .add_edge( onto_graph.root_index, - EdgeWeight::new(onto_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(onto_vector_clock_id, EdgeWeightKind::new_use()) .expect("unable to make edge weigh"), cat_node_idx, ) .expect("unable add edge "); - let shared_value_id = to_rebase_change_set - .generate_ulid() - .expect("unable to gen ulid"); + let shared_value_id = to_rebase_graph.generate_ulid().expect("unable to gen ulid"); - let unique_to_rebase_value_id = to_rebase_change_set + let unique_to_rebase_value_id = to_rebase_graph .generate_ulid() .expect("unable to generate ulid"); - let unique_to_onto_value_id = onto_change_set - .generate_ulid() - .expect("unable to generate ulid"); + let unique_to_onto_value_id = onto_graph.generate_ulid().expect("unable to generate ulid"); let to_rebase_value_ids = [unique_to_rebase_value_id, shared_value_id]; let onto_value_ids = [unique_to_onto_value_id, shared_value_id]; - for (graph, change_set, values) in [ + for (graph, vector_clock_id, values) in [ ( &mut to_rebase_graph, - &to_rebase_change_set, + to_rebase_vector_clock_id, &to_rebase_value_ids, ), - (&mut onto_graph, &onto_change_set, &onto_value_ids), + (&mut onto_graph, onto_vector_clock_id, &onto_value_ids), ] { let (cat_id, _) = graph .get_category_node(None, DependentValueRoots) @@ -3552,15 +3407,20 @@ mod test { .expect("cat node for dvu roots not there"); for value_id in values { - let node_weight = NodeWeight::new_dependent_value_root(change_set, *value_id) - .expect("unable to make root node weight"); + let node_weight = NodeWeight::new_dependent_value_root( + vector_clock_id, + Ulid::new(), + Ulid::new(), + *value_id, + ) + .expect("unable to make root node weight"); let dvu_root_idx = graph.add_node(node_weight).expect("unable to add node"); graph .add_edge( graph .get_node_index_by_id(cat_id) .expect("unable to get node index for category"), - EdgeWeight::new(change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(vector_clock_id, EdgeWeightKind::new_use()) .expect("unable to make edge weight"), dvu_root_idx, ) @@ -3571,29 +3431,29 @@ mod test { to_rebase_graph.cleanup(); onto_graph.cleanup(); to_rebase_graph - .mark_graph_seen(to_rebase_change_set.vector_clock_id()) + .mark_graph_seen(to_rebase_vector_clock_id) .expect("unable to mark graph seen"); onto_graph - .mark_graph_seen(onto_change_set.vector_clock_id()) + .mark_graph_seen(onto_vector_clock_id) .expect("unable to mark graph seen"); let ConflictsAndUpdates { conflicts, updates } = to_rebase_graph .detect_conflicts_and_updates( - to_rebase_change_set.vector_clock_id(), + to_rebase_vector_clock_id, &onto_graph, - onto_change_set.vector_clock_id(), + onto_vector_clock_id, ) .expect("able to detect conflicts and updates"); assert!(conflicts.is_empty()); to_rebase_graph - .perform_updates(&to_rebase_change_set, &onto_graph, &updates) + .perform_updates(to_rebase_vector_clock_id, &onto_graph, &updates) .expect("unable to perform updates"); to_rebase_graph.cleanup(); to_rebase_graph - .mark_graph_seen(to_rebase_change_set.vector_clock_id()) + .mark_graph_seen(to_rebase_vector_clock_id) .expect("unable to mark graph seen"); let neighbors_of_root: Vec = to_rebase_graph diff --git a/lib/dal/src/workspace_snapshot/graph/tests/rebase.rs b/lib/dal/src/workspace_snapshot/graph/tests/rebase.rs index cb8689e7f1..dd110c1e11 100644 --- a/lib/dal/src/workspace_snapshot/graph/tests/rebase.rs +++ b/lib/dal/src/workspace_snapshot/graph/tests/rebase.rs @@ -2,9 +2,9 @@ #[cfg(test)] mod test { use pretty_assertions_sorted::assert_eq; - use si_events::ContentHash; + use si_events::ulid::Ulid; + use si_events::{ContentHash, VectorClockId}; - use crate::change_set::ChangeSet; use crate::func::FuncKind; use crate::workspace_snapshot::content_address::ContentAddress; use crate::workspace_snapshot::edge_weight::{EdgeWeight, EdgeWeightKind}; @@ -16,53 +16,55 @@ mod test { #[test] fn simulate_rebase() { - let to_rebase_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let to_rebase_change_set = &to_rebase_change_set; - let mut to_rebase = WorkspaceSnapshotGraph::new(to_rebase_change_set) + let actor_id = Ulid::new(); + let to_rebase_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); + let mut to_rebase = WorkspaceSnapshotGraph::new(to_rebase_vector_clock_id) .expect("Unable to create WorkspaceSnapshotGraph"); // Set up the to rebase graph. let schema_category_node_index = to_rebase - .add_category_node(to_rebase_change_set, CategoryNodeKind::Schema) + .add_category_node( + to_rebase_vector_clock_id, + Ulid::new(), + Ulid::new(), + CategoryNodeKind::Schema, + ) .expect("could not add category node"); to_rebase .add_edge( to_rebase.root_index, - EdgeWeight::new( - to_rebase_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("could not create edge weight"), + EdgeWeight::new(to_rebase_vector_clock_id, EdgeWeightKind::new_use()) + .expect("could not create edge weight"), schema_category_node_index, ) .expect("could not add edge"); let func_category_node_index = to_rebase - .add_category_node(to_rebase_change_set, CategoryNodeKind::Func) + .add_category_node( + to_rebase_vector_clock_id, + Ulid::new(), + Ulid::new(), + CategoryNodeKind::Func, + ) .expect("could not add category node"); to_rebase .add_edge( to_rebase.root_index, - EdgeWeight::new( - to_rebase_change_set.vector_clock_id(), - EdgeWeightKind::new_use(), - ) - .expect("could not create edge weight"), + EdgeWeight::new(to_rebase_vector_clock_id, EdgeWeightKind::new_use()) + .expect("could not create edge weight"), func_category_node_index, ) .expect("could not add edge"); // Create the onto graph from the to rebase graph. - let onto_change_set = ChangeSet::new_local().expect("Unable to create ChangeSet"); - let onto_change_set = &onto_change_set; + let onto_vector_clock_id = VectorClockId::new(Ulid::new(), actor_id); let mut onto = to_rebase.clone(); // FuncCategory --Use--> Func - let func_id = onto_change_set - .generate_ulid() - .expect("could not generate ulid"); + let func_id = onto.generate_ulid().expect("could not generate ulid"); let func_node_weight = FuncNodeWeight::new( - onto_change_set, + onto_vector_clock_id, func_id, + Ulid::new(), ContentAddress::Func(ContentHash::from("foo")), "foo".to_string(), FuncKind::Intrinsic, @@ -73,7 +75,7 @@ mod test { .expect("could not add node"); onto.add_edge( func_category_node_index, - EdgeWeight::new(onto_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(onto_vector_clock_id, EdgeWeightKind::new_use()) .expect("could not create edge weight"), func_node_index, ) @@ -81,10 +83,9 @@ mod test { // SchemaCategory --Use--> Schema let schema_node_weight = ContentNodeWeight::new( - onto_change_set, - onto_change_set - .generate_ulid() - .expect("could not generate ulid"), + onto_vector_clock_id, + onto.generate_ulid().expect("could not generate ulid"), + Ulid::new(), ContentAddress::Schema(ContentHash::from("foo")), ) .expect("could not create func node weight"); @@ -93,7 +94,7 @@ mod test { .expect("could not add node"); onto.add_edge( schema_category_node_index, - EdgeWeight::new(onto_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(onto_vector_clock_id, EdgeWeightKind::new_use()) .expect("could not create edge weight"), schema_node_index, ) @@ -101,10 +102,9 @@ mod test { // Schema --Use--> SchemaVariant let schema_variant_node_weight = ContentNodeWeight::new( - onto_change_set, - onto_change_set - .generate_ulid() - .expect("could not generate ulid"), + onto_vector_clock_id, + onto.generate_ulid().expect("could not generate ulid"), + Ulid::new(), ContentAddress::SchemaVariant(ContentHash::from("foo")), ) .expect("could not create func node weight"); @@ -113,7 +113,7 @@ mod test { .expect("could not add node"); onto.add_edge( schema_node_index, - EdgeWeight::new(onto_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(onto_vector_clock_id, EdgeWeightKind::new_use()) .expect("could not create edge weight"), schema_variant_node_index, ) @@ -125,7 +125,7 @@ mod test { .expect("could not get node index by id"); onto.add_edge( schema_variant_node_index, - EdgeWeight::new(onto_change_set.vector_clock_id(), EdgeWeightKind::new_use()) + EdgeWeight::new(onto_vector_clock_id, EdgeWeightKind::new_use()) .expect("could not create edge weight"), func_node_index, ) @@ -136,11 +136,7 @@ mod test { conflicts: before_cleanup_conflicts, updates: before_cleanup_updates, } = to_rebase - .detect_conflicts_and_updates( - to_rebase_change_set.vector_clock_id(), - &onto, - onto_change_set.vector_clock_id(), - ) + .detect_conflicts_and_updates(to_rebase_vector_clock_id, &onto, onto_vector_clock_id) .expect("could not detect conflicts and updates"); // Cleanup and check node count. @@ -153,11 +149,7 @@ mod test { // Detect conflicts and updates. Ensure cleanup did not affect the results. let ConflictsAndUpdates { conflicts, updates } = to_rebase - .detect_conflicts_and_updates( - to_rebase_change_set.vector_clock_id(), - &onto, - onto_change_set.vector_clock_id(), - ) + .detect_conflicts_and_updates(to_rebase_vector_clock_id, &onto, onto_vector_clock_id) .expect("could not detect conflicts and updates"); assert!(conflicts.is_empty()); assert_eq!( @@ -184,7 +176,7 @@ mod test { // Perform the updates. In the future, we may want to see if the onto and resulting to // rebase graphs are logically equivalent after updates are performed. to_rebase - .perform_updates(to_rebase_change_set, &onto, &updates) + .perform_updates(to_rebase_vector_clock_id, &onto, &updates) .expect("could not perform updates"); } } diff --git a/lib/dal/src/workspace_snapshot/node_weight.rs b/lib/dal/src/workspace_snapshot/node_weight.rs index 51474bbd84..74b1306260 100644 --- a/lib/dal/src/workspace_snapshot/node_weight.rs +++ b/lib/dal/src/workspace_snapshot/node_weight.rs @@ -10,7 +10,6 @@ use crate::workspace_snapshot::vector_clock::VectorClockId; use crate::EdgeWeightKindDiscriminants; use crate::{ action::prototype::ActionKind, - change_set::{ChangeSet, ChangeSetError}, workspace_snapshot::{ content_address::ContentAddress, vector_clock::{HasVectorClocks, VectorClock, VectorClockError}, @@ -59,8 +58,8 @@ pub enum NodeWeightError { CannotSetOrderOnKind, #[error("Cannot update root node's content hash")] CannotUpdateRootNodeContentHash, - #[error("ChangeSet error: {0}")] - ChangeSet(#[from] ChangeSetError), + // #[error("ChangeSet error: {0}")] + // ChangeSet(#[from] ChangeSetError), #[error("Incompatible node weights")] IncompatibleNodeWeightVariants, #[error("Invalid ContentAddress variant ({0}) for NodeWeight variant ({1})")] @@ -310,11 +309,11 @@ impl NodeWeight { pub fn set_vector_clock_recently_seen_to( &mut self, - change_set: &ChangeSet, + vector_clock_id: VectorClockId, new_clock_value: DateTime, ) { self.vector_clock_recently_seen_mut() - .inc_to(change_set.vector_clock_id(), new_clock_value); + .inc_to(vector_clock_id, new_clock_value); } pub fn remove_vector_clock_entries(&mut self, allow_list: &[VectorClockId]) { @@ -513,37 +512,45 @@ impl NodeWeight { } pub fn new_content( - change_set: &ChangeSet, - content_id: Ulid, + vector_clock_id: VectorClockId, + id: Ulid, + lineage_id: Ulid, kind: ContentAddress, ) -> NodeWeightResult { Ok(NodeWeight::Content(ContentNodeWeight::new( - change_set, content_id, kind, + vector_clock_id, + id, + lineage_id, + kind, )?)) } pub fn new_action( - change_set: &ChangeSet, + vector_clock_id: VectorClockId, originating_change_set_id: ChangeSetId, action_id: Ulid, + lineage_id: Ulid, ) -> NodeWeightResult { Ok(NodeWeight::Action(ActionNodeWeight::new( - change_set, + vector_clock_id, originating_change_set_id, action_id, + lineage_id, )?)) } pub fn new_action_prototype( - change_set: &ChangeSet, - action_id: Ulid, + vector_clock_id: VectorClockId, + action_prototype_id: Ulid, + lineage_id: Ulid, kind: ActionKind, name: String, description: Option, ) -> NodeWeightResult { Ok(NodeWeight::ActionPrototype(ActionPrototypeNodeWeight::new( - change_set, - action_id, + vector_clock_id, + action_prototype_id, + lineage_id, kind, name, description, @@ -551,50 +558,58 @@ impl NodeWeight { } pub fn new_attribute_value( - change_set: &ChangeSet, + vector_clock_id: VectorClockId, attribute_value_id: Ulid, + lineage_id: Ulid, unprocessed_value: Option, value: Option, ) -> NodeWeightResult { Ok(NodeWeight::AttributeValue(AttributeValueNodeWeight::new( - change_set, + vector_clock_id, attribute_value_id, + lineage_id, unprocessed_value, value, )?)) } pub fn new_dependent_value_root( - change_set: &ChangeSet, + vector_clock_id: VectorClockId, + id: Ulid, + lineage_id: Ulid, value_id: Ulid, ) -> NodeWeightResult { Ok(NodeWeight::DependentValueRoot( - DependentValueRootNodeWeight::new(change_set, value_id)?, + DependentValueRootNodeWeight::new(vector_clock_id, id, lineage_id, value_id)?, )) } pub fn new_component( - change_set: &ChangeSet, + vector_clock_id: VectorClockId, component_id: Ulid, + lineage_id: Ulid, content_hash: ContentHash, ) -> NodeWeightResult { Ok(NodeWeight::Component(ComponentNodeWeight::new( - change_set, + vector_clock_id, component_id, + lineage_id, ContentAddress::Component(content_hash), )?)) } pub fn new_prop( - change_set: &ChangeSet, + vector_clock_id: VectorClockId, prop_id: Ulid, + lineage_id: Ulid, prop_kind: PropKind, name: impl AsRef, content_hash: ContentHash, ) -> NodeWeightResult { Ok(NodeWeight::Prop(PropNodeWeight::new( - change_set, + vector_clock_id, prop_id, + lineage_id, ContentAddress::Prop(content_hash), prop_kind, name.as_ref().to_string(), @@ -602,15 +617,17 @@ impl NodeWeight { } pub fn new_func( - change_set: &ChangeSet, + vector_clock_id: VectorClockId, func_id: Ulid, + lineage_id: Ulid, name: impl AsRef, func_kind: FuncKind, content_hash: ContentHash, ) -> NodeWeightResult { Ok(NodeWeight::Func(FuncNodeWeight::new( - change_set, + vector_clock_id, func_id, + lineage_id, ContentAddress::Func(content_hash), name.as_ref().to_string(), func_kind, @@ -618,42 +635,48 @@ impl NodeWeight { } pub fn new_func_argument( - change_set: &ChangeSet, + vector_clock_id: VectorClockId, func_arg_id: Ulid, + lineage_id: Ulid, name: impl AsRef, content_hash: ContentHash, ) -> NodeWeightResult { Ok(NodeWeight::FuncArgument(FuncArgumentNodeWeight::new( - change_set, + vector_clock_id, func_arg_id, + lineage_id, ContentAddress::FuncArg(content_hash), name.as_ref().to_string(), )?)) } pub fn new_attribute_prototype_argument( - change_set: &ChangeSet, + vector_clock_id: VectorClockId, attribute_prototype_argument_id: Ulid, + lineage_id: Ulid, targets: Option, ) -> NodeWeightResult { Ok(NodeWeight::AttributePrototypeArgument( AttributePrototypeArgumentNodeWeight::new( - change_set, + vector_clock_id, attribute_prototype_argument_id, + lineage_id, targets, )?, )) } pub fn new_secret( - change_set: &ChangeSet, + vector_clock_id: VectorClockId, secret_id: Ulid, + lineage_id: Ulid, encrypted_secret_key: EncryptedSecretKey, content_hash: ContentHash, ) -> NodeWeightResult { Ok(NodeWeight::Secret(SecretNodeWeight::new( - change_set, + vector_clock_id, secret_id, + lineage_id, ContentAddress::Secret(content_hash), encrypted_secret_key, )?)) diff --git a/lib/dal/src/workspace_snapshot/node_weight/action_node_weight.rs b/lib/dal/src/workspace_snapshot/node_weight/action_node_weight.rs index 85ad8385bf..1394a63e2b 100644 --- a/lib/dal/src/workspace_snapshot/node_weight/action_node_weight.rs +++ b/lib/dal/src/workspace_snapshot/node_weight/action_node_weight.rs @@ -1,5 +1,5 @@ use serde::{Deserialize, Serialize}; -use si_events::{merkle_tree_hash::MerkleTreeHash, ulid::Ulid, ContentHash}; +use si_events::{merkle_tree_hash::MerkleTreeHash, ulid::Ulid, ContentHash, VectorClockId}; use crate::{ action::ActionState, @@ -8,7 +8,7 @@ use crate::{ graph::LineageId, vector_clock::{HasVectorClocks, VectorClock}, }, - ChangeSet, ChangeSetId, EdgeWeightKindDiscriminants, + ChangeSetId, EdgeWeightKindDiscriminants, }; use super::NodeWeightResult; @@ -29,18 +29,19 @@ pub struct ActionNodeWeight { impl ActionNodeWeight { pub fn new( - change_set: &ChangeSet, + vector_clock_id: VectorClockId, originating_change_set_id: ChangeSetId, id: Ulid, + lineage_id: Ulid, ) -> NodeWeightResult { - let new_vector_clock = VectorClock::new(change_set.vector_clock_id()); + let new_vector_clock = VectorClock::new(vector_clock_id); Ok(Self { id, state: ActionState::Queued, func_execution_pk: None, originating_changeset_id: originating_change_set_id, - lineage_id: change_set.generate_ulid()?, + lineage_id, merkle_tree_hash: MerkleTreeHash::default(), vector_clock_first_seen: new_vector_clock.clone(), vector_clock_recently_seen: new_vector_clock.clone(), diff --git a/lib/dal/src/workspace_snapshot/node_weight/action_prototype_node_weight.rs b/lib/dal/src/workspace_snapshot/node_weight/action_prototype_node_weight.rs index fe43b8d53f..5f03e40d4e 100644 --- a/lib/dal/src/workspace_snapshot/node_weight/action_prototype_node_weight.rs +++ b/lib/dal/src/workspace_snapshot/node_weight/action_prototype_node_weight.rs @@ -1,5 +1,5 @@ use serde::{Deserialize, Serialize}; -use si_events::{merkle_tree_hash::MerkleTreeHash, ulid::Ulid, ContentHash}; +use si_events::{merkle_tree_hash::MerkleTreeHash, ulid::Ulid, ContentHash, VectorClockId}; use crate::{ action::prototype::ActionKind, @@ -7,7 +7,7 @@ use crate::{ graph::LineageId, vector_clock::{HasVectorClocks, VectorClock}, }, - ChangeSet, EdgeWeightKindDiscriminants, + EdgeWeightKindDiscriminants, }; use super::NodeWeightResult; @@ -29,13 +29,14 @@ pub struct ActionPrototypeNodeWeight { impl ActionPrototypeNodeWeight { pub fn new( - change_set: &ChangeSet, + vector_clock_id: VectorClockId, id: Ulid, + lineage_id: Ulid, kind: ActionKind, name: impl AsRef, description: Option>, ) -> NodeWeightResult { - let new_vector_clock = VectorClock::new(change_set.vector_clock_id()); + let new_vector_clock = VectorClock::new(vector_clock_id); let name = name.as_ref().to_string(); let description = description.map(|d| d.as_ref().to_string()); @@ -44,7 +45,7 @@ impl ActionPrototypeNodeWeight { kind, name, description, - lineage_id: change_set.generate_ulid()?, + lineage_id, merkle_tree_hash: MerkleTreeHash::default(), vector_clock_first_seen: new_vector_clock.clone(), vector_clock_recently_seen: new_vector_clock.clone(), diff --git a/lib/dal/src/workspace_snapshot/node_weight/attribute_prototype_argument_node_weight.rs b/lib/dal/src/workspace_snapshot/node_weight/attribute_prototype_argument_node_weight.rs index d06f2af7dd..ade107bbf2 100644 --- a/lib/dal/src/workspace_snapshot/node_weight/attribute_prototype_argument_node_weight.rs +++ b/lib/dal/src/workspace_snapshot/node_weight/attribute_prototype_argument_node_weight.rs @@ -1,8 +1,7 @@ use serde::{Deserialize, Serialize}; -use si_events::{merkle_tree_hash::MerkleTreeHash, ulid::Ulid, ContentHash}; +use si_events::{merkle_tree_hash::MerkleTreeHash, ulid::Ulid, ContentHash, VectorClockId}; use crate::{ - change_set::ChangeSet, workspace_snapshot::{ graph::LineageId, node_weight::NodeWeightResult, @@ -33,18 +32,19 @@ pub struct AttributePrototypeArgumentNodeWeight { impl AttributePrototypeArgumentNodeWeight { pub fn new( - change_set: &ChangeSet, + vector_clock_id: VectorClockId, id: Ulid, + lineage_id: Ulid, targets: Option, ) -> NodeWeightResult { Ok(Self { id, - lineage_id: change_set.generate_ulid()?, + lineage_id, merkle_tree_hash: MerkleTreeHash::default(), targets, - vector_clock_first_seen: VectorClock::new(change_set.vector_clock_id()), - vector_clock_recently_seen: VectorClock::new(change_set.vector_clock_id()), - vector_clock_write: VectorClock::new(change_set.vector_clock_id()), + vector_clock_first_seen: VectorClock::new(vector_clock_id), + vector_clock_recently_seen: VectorClock::new(vector_clock_id), + vector_clock_write: VectorClock::new(vector_clock_id), timestamp: Timestamp::now(), }) } diff --git a/lib/dal/src/workspace_snapshot/node_weight/attribute_value_node_weight.rs b/lib/dal/src/workspace_snapshot/node_weight/attribute_value_node_weight.rs index ba5e0835d1..ded04924e5 100644 --- a/lib/dal/src/workspace_snapshot/node_weight/attribute_value_node_weight.rs +++ b/lib/dal/src/workspace_snapshot/node_weight/attribute_value_node_weight.rs @@ -1,8 +1,7 @@ use serde::{Deserialize, Serialize}; -use si_events::{merkle_tree_hash::MerkleTreeHash, ulid::Ulid, ContentHash}; +use si_events::{merkle_tree_hash::MerkleTreeHash, ulid::Ulid, ContentHash, VectorClockId}; use crate::{ - change_set::ChangeSet, func::FuncExecutionPk, workspace_snapshot::{ content_address::ContentAddress, @@ -34,18 +33,19 @@ pub struct AttributeValueNodeWeight { impl AttributeValueNodeWeight { pub fn new( - change_set: &ChangeSet, + vector_clock_id: VectorClockId, id: Ulid, + lineage_id: Ulid, unprocessed_value: Option, value: Option, ) -> NodeWeightResult { Ok(Self { id, - lineage_id: change_set.generate_ulid()?, + lineage_id, merkle_tree_hash: MerkleTreeHash::default(), - vector_clock_first_seen: VectorClock::new(change_set.vector_clock_id()), - vector_clock_recently_seen: VectorClock::new(change_set.vector_clock_id()), - vector_clock_write: VectorClock::new(change_set.vector_clock_id()), + vector_clock_first_seen: VectorClock::new(vector_clock_id), + vector_clock_recently_seen: VectorClock::new(vector_clock_id), + vector_clock_write: VectorClock::new(vector_clock_id), unprocessed_value, value, func_execution_pk: None, diff --git a/lib/dal/src/workspace_snapshot/node_weight/category_node_weight.rs b/lib/dal/src/workspace_snapshot/node_weight/category_node_weight.rs index 08d16fbf00..264b4033cb 100644 --- a/lib/dal/src/workspace_snapshot/node_weight/category_node_weight.rs +++ b/lib/dal/src/workspace_snapshot/node_weight/category_node_weight.rs @@ -1,8 +1,8 @@ use serde::{Deserialize, Serialize}; +use si_events::VectorClockId; use si_events::{merkle_tree_hash::MerkleTreeHash, ulid::Ulid, ContentHash}; use strum::{Display, EnumIter}; -use crate::change_set::ChangeSet; use crate::workspace_snapshot::vector_clock::HasVectorClocks; use crate::workspace_snapshot::{node_weight::NodeWeightResult, vector_clock::VectorClock}; use crate::EdgeWeightKindDiscriminants; @@ -67,16 +67,21 @@ impl CategoryNodeWeight { self.merkle_tree_hash = new_hash; } - pub fn new(change_set: &ChangeSet, kind: CategoryNodeKind) -> NodeWeightResult { + pub fn new( + id: Ulid, + lineage_id: Ulid, + vector_clock_id: VectorClockId, + kind: CategoryNodeKind, + ) -> NodeWeightResult { Ok(Self { - id: change_set.generate_ulid()?, - lineage_id: change_set.generate_ulid()?, + id, + lineage_id, kind, - vector_clock_write: VectorClock::new(change_set.vector_clock_id()), - vector_clock_first_seen: VectorClock::new(change_set.vector_clock_id()), + vector_clock_write: VectorClock::new(vector_clock_id), + vector_clock_first_seen: VectorClock::new(vector_clock_id), content_hash: ContentHash::from(&serde_json::json![kind]), merkle_tree_hash: Default::default(), - vector_clock_recently_seen: Default::default(), + vector_clock_recently_seen: VectorClock::new(vector_clock_id), }) } diff --git a/lib/dal/src/workspace_snapshot/node_weight/component_node_weight.rs b/lib/dal/src/workspace_snapshot/node_weight/component_node_weight.rs index 6291b5fe2e..7e1a1a19c6 100644 --- a/lib/dal/src/workspace_snapshot/node_weight/component_node_weight.rs +++ b/lib/dal/src/workspace_snapshot/node_weight/component_node_weight.rs @@ -1,8 +1,7 @@ use serde::{Deserialize, Serialize}; -use si_events::{merkle_tree_hash::MerkleTreeHash, ulid::Ulid, ContentHash}; +use si_events::{merkle_tree_hash::MerkleTreeHash, ulid::Ulid, ContentHash, VectorClockId}; use crate::{ - change_set::ChangeSet, workspace_snapshot::{ content_address::{ContentAddress, ContentAddressDiscriminants}, graph::LineageId, @@ -27,15 +26,16 @@ pub struct ComponentNodeWeight { impl ComponentNodeWeight { pub fn new( - change_set: &ChangeSet, + vector_clock_id: VectorClockId, id: Ulid, + lineage_id: Ulid, content_address: ContentAddress, ) -> NodeWeightResult { - let new_vector_clock = VectorClock::new(change_set.vector_clock_id()); + let new_vector_clock = VectorClock::new(vector_clock_id); Ok(Self { id, - lineage_id: change_set.generate_ulid()?, + lineage_id, content_address, merkle_tree_hash: MerkleTreeHash::default(), to_delete: false, diff --git a/lib/dal/src/workspace_snapshot/node_weight/content_node_weight.rs b/lib/dal/src/workspace_snapshot/node_weight/content_node_weight.rs index b360aa8f48..75bc142b60 100644 --- a/lib/dal/src/workspace_snapshot/node_weight/content_node_weight.rs +++ b/lib/dal/src/workspace_snapshot/node_weight/content_node_weight.rs @@ -1,17 +1,15 @@ use serde::{Deserialize, Serialize}; use si_events::merkle_tree_hash::MerkleTreeHash; +use si_events::VectorClockId; use si_events::{ulid::Ulid, ContentHash}; -use crate::EdgeWeightKindDiscriminants; -use crate::{ - change_set::ChangeSet, - workspace_snapshot::{ - content_address::ContentAddress, - graph::LineageId, - node_weight::{NodeWeightError, NodeWeightResult}, - vector_clock::{HasVectorClocks, VectorClock}, - }, +use crate::workspace_snapshot::{ + content_address::ContentAddress, + graph::LineageId, + node_weight::{NodeWeightError, NodeWeightResult}, + vector_clock::{HasVectorClocks, VectorClock}, }; +use crate::EdgeWeightKindDiscriminants; #[derive(Clone, Serialize, Deserialize)] pub struct ContentNodeWeight { @@ -42,18 +40,19 @@ pub struct ContentNodeWeight { impl ContentNodeWeight { pub fn new( - change_set: &ChangeSet, + vector_clock_id: VectorClockId, id: Ulid, + lineage_id: Ulid, content_address: ContentAddress, ) -> NodeWeightResult { Ok(Self { id, - lineage_id: change_set.generate_ulid()?, + lineage_id, content_address, merkle_tree_hash: MerkleTreeHash::default(), - vector_clock_first_seen: VectorClock::new(change_set.vector_clock_id()), - vector_clock_recently_seen: VectorClock::new(change_set.vector_clock_id()), - vector_clock_write: VectorClock::new(change_set.vector_clock_id()), + vector_clock_first_seen: VectorClock::new(vector_clock_id), + vector_clock_recently_seen: VectorClock::new(vector_clock_id), + vector_clock_write: VectorClock::new(vector_clock_id), to_delete: false, }) } diff --git a/lib/dal/src/workspace_snapshot/node_weight/dependent_value_root_node_weight.rs b/lib/dal/src/workspace_snapshot/node_weight/dependent_value_root_node_weight.rs index eee79c0ded..126666f4be 100644 --- a/lib/dal/src/workspace_snapshot/node_weight/dependent_value_root_node_weight.rs +++ b/lib/dal/src/workspace_snapshot/node_weight/dependent_value_root_node_weight.rs @@ -1,8 +1,9 @@ use serde::{Deserialize, Serialize}; +use si_events::VectorClockId; use si_events::{merkle_tree_hash::MerkleTreeHash, ulid::Ulid, ContentHash}; use crate::workspace_snapshot::vector_clock::{HasVectorClocks, VectorClock}; -use crate::{ChangeSet, EdgeWeightKindDiscriminants}; +use crate::EdgeWeightKindDiscriminants; use super::NodeWeightResult; @@ -39,29 +40,34 @@ impl DependentValueRootNodeWeight { self.lineage_id } - pub fn merge_clocks(&mut self, change_set: &ChangeSet, other: &Self) { + pub fn merge_clocks(&mut self, vector_clock_id: VectorClockId, other: &Self) { self.vector_clock_write - .merge(change_set.vector_clock_id(), other.vector_clock_write()); - self.vector_clock_first_seen.merge( - change_set.vector_clock_id(), - other.vector_clock_first_seen(), - ); + .merge(vector_clock_id, other.vector_clock_write()); + self.vector_clock_first_seen + .merge(vector_clock_id, other.vector_clock_first_seen()); + self.vector_clock_recently_seen + .merge(vector_clock_id, other.vector_clock_recently_seen()); } pub fn merkle_tree_hash(&self) -> MerkleTreeHash { self.merkle_tree_hash } - pub fn new(change_set: &ChangeSet, value_id: Ulid) -> NodeWeightResult { + pub fn new( + vector_clock_id: VectorClockId, + id: Ulid, + lineage_id: Ulid, + value_id: Ulid, + ) -> NodeWeightResult { Ok(Self { - id: change_set.generate_ulid()?, - lineage_id: change_set.generate_ulid()?, + id, + lineage_id, value_id, touch_count: 0, - vector_clock_write: VectorClock::new(change_set.vector_clock_id()), - vector_clock_first_seen: VectorClock::new(change_set.vector_clock_id()), + vector_clock_write: VectorClock::new(vector_clock_id), + vector_clock_first_seen: VectorClock::new(vector_clock_id), merkle_tree_hash: Default::default(), - vector_clock_recently_seen: Default::default(), + vector_clock_recently_seen: VectorClock::new(vector_clock_id), }) } diff --git a/lib/dal/src/workspace_snapshot/node_weight/func_argument_node_weight.rs b/lib/dal/src/workspace_snapshot/node_weight/func_argument_node_weight.rs index 78edc6de84..74ea2ee7b1 100644 --- a/lib/dal/src/workspace_snapshot/node_weight/func_argument_node_weight.rs +++ b/lib/dal/src/workspace_snapshot/node_weight/func_argument_node_weight.rs @@ -1,8 +1,7 @@ use serde::{Deserialize, Serialize}; -use si_events::{merkle_tree_hash::MerkleTreeHash, ulid::Ulid, ContentHash}; +use si_events::{merkle_tree_hash::MerkleTreeHash, ulid::Ulid, ContentHash, VectorClockId}; use crate::{ - change_set::ChangeSet, workspace_snapshot::{ content_address::{ContentAddress, ContentAddressDiscriminants}, graph::LineageId, @@ -27,20 +26,21 @@ pub struct FuncArgumentNodeWeight { impl FuncArgumentNodeWeight { pub fn new( - change_set: &ChangeSet, + vector_clock_id: VectorClockId, id: Ulid, + lineage_id: Ulid, content_address: ContentAddress, name: String, ) -> NodeWeightResult { Ok(Self { id, - lineage_id: change_set.generate_ulid()?, + lineage_id, content_address, merkle_tree_hash: MerkleTreeHash::default(), name, - vector_clock_first_seen: VectorClock::new(change_set.vector_clock_id()), - vector_clock_recently_seen: VectorClock::new(change_set.vector_clock_id()), - vector_clock_write: VectorClock::new(change_set.vector_clock_id()), + vector_clock_first_seen: VectorClock::new(vector_clock_id), + vector_clock_recently_seen: VectorClock::new(vector_clock_id), + vector_clock_write: VectorClock::new(vector_clock_id), }) } diff --git a/lib/dal/src/workspace_snapshot/node_weight/func_node_weight.rs b/lib/dal/src/workspace_snapshot/node_weight/func_node_weight.rs index b52dde4bf1..23a7e10c6d 100644 --- a/lib/dal/src/workspace_snapshot/node_weight/func_node_weight.rs +++ b/lib/dal/src/workspace_snapshot/node_weight/func_node_weight.rs @@ -1,19 +1,17 @@ use serde::{Deserialize, Serialize}; +use si_events::VectorClockId; use si_events::{merkle_tree_hash::MerkleTreeHash, ulid::Ulid, ContentHash}; use crate::func::FuncKind; use crate::workspace_snapshot::content_address::ContentAddressDiscriminants; use crate::workspace_snapshot::vector_clock::HasVectorClocks; -use crate::EdgeWeightKindDiscriminants; -use crate::{ - change_set::ChangeSet, - workspace_snapshot::{ - content_address::ContentAddress, - graph::LineageId, - node_weight::{NodeWeightError, NodeWeightResult}, - vector_clock::VectorClock, - }, +use crate::workspace_snapshot::{ + content_address::ContentAddress, + graph::LineageId, + node_weight::{NodeWeightError, NodeWeightResult}, + vector_clock::VectorClock, }; +use crate::EdgeWeightKindDiscriminants; #[derive(Clone, Serialize, Deserialize)] pub struct FuncNodeWeight { @@ -30,22 +28,23 @@ pub struct FuncNodeWeight { impl FuncNodeWeight { pub fn new( - change_set: &ChangeSet, + vector_clock_id: VectorClockId, id: Ulid, + lineage_id: Ulid, content_address: ContentAddress, name: String, func_kind: FuncKind, ) -> NodeWeightResult { Ok(Self { id, - lineage_id: change_set.generate_ulid()?, + lineage_id, content_address, merkle_tree_hash: MerkleTreeHash::default(), name, func_kind, - vector_clock_first_seen: VectorClock::new(change_set.vector_clock_id()), - vector_clock_recently_seen: VectorClock::new(change_set.vector_clock_id()), - vector_clock_write: VectorClock::new(change_set.vector_clock_id()), + vector_clock_first_seen: VectorClock::new(vector_clock_id), + vector_clock_recently_seen: VectorClock::new(vector_clock_id), + vector_clock_write: VectorClock::new(vector_clock_id), }) } diff --git a/lib/dal/src/workspace_snapshot/node_weight/ordering_node_weight.rs b/lib/dal/src/workspace_snapshot/node_weight/ordering_node_weight.rs index d6f325b855..2c12aa7364 100644 --- a/lib/dal/src/workspace_snapshot/node_weight/ordering_node_weight.rs +++ b/lib/dal/src/workspace_snapshot/node_weight/ordering_node_weight.rs @@ -2,7 +2,6 @@ use serde::{Deserialize, Serialize}; use si_events::{merkle_tree_hash::MerkleTreeHash, ulid::Ulid, ContentHash}; use super::NodeWeightError; -use crate::change_set::ChangeSet; use crate::workspace_snapshot::vector_clock::{HasVectorClocks, VectorClockId}; use crate::workspace_snapshot::{node_weight::NodeWeightResult, vector_clock::VectorClock}; use crate::EdgeWeightKindDiscriminants; @@ -41,12 +40,17 @@ impl OrderingNodeWeight { self.merkle_tree_hash } - pub fn new(change_set: &ChangeSet) -> NodeWeightResult { + pub fn new( + id: Ulid, + lineage_id: Ulid, + vector_clock_id: VectorClockId, + ) -> NodeWeightResult { Ok(Self { - id: change_set.generate_ulid()?, - lineage_id: change_set.generate_ulid()?, - vector_clock_write: VectorClock::new(change_set.vector_clock_id()), - vector_clock_first_seen: VectorClock::new(change_set.vector_clock_id()), + id, + lineage_id, + vector_clock_write: VectorClock::new(vector_clock_id), + vector_clock_first_seen: VectorClock::new(vector_clock_id), + vector_clock_recently_seen: VectorClock::new(vector_clock_id), ..Default::default() }) } diff --git a/lib/dal/src/workspace_snapshot/node_weight/prop_node_weight.rs b/lib/dal/src/workspace_snapshot/node_weight/prop_node_weight.rs index ad0a9132ff..5e6a8c2534 100644 --- a/lib/dal/src/workspace_snapshot/node_weight/prop_node_weight.rs +++ b/lib/dal/src/workspace_snapshot/node_weight/prop_node_weight.rs @@ -1,11 +1,11 @@ use serde::{Deserialize, Serialize}; +use si_events::VectorClockId; use si_events::{merkle_tree_hash::MerkleTreeHash, ulid::Ulid, ContentHash}; use crate::workspace_snapshot::content_address::ContentAddressDiscriminants; use crate::workspace_snapshot::vector_clock::HasVectorClocks; use crate::EdgeWeightKindDiscriminants; use crate::{ - change_set::ChangeSet, workspace_snapshot::{ content_address::ContentAddress, graph::LineageId, @@ -31,23 +31,24 @@ pub struct PropNodeWeight { impl PropNodeWeight { pub fn new( - change_set: &ChangeSet, + vector_clock_id: VectorClockId, id: Ulid, + lineage_id: Ulid, content_address: ContentAddress, kind: PropKind, name: String, ) -> NodeWeightResult { Ok(Self { id, - lineage_id: change_set.generate_ulid()?, + lineage_id, content_address, merkle_tree_hash: MerkleTreeHash::default(), kind, name, can_be_used_as_prototype_arg: false, - vector_clock_first_seen: VectorClock::new(change_set.vector_clock_id()), - vector_clock_recently_seen: VectorClock::new(change_set.vector_clock_id()), - vector_clock_write: VectorClock::new(change_set.vector_clock_id()), + vector_clock_first_seen: VectorClock::new(vector_clock_id), + vector_clock_recently_seen: VectorClock::new(vector_clock_id), + vector_clock_write: VectorClock::new(vector_clock_id), }) } diff --git a/lib/dal/src/workspace_snapshot/node_weight/secret_node_weight.rs b/lib/dal/src/workspace_snapshot/node_weight/secret_node_weight.rs index 6afd1f28a1..0401f9b8c3 100644 --- a/lib/dal/src/workspace_snapshot/node_weight/secret_node_weight.rs +++ b/lib/dal/src/workspace_snapshot/node_weight/secret_node_weight.rs @@ -1,18 +1,16 @@ use serde::{Deserialize, Serialize}; +use si_events::VectorClockId; use si_events::{merkle_tree_hash::MerkleTreeHash, ulid::Ulid, ContentHash, EncryptedSecretKey}; use crate::workspace_snapshot::content_address::ContentAddressDiscriminants; use crate::workspace_snapshot::vector_clock::HasVectorClocks; -use crate::EdgeWeightKindDiscriminants; -use crate::{ - change_set::ChangeSet, - workspace_snapshot::{ - content_address::ContentAddress, - graph::LineageId, - node_weight::{NodeWeightError, NodeWeightResult}, - vector_clock::VectorClock, - }, +use crate::workspace_snapshot::{ + content_address::ContentAddress, + graph::LineageId, + node_weight::{NodeWeightError, NodeWeightResult}, + vector_clock::VectorClock, }; +use crate::EdgeWeightKindDiscriminants; #[derive(Clone, Serialize, Deserialize)] pub struct SecretNodeWeight { @@ -28,19 +26,20 @@ pub struct SecretNodeWeight { impl SecretNodeWeight { pub fn new( - change_set: &ChangeSet, + vector_clock_id: VectorClockId, id: Ulid, + lineage_id: Ulid, content_address: ContentAddress, encrypted_secret_key: EncryptedSecretKey, ) -> NodeWeightResult { Ok(Self { id, - lineage_id: change_set.generate_ulid()?, + lineage_id, content_address, merkle_tree_hash: MerkleTreeHash::default(), - vector_clock_first_seen: VectorClock::new(change_set.vector_clock_id()), - vector_clock_recently_seen: VectorClock::new(change_set.vector_clock_id()), - vector_clock_write: VectorClock::new(change_set.vector_clock_id()), + vector_clock_first_seen: VectorClock::new(vector_clock_id), + vector_clock_recently_seen: VectorClock::new(vector_clock_id), + vector_clock_write: VectorClock::new(vector_clock_id), encrypted_secret_key, }) } diff --git a/lib/dal/src/workspace_snapshot/vector_clock.rs b/lib/dal/src/workspace_snapshot/vector_clock.rs index fbc92f0162..032dbda623 100644 --- a/lib/dal/src/workspace_snapshot/vector_clock.rs +++ b/lib/dal/src/workspace_snapshot/vector_clock.rs @@ -6,8 +6,10 @@ use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use thiserror::Error; -use crate::pk; use crate::workspace_snapshot::lamport_clock::{LamportClock, LamportClockError}; +use crate::{pk, ChangeSetId}; + +pub use si_events::{VectorClockActorId, VectorClockChangeSetId, VectorClockId}; #[derive(Debug, Error)] pub enum VectorClockError { @@ -17,7 +19,7 @@ pub enum VectorClockError { pub type VectorClockResult = Result; -pk!(VectorClockId); +pk!(DeprecatedVectorClockId); #[derive(Default, Serialize, Deserialize, PartialEq, Eq, Clone)] pub struct VectorClock { @@ -48,6 +50,18 @@ impl VectorClock { } } + pub fn max_for_change_set_id( + &self, + change_set_id: ChangeSetId, + ) -> Option<(VectorClockId, LamportClock)> { + let change_set_id = VectorClockChangeSetId::new(change_set_id.into_inner().into()); + self.entries + .iter() + .filter(|(clock_id, _)| clock_id.change_set_id() == change_set_id) + .max_by(|(_, clock_a), (_, clock_b)| (**clock_a).cmp(*clock_b)) + .map(|(clock_id, clock)| (*clock_id, *clock)) + } + pub fn entry_for(&self, vector_clock_id: VectorClockId) -> Option { self.entries.get(&vector_clock_id).copied() } diff --git a/lib/dal/tests/integration_test/component.rs b/lib/dal/tests/integration_test/component.rs index 3e70fe59c7..befeac9d6d 100644 --- a/lib/dal/tests/integration_test/component.rs +++ b/lib/dal/tests/integration_test/component.rs @@ -502,6 +502,8 @@ async fn through_the_wormholes_child_value_reactivity(ctx: &mut DalContext) { assert_eq!(possible_world_a, view); + dbg!("committing"); + ChangeSetTestHelpers::commit_and_update_snapshot_to_visibility(ctx) .await .expect("could not commit and update snapshot to visibility"); diff --git a/lib/dal/tests/integration_test/rebaser.rs b/lib/dal/tests/integration_test/rebaser.rs index 519e5d576e..86a2b4f6eb 100644 --- a/lib/dal/tests/integration_test/rebaser.rs +++ b/lib/dal/tests/integration_test/rebaser.rs @@ -494,3 +494,47 @@ async fn correctly_detect_unrelated_unmodified_data(ctx: &mut DalContext) { "Found more than one AV for qualification.qualificationItem" ); } + +#[test] +async fn change_set_pointer_update(ctx: &mut DalContext) { + dbg!(ctx.visibility()); + dbg!(ctx.history_actor()); + dbg!(ctx.tenancy()); + let _ = dbg!(ctx.vector_clock_id()); + + let root_node_idx = ctx + .workspace_snapshot() + .expect("get snap") + .root() + .await + .expect("get root node index"); + + let root_node = ctx + .workspace_snapshot() + .expect("get snap") + .get_node_weight(root_node_idx) + .await + .expect("get root node"); + + dbg!(root_node); + + ChangeSetTestHelpers::commit_and_update_snapshot_to_visibility(ctx) + .await + .expect("Unable to commit_and_update_snapshot_to_visibility"); + + let root_node_idx = ctx + .workspace_snapshot() + .expect("get snap") + .root() + .await + .expect("get root node index"); + + let root_node = ctx + .workspace_snapshot() + .expect("get snap") + .get_node_weight(root_node_idx) + .await + .expect("get root node"); + + dbg!(root_node); +} diff --git a/lib/rebaser-server/src/rebase.rs b/lib/rebaser-server/src/rebase.rs index 9011c455d1..eb78f2d6dc 100644 --- a/lib/rebaser-server/src/rebase.rs +++ b/lib/rebaser-server/src/rebase.rs @@ -64,9 +64,15 @@ pub async fn perform_rebase( // Perform the conflicts and updates detection. let onto_vector_clock_id: VectorClockId = message.payload.onto_vector_clock_id.into(); + let to_rebase_vector_clock_id = to_rebase_workspace_snapshot + .max_recently_seen_clock_id_for_change_set(to_rebase_change_set.id) + .await + .unwrap() + .unwrap(); + let conflicts_and_updates = to_rebase_workspace_snapshot .detect_conflicts_and_updates( - to_rebase_change_set.vector_clock_id(), + to_rebase_vector_clock_id, &onto_workspace_snapshot, onto_vector_clock_id, ) @@ -83,7 +89,7 @@ pub async fn perform_rebase( let message: RebaseStatus = if conflicts_and_updates.conflicts.is_empty() { to_rebase_workspace_snapshot .perform_updates( - &to_rebase_change_set, + to_rebase_vector_clock_id, &onto_workspace_snapshot, conflicts_and_updates.updates.as_slice(), ) @@ -93,8 +99,11 @@ pub async fn perform_rebase( if !conflicts_and_updates.updates.is_empty() { // Once all updates have been performed, we can write out, mark everything as recently seen // and update the pointer. + dbg!(ctx.vector_clock_id()?); + dbg!(ctx.visibility()); + dbg!(ctx.tenancy()); to_rebase_workspace_snapshot - .write(ctx, to_rebase_change_set.vector_clock_id()) + .write(ctx, ctx.vector_clock_id()?) .await?; info!("snapshot written: {:?}", start.elapsed()); to_rebase_change_set diff --git a/lib/sdf-server/src/server/server.rs b/lib/sdf-server/src/server/server.rs index d2a088233b..faf169c0b3 100644 --- a/lib/sdf-server/src/server/server.rs +++ b/lib/sdf-server/src/server/server.rs @@ -269,24 +269,6 @@ impl Server<(), ()> { Ok(()) } - // /// Start the basic resource refresh scheduler - // pub async fn start_resource_refresh_scheduler( - // services_context: ServicesContext, - // shutdown_broadcast_rx: broadcast::Receiver<()>, - // ) { - // ResourceScheduler::new(services_context).start(shutdown_broadcast_rx); - // } - - // pub async fn start_status_updater( - // services_context: ServicesContext, - // shutdown_broadcast_rx: broadcast::Receiver<()>, - // ) -> Result<()> { - // StatusReceiver::new(services_context) - // .await? - // .start(shutdown_broadcast_rx); - // Ok(()) - // } - #[instrument(name = "sdf.init.create_pg_pool", level = "info", skip_all)] pub async fn create_pg_pool(pg_pool_config: &PgPoolConfig) -> Result { let pool = PgPool::new(pg_pool_config).await?; @@ -352,10 +334,13 @@ pub async fn migrate_builtins_from_module_index(services_context: &ServicesConte let instant = Instant::now(); let mut dal_context = services_context.clone().into_builder(true); + info!("a"); dal_context.set_no_dependent_values(); + info!("b"); dal_context.set_no_auto_migrate_snapshots(); + info!("c"); let mut ctx = dal_context.build_default().await?; - + info!("setup builtin workspace"); Workspace::setup_builtin(&mut ctx).await?; info!("migrating intrinsic functions"); diff --git a/lib/si-events-rs/src/vector_clock_id.rs b/lib/si-events-rs/src/vector_clock_id.rs index 38bf924c4c..b4fa0dcd92 100644 --- a/lib/si-events-rs/src/vector_clock_id.rs +++ b/lib/si-events-rs/src/vector_clock_id.rs @@ -5,6 +5,28 @@ use crate::ulid::Ulid; #[derive(Serialize, Deserialize, Hash, PartialEq, Eq, Clone, Copy, Debug)] pub struct VectorClockChangeSetId(Ulid); +impl VectorClockChangeSetId { + pub fn new(ulid: Ulid) -> Self { + Self(ulid) + } + + pub fn into_inner(self) -> Ulid { + self.0 + } +} + +impl From for VectorClockChangeSetId { + fn from(value: ulid::Ulid) -> Self { + Self(value.into()) + } +} + +impl From for VectorClockChangeSetId { + fn from(value: Ulid) -> Self { + Self(value) + } +} + impl std::fmt::Display for VectorClockChangeSetId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.0) @@ -14,18 +36,91 @@ impl std::fmt::Display for VectorClockChangeSetId { #[derive(Serialize, Deserialize, Hash, PartialEq, Eq, Clone, Copy, Debug)] pub struct VectorClockActorId(Ulid); +impl VectorClockActorId { + pub fn new(ulid: Ulid) -> Self { + Self(ulid) + } + + pub fn into_inner(self) -> Ulid { + self.0 + } +} + +impl From for VectorClockActorId { + fn from(value: Ulid) -> Self { + Self(value) + } +} + +impl From for VectorClockActorId { + fn from(value: ulid::Ulid) -> Self { + Self(value.into()) + } +} + impl std::fmt::Display for VectorClockActorId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.0) } } -#[derive(Serialize, Deserialize, Hash, PartialEq, Eq, Clone, Copy, Debug)] +#[derive(Hash, PartialEq, Eq, Clone, Copy, Debug)] pub struct VectorClockId { change_set_id: VectorClockChangeSetId, actor_id: VectorClockActorId, } +pub struct VectorClockIdStringDeserializeVisitor; + +impl<'de> serde::de::Visitor<'de> for VectorClockIdStringDeserializeVisitor { + type Value = VectorClockId; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("a string reprensenting a VectorClockId") + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + let (change_set_id_string, actor_id_string) = v.split_once(';').ok_or(E::custom( + format!("{v} is not a valid VectorClockId string representation."), + ))?; + + let change_set_id = Ulid::from_string(change_set_id_string).map_err(|e| { + E::custom(format!( + "VectorClock ChangeSetId \"{change_set_id_string}\" is not a valid Ulid representation: {e}" + )) + })?; + let actor_id = Ulid::from_string(actor_id_string).map_err(|e| { + E::custom(format!( + "VectorClock ActorId \"{actor_id_string}\" is not a valid Ulid representation: {e}" + )) + })?; + + Ok(VectorClockId::new(change_set_id, actor_id)) + } +} + +impl<'de> serde::Deserialize<'de> for VectorClockId { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + deserializer.deserialize_str(VectorClockIdStringDeserializeVisitor) + } +} + +impl serde::Serialize for VectorClockId { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let string_vector_clock_id = format!("{};{}", self.change_set_id, self.actor_id); + serializer.serialize_str(&string_vector_clock_id) + } +} + impl std::fmt::Display for VectorClockId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( @@ -37,10 +132,13 @@ impl std::fmt::Display for VectorClockId { } impl VectorClockId { - pub fn new(change_set_id: VectorClockChangeSetId, actor_id: VectorClockActorId) -> Self { + pub fn new( + change_set_id: impl Into, + actor_id: impl Into, + ) -> Self { Self { - change_set_id, - actor_id, + change_set_id: change_set_id.into(), + actor_id: actor_id.into(), } } @@ -55,6 +153,8 @@ impl VectorClockId { #[cfg(test)] mod tests { + use std::collections::HashMap; + use super::*; #[test] @@ -74,4 +174,21 @@ mod tests { let display = format!("{vector_clock_id}"); assert_eq!(expected, display); } + + #[test] + fn serde_json() { + let mut vector_clock_map = HashMap::new(); + + for i in 0..10 { + let vector_clock_id = VectorClockId::new(Ulid::new(), Ulid::new()); + vector_clock_map.insert(vector_clock_id, i); + } + + let json_string = + serde_json::to_string(&vector_clock_map).expect("should serialize to string"); + let deserialized: HashMap = + serde_json::from_str(&json_string).expect("should deserialize"); + + assert_eq!(vector_clock_map, deserialized); + } } diff --git a/lib/si-layer-cache/src/activities/rebase.rs b/lib/si-layer-cache/src/activities/rebase.rs index 91721a3c82..e2703fd123 100644 --- a/lib/si-layer-cache/src/activities/rebase.rs +++ b/lib/si-layer-cache/src/activities/rebase.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use strum::EnumDiscriminants; -use si_events::WorkspaceSnapshotAddress; +use si_events::{VectorClockId, WorkspaceSnapshotAddress}; use telemetry::prelude::*; use telemetry::tracing::instrument; use tokio::sync::mpsc::UnboundedReceiver; @@ -24,7 +24,7 @@ pub struct RebaseRequest { /// Derived from the ephemeral or persisted change set that's either the base change set, the /// last change set before edits were made, or the change set that you are trying to rebase /// onto base. - pub onto_vector_clock_id: Ulid, + pub onto_vector_clock_id: VectorClockId, /// DEPRECATED: We have to hang on to this to ensure we can deserialize this message pub dvu_values: Option>, } @@ -33,7 +33,7 @@ impl RebaseRequest { pub fn new( to_rebase_change_set_id: Ulid, onto_workspace_snapshot_address: WorkspaceSnapshotAddress, - onto_vector_clock_id: Ulid, + onto_vector_clock_id: VectorClockId, ) -> RebaseRequest { RebaseRequest { to_rebase_change_set_id, @@ -117,7 +117,7 @@ impl<'a> ActivityRebase<'a> { &self, to_rebase_change_set_id: Ulid, onto_workspace_snapshot_address: WorkspaceSnapshotAddress, - onto_vector_clock_id: Ulid, + onto_vector_clock_id: VectorClockId, metadata: LayeredEventMetadata, ) -> LayerDbResult { let payload = RebaseRequest::new( @@ -135,7 +135,7 @@ impl<'a> ActivityRebase<'a> { &self, to_rebase_change_set_id: Ulid, onto_workspace_snapshot_address: WorkspaceSnapshotAddress, - onto_vector_clock_id: Ulid, + onto_vector_clock_id: VectorClockId, metadata: LayeredEventMetadata, ) -> LayerDbResult { let payload = RebaseRequest::new( diff --git a/lib/si-layer-cache/tests/integration_test/activities/rebase.rs b/lib/si-layer-cache/tests/integration_test/activities/rebase.rs index b4d2fbe713..fc8fe39279 100644 --- a/lib/si-layer-cache/tests/integration_test/activities/rebase.rs +++ b/lib/si-layer-cache/tests/integration_test/activities/rebase.rs @@ -3,7 +3,10 @@ use std::sync::{ Arc, }; -use si_events::{Actor, ChangeSetId, Tenancy, WorkspacePk, WorkspaceSnapshotAddress}; +use si_events::{ + Actor, ChangeSetId, Tenancy, VectorClockActorId, VectorClockChangeSetId, VectorClockId, + WorkspacePk, WorkspaceSnapshotAddress, +}; use si_layer_cache::{ activities::ActivityId, event::LayeredEventMetadata, memory_cache::MemoryCacheConfig, LayerDb, }; @@ -78,6 +81,11 @@ async fn subscribe_rebaser_requests_work_queue() { let tenancy = Tenancy::new(WorkspacePk::new(), ChangeSetId::new()); let actor = Actor::System; let metadata = LayeredEventMetadata::new(tenancy, actor); + let vector_clock_id = VectorClockId::new( + VectorClockChangeSetId::new(Ulid::new().into()), + // zackfactor - is this the system actor? + VectorClockActorId::new(tenancy.workspace_pk.into_inner().into()), + ); let rebase_request_activity = ldb_duff .activity() @@ -85,7 +93,7 @@ async fn subscribe_rebaser_requests_work_queue() { .rebase( Ulid::new(), WorkspaceSnapshotAddress::new(b"poop"), - Ulid::new(), + vector_clock_id, metadata.clone(), ) .await @@ -193,6 +201,11 @@ async fn rebase_and_wait() { let metadata = LayeredEventMetadata::new(tenancy, actor); let metadata_for_task = metadata.clone(); + let onto_vector_clock_id = VectorClockId::new( + VectorClockChangeSetId::new(Ulid::new().into()), + VectorClockActorId::new(Ulid::new().into()), + ); + let rebase_request_task = tokio::spawn(async move { ldb_slash .activity() @@ -200,7 +213,7 @@ async fn rebase_and_wait() { .rebase_and_wait( Ulid::new(), WorkspaceSnapshotAddress::new(b"poop"), - Ulid::new(), + onto_vector_clock_id, metadata_for_task, ) .await @@ -330,13 +343,17 @@ async fn rebase_requests_work_queue_stress() { tracker.spawn(async move { let mut count = 0; while count < rebase_activities { + let vector_clock_id = VectorClockId::new( + VectorClockChangeSetId::new(Ulid::new().into()), + VectorClockActorId::new(Ulid::new().into()), + ); let _rebase_request_activity = ldb_duff .activity() .rebase() .rebase( Ulid::new(), WorkspaceSnapshotAddress::new(b"poop"), - Ulid::new(), + vector_clock_id, send_meta.clone(), ) .await @@ -485,13 +502,17 @@ async fn rebase_and_wait_stress() { loop { SENT_REQUEST_COUNTER.fetch_add(1, Ordering::Relaxed); let mp = metadata_for_sender.clone(); + let onto_vector_clock_id = VectorClockId::new( + VectorClockChangeSetId::new(Ulid::new().into()), + VectorClockActorId::new(Ulid::new().into()), + ); let _response = ldb_slash_clone .activity() .rebase() .rebase_and_wait( Ulid::new(), WorkspaceSnapshotAddress::new(b"poop"), - Ulid::new(), + onto_vector_clock_id, mp, ) .await; diff --git a/lib/si-test-macros/src/expand.rs b/lib/si-test-macros/src/expand.rs index ee2c6c1d88..685d67c82a 100644 --- a/lib/si-test-macros/src/expand.rs +++ b/lib/si-test-macros/src/expand.rs @@ -539,7 +539,8 @@ pub(crate) trait FnSetupExpander { .wrap_err("failed to build default dal ctx for dal_context_default")?; ctx.update_tenancy(::dal::Tenancy::new(*#nw.workspace.pk())); ::dal_test::expand_helpers::create_change_set_and_update_ctx(&mut ctx, #nw.workspace.default_change_set_id()).await; - ctx.blocking_commit() + ::dal_test::expand_helpers::create_user_and_update_ctx(&mut ctx).await; + ctx.commit_no_rebase() .await .wrap_err("failed to commit create_change_set_and_update_ctx")?; @@ -570,7 +571,8 @@ pub(crate) trait FnSetupExpander { .wrap_err("failed to build default dal ctx for dal_context_default_mut")?; ctx.update_tenancy(::dal::Tenancy::new(*#nw.workspace.pk())); ::dal_test::expand_helpers::create_change_set_and_update_ctx(&mut ctx, #nw.workspace.default_change_set_id()).await; - ctx.blocking_commit() + ::dal_test::expand_helpers::create_user_and_update_ctx(&mut ctx).await; + ctx.commit_no_rebase() .await .wrap_err("failed to commit create_change_set_and_update_ctx_mut")?;