Skip to content

Commit

Permalink
Remove reference-counted pointer from DataTree
Browse files Browse the repository at this point in the history
This commit reverts 945368c. That commit intended to
simplify lifetime management by changing `DataTree` to contain a
reference-counting pointer instead of a regular reference to the
associated YANG context. In practice, however, that change caused
more problems than it solved. The major issue was the inconsistency
where all other structs were using regular references instead of
reference-counting pointers. This inconsistency was problematic for
expanding the API surface to cover features like YANG extensions,
where data trees can be created from schema structs. Having explicit
control over the data trees lifetimes is also desired in many cases.

With this change, `DataNodeRef` now has two lifetime parameters:
one for the associated data tree and another for the associated
YANG context.  These two lifetimes are necessary to express the logic
of the `DataNodeRef::duplicate` method, in which a new data tree is
created with a new lifetime while maintaining the same lifetime for
the YANG context.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
  • Loading branch information
rwestphal committed Aug 1, 2024
1 parent f40af12 commit 515e753
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 141 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ By default, yang-rs uses pre-generated FFI bindings and uses dynamic linking to
A basic example that parses and validates JSON instance data, and then converts
it to the XML format:
```rust,no_run
use std::sync::Arc;
use std::fs::File;
use yang3::context::{Context, ContextFlags};
use yang3::data::{
Expand All @@ -70,7 +69,6 @@ fn main() -> std::io::Result<()> {
ctx.load_module(module_name, None, &[])
.expect("Failed to load module");
}
let ctx = Arc::new(ctx);
// Parse and validate data tree in the JSON format.
let dtree = DataTree::parse_file(
Expand Down
16 changes: 5 additions & 11 deletions benches/data.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
use std::sync::Arc;

use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use yang3::context::{Context, ContextFlags};
use yang3::data::{Data, DataDiffFlags, DataTree, DataValidationFlags};

static SEARCH_DIR: &str = "./assets/yang/";

fn data_generate(ctx: &Arc<Context>, interfaces: u32) -> DataTree {
fn data_generate(ctx: &Context, interfaces: u32) -> DataTree {
let mut dtree = DataTree::new(ctx);

for i in 1..=interfaces {
Expand Down Expand Up @@ -38,18 +36,14 @@ fn criterion_benchmark(c: &mut Criterion) {
];

// Initialize context.
let mut ctx = Arc::new(
Context::new(ContextFlags::NO_YANGLIBRARY)
.expect("Failed to create context"),
);
(*Arc::get_mut(&mut ctx).unwrap())
.set_searchdir(SEARCH_DIR)
let mut ctx = Context::new(ContextFlags::NO_YANGLIBRARY)
.expect("Failed to create context");
ctx.set_searchdir(SEARCH_DIR)
.expect("Failed to set YANG search directory");

// Load YANG modules.
for module_name in &["ietf-interfaces", "iana-if-type"] {
(*Arc::get_mut(&mut ctx).unwrap())
.load_module(module_name, None, &[])
ctx.load_module(module_name, None, &[])
.expect("Failed to load module");
}

Expand Down
2 changes: 0 additions & 2 deletions examples/data_diff.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::sync::Arc;
use yang3::context::{Context, ContextFlags};
use yang3::data::{
Data, DataDiffFlags, DataFormat, DataParserFlags, DataPrinterFlags,
Expand Down Expand Up @@ -61,7 +60,6 @@ fn main() -> std::io::Result<()> {
ctx.load_module(module_name, None, &[])
.expect("Failed to load module");
}
let ctx = Arc::new(ctx);

// Parse data trees from JSON strings.
let dtree1 = DataTree::parse_string(
Expand Down
2 changes: 0 additions & 2 deletions examples/data_edit.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::fs::File;
use std::sync::Arc;
use yang3::context::{Context, ContextFlags};
use yang3::data::{
Data, DataFormat, DataParserFlags, DataPrinterFlags, DataTree,
Expand All @@ -25,7 +24,6 @@ fn main() -> std::io::Result<()> {
ctx.load_module(module_name, None, &[])
.expect("Failed to load module");
}
let ctx = Arc::new(ctx);

// Parse data tree from JSON file.
let mut dtree = DataTree::parse_file(
Expand Down
2 changes: 0 additions & 2 deletions examples/data_iteration.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::fs::File;
use std::sync::Arc;
use yang3::context::{Context, ContextFlags};
use yang3::data::{
Data, DataFormat, DataParserFlags, DataTree, DataValidationFlags,
Expand All @@ -19,7 +18,6 @@ fn main() -> std::io::Result<()> {
ctx.load_module(module_name, None, &[])
.expect("Failed to load module");
}
let ctx = Arc::new(ctx);

// Parse data tree in the JSON format.
let dtree = DataTree::parse_file(
Expand Down
2 changes: 0 additions & 2 deletions examples/data_json2xml.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::fs::File;
use std::sync::Arc;
use yang3::context::{Context, ContextFlags};
use yang3::data::{
Data, DataFormat, DataParserFlags, DataPrinterFlags, DataTree,
Expand All @@ -20,7 +19,6 @@ fn main() -> std::io::Result<()> {
ctx.load_module(module_name, None, &[])
.expect("Failed to load module");
}
let ctx = Arc::new(ctx);

// Parse data tree in the JSON format.
let dtree = DataTree::parse_file(
Expand Down
Loading

0 comments on commit 515e753

Please sign in to comment.