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

Method create_view

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

Source from the content-addressed store, hash-verified

442 }
443
444 fn create_view(
445 &mut self,
446 name: &str,
447 kind: ViewScope,
448 parent: Option<u64>,
449 ) -> PristineResult<ViewState> {
450 // Check if view already exists
451 {
452 let table = self.txn.open_table(VIEWS)?;
453 if table.get(name)?.is_some() {
454 return Err(PristineError::ViewAlreadyExists {
455 name: name.to_string(),
456 });
457 }
458 }
459
460 // Validate parent exists if specified, and detect cycles
461 if let Some(parent_id) = parent {
462 let parent_view = ViewTxnT::get_view_by_id(self, parent_id)?.ok_or_else(|| {
463 PristineError::ViewNotFound {
464 name: format!("parent view id={}", parent_id),
465 }
466 })?;
467
468 // Cycle detection: walk the parent chain from the proposed parent
469 // upward. If we ever encounter our own (not-yet-allocated) name,
470 // there's a cycle. Since the view doesn't exist yet, we only need
471 // to check that the parent chain terminates without revisiting
472 // `parent_id` — which is guaranteed as long as the existing graph
473 // is acyclic and we're adding a leaf.
474 //
475 // However, we also guard against the degenerate case where someone
476 // passes parent == self (once IDs are known). Since we haven't
477 // allocated an ID yet, the only risk is the parent chain itself
478 // being cyclic (which would be a pre-existing bug). We do a bounded
479 // walk as a safety check.
480 let mut visited = std::collections::HashSet::new();
481 visited.insert(parent_id);
482 let mut cursor = parent_view.parent;
483 while let Some(ancestor_id) = cursor {
484 if !visited.insert(ancestor_id) {
485 // We've seen this ID before — cycle detected in existing chain
486 return Err(PristineError::ViewCycleDetected {
487 name: name.to_string(),
488 parent_name: parent_view.name.clone(),
489 });
490 }
491 match ViewTxnT::get_view_by_id(self, ancestor_id)? {
492 Some(ancestor) => cursor = ancestor.parent,
493 None => break, // Broken chain — parent doesn't exist (shouldn't happen)
494 }
495 }
496 }
497
498 // Allocate ID and create state
499 let id = self.next_view_id.fetch_add(1, Ordering::SeqCst);
500 let state = ViewState::with_scope(id, name.to_string(), kind, parent);
501

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