MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / create_view

Method create_view

atomic-core/src/pristine/txn/write/mod.rs:917–983  ·  view source on GitHub ↗
(
        &mut self,
        name: &str,
        kind: ViewScope,
        parent: Option<u64>,
    )

Source from the content-addressed store, hash-verified

915 }
916
917 fn create_view(
918 &mut self,
919 name: &str,
920 kind: ViewScope,
921 parent: Option<u64>,
922 ) -> PristineResult<ViewState> {
923 // Check if view already exists
924 {
925 let table = self.txn.open_table(VIEWS)?;
926 if table.get(name)?.is_some() {
927 return Err(PristineError::ViewAlreadyExists {
928 name: name.to_string(),
929 });
930 }
931 }
932
933 // Validate parent exists if specified, and detect cycles
934 if let Some(parent_id) = parent {
935 let parent_view = ViewTxnT::get_view_by_id(self, parent_id)?.ok_or_else(|| {
936 PristineError::ViewNotFound {
937 name: format!("parent view id={}", parent_id),
938 }
939 })?;
940
941 // Cycle detection: walk the parent chain from the proposed parent
942 // upward. If we ever encounter our own (not-yet-allocated) name,
943 // there's a cycle. Since the view doesn't exist yet, we only need
944 // to check that the parent chain terminates without revisiting
945 // `parent_id` — which is guaranteed as long as the existing graph
946 // is acyclic and we're adding a leaf.
947 //
948 // However, we also guard against the degenerate case where someone
949 // passes parent == self (once IDs are known). Since we haven't
950 // allocated an ID yet, the only risk is the parent chain itself
951 // being cyclic (which would be a pre-existing bug). We do a bounded
952 // walk as a safety check.
953 let mut visited = std::collections::HashSet::new();
954 visited.insert(parent_id);
955 let mut cursor = parent_view.parent;
956 while let Some(ancestor_id) = cursor {
957 if !visited.insert(ancestor_id) {
958 // We've seen this ID before — cycle detected in existing chain
959 return Err(PristineError::ViewCycleDetected {
960 name: name.to_string(),
961 parent_name: parent_view.name.clone(),
962 });
963 }
964 match ViewTxnT::get_view_by_id(self, ancestor_id)? {
965 Some(ancestor) => cursor = ancestor.parent,
966 None => break, // Broken chain — parent doesn't exist (shouldn't happen)
967 }
968 }
969 }
970
971 // Allocate ID and create state
972 let id = self.next_view_id.fetch_add(1, Ordering::SeqCst);
973 let state = ViewState::with_scope(id, name.to_string(), kind, parent);
974

Callers 14

run_pushMethod · 0.45
runMethod · 0.45
run_two_tierMethod · 0.45
runMethod · 0.45
test_list_multiple_viewsFunction · 0.45
test_list_verboseFunction · 0.45
test_list_after_switchFunction · 0.45

Calls 5

serialize_view_stateFunction · 0.85
getMethod · 0.65
insertMethod · 0.45
cloneMethod · 0.45
as_sliceMethod · 0.45

Tested by 10

test_list_multiple_viewsFunction · 0.36
test_list_verboseFunction · 0.36
test_list_after_switchFunction · 0.36
test_del_viewFunction · 0.36