From 574106125f4f4003b45e8f7d60d200aa529b62f6 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Wed, 6 Dec 2023 13:48:41 +0100 Subject: [PATCH] Added reference count for shared yang-specs (schema mounts) --- CHANGELOG.md | 4 +++ lib/clixon/clixon_yang.h | 3 ++ lib/src/clixon_yang.c | 55 ++++++++++++++++++++++++++++++++-- lib/src/clixon_yang_internal.h | 1 + 4 files changed, 61 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4775626..70c99c6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ ## 6.6.0 Expected: February 2024 +### Minor features + +* Added reference count for shared yang-specs (schema mounts) + ## 6.5.0 6 December 2023 diff --git a/lib/clixon/clixon_yang.h b/lib/clixon/clixon_yang.h index 0eea5a33..5a0399c6 100644 --- a/lib/clixon/clixon_yang.h +++ b/lib/clixon/clixon_yang.h @@ -240,6 +240,9 @@ int yang_cv_set(yang_stmt *ys, cg_var *cv); cvec *yang_cvec_get(yang_stmt *ys); int yang_cvec_set(yang_stmt *ys, cvec *cvv); cg_var *yang_cvec_add(yang_stmt *ys, enum cv_type type, char *name); +int yang_ref_get(yang_stmt *ys); +int yang_ref_inc(yang_stmt *ys); +int yang_ref_dec(yang_stmt *ys); uint16_t yang_flag_get(yang_stmt *ys, uint16_t flag); int yang_flag_set(yang_stmt *ys, uint16_t flag); int yang_flag_reset(yang_stmt *ys, uint16_t flag); diff --git a/lib/src/clixon_yang.c b/lib/src/clixon_yang.c index c167da2f..1d7971f1 100644 --- a/lib/src/clixon_yang.c +++ b/lib/src/clixon_yang.c @@ -345,6 +345,50 @@ yang_cvec_add(yang_stmt *ys, return cv; } +/*! Get yang object reference count + * + * @param[in] ys Yang statement + * @retval ref Reference coun t + */ +int +yang_ref_get(yang_stmt *ys) +{ + return ys->ys_ref; +} + +/*! Increment yang object reference count with +1 + * + * @param[in] ys Yang statement + * @retval 0 + */ +int +yang_ref_inc(yang_stmt *ys) +{ + ys->ys_ref++; + return 0; +} + +/*! Decrement yang object reference count with -1 + * + * @param[in] ys Yang statement + * @retval 0 Ok + * @retval -1 Error + */ +int +yang_ref_dec(yang_stmt *ys) +{ + int retval = -1; + + if (ys->ys_ref <= 0){ + clicon_err(OE_YANG, 0, "reference count is %d cannot decrement", ys->ys_ref); + goto done; + } + ys->ys_ref--; + retval = 0; + done: + return retval; +} + /*! Get yang stmt flags, used for internal algorithms * * @param[in] ys Yang statement @@ -813,12 +857,19 @@ ys_freechildren(yang_stmt *ys) * @param[in] ys Yang node to remove and all its children recursively * @note does not remove yang node from tree * @see ys_prune Remove from parent + * @note special case of keeping track of reference counts if yang-spec */ int ys_free(yang_stmt *ys) { - ys_freechildren(ys); - ys_free1(ys, 1); + if (yang_keyword_get(ys) == Y_SPEC && + yang_ref_get(ys) > 0){ + yang_ref_dec(ys); + } + else { + ys_freechildren(ys); + ys_free1(ys, 1); + } return 0; } diff --git a/lib/src/clixon_yang_internal.h b/lib/src/clixon_yang_internal.h index 8720f95d..3a2a59cc 100644 --- a/lib/src/clixon_yang_internal.h +++ b/lib/src/clixon_yang_internal.h @@ -101,6 +101,7 @@ struct yang_stmt{ Y_EXTENSION: vector of instantiated UNKNOWNSo Y_UNKNOWN: app-dep: yang-mount-points */ + int ys_ref; /* Reference count for free, only YS_SPEC */ yang_type_cache *ys_typecache; /* If ys_keyword==Y_TYPE, cache all typedef data except unions */ char *ys_when_xpath; /* Special conditional for a "when"-associated augment/uses xpath */ cvec *ys_when_nsc; /* Special conditional for a "when"-associated augment/uses namespace ctx */