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

Method create_view

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

Source from the content-addressed store, hash-verified

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

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