Skip to content

Commit 7ba2069

Browse files
committed
context UPDATE ignore module order when generating hash
Refs #2443
1 parent c03d4d3 commit 7ba2069

File tree

2 files changed

+52
-14
lines changed

2 files changed

+52
-14
lines changed

src/context.c

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -751,38 +751,77 @@ ly_ctx_get_modules_hash(const struct ly_ctx *ctx)
751751
return ctx->mod_hash;
752752
}
753753

754+
/**
755+
* @brief qsort() alphabetical compare of modules.
756+
*/
757+
static int
758+
ly_ctx_mod_cmp_cb(const void *ptr1, const void *ptr2)
759+
{
760+
const struct lys_module *mod1, *mod2;
761+
int r;
762+
763+
mod1 = *(struct lys_module **)ptr1;
764+
mod2 = *(struct lys_module **)ptr2;
765+
766+
/* module name */
767+
r = strcmp(mod1->name, mod2->name);
768+
if (!r) {
769+
/* revision */
770+
if (mod1->revision && !mod2->revision) {
771+
r = 1;
772+
} else if (!mod1->revision && mod2->revision) {
773+
r = -1;
774+
} else if (mod1->revision && mod2->revision) {
775+
r = strcmp(mod1->revision, mod2->revision);
776+
}
777+
}
778+
779+
return r;
780+
}
781+
754782
void
755783
ly_ctx_new_change(struct ly_ctx *ctx)
756784
{
757-
const struct lys_module *mod;
758-
uint32_t i = ly_ctx_internal_modules_count(ctx), hash = 0;
785+
uint32_t i, hash = 0;
786+
const struct lys_module **mods = NULL;
759787
LY_ARRAY_COUNT_TYPE u;
760788

761789
/* change counter */
762790
ctx->change_count++;
763791

764-
/* module hash */
765-
while ((mod = ly_ctx_get_module_iter(ctx, &i))) {
792+
/* collect modules into an array */
793+
mods = malloc(ctx->modules.count * sizeof *mods);
794+
LY_CHECK_ERR_GOTO(!mods, LOGMEM(ctx), cleanup);
795+
memcpy(mods, ctx->modules.objs, ctx->modules.count * sizeof *mods);
796+
797+
/* sort modules alphabetically */
798+
qsort(mods, ctx->modules.count, sizeof *mods, ly_ctx_mod_cmp_cb);
799+
800+
/* calculate module hash */
801+
for (i = 0; i < ctx->modules.count; ++i) {
766802
/* name */
767-
hash = lyht_hash_multi(hash, mod->name, strlen(mod->name));
803+
hash = lyht_hash_multi(hash, mods[i]->name, strlen(mods[i]->name));
768804

769805
/* revision */
770-
if (mod->revision) {
771-
hash = lyht_hash_multi(hash, mod->revision, strlen(mod->revision));
806+
if (mods[i]->revision) {
807+
hash = lyht_hash_multi(hash, mods[i]->revision, strlen(mods[i]->revision));
772808
}
773809

774810
/* enabled features */
775-
if (mod->implemented) {
776-
LY_ARRAY_FOR(mod->compiled->features, u) {
777-
hash = lyht_hash_multi(hash, mod->compiled->features[u], strlen(mod->compiled->features[u]));
811+
if (mods[i]->implemented) {
812+
LY_ARRAY_FOR(mods[i]->compiled->features, u) {
813+
hash = lyht_hash_multi(hash, mods[i]->compiled->features[u], strlen(mods[i]->compiled->features[u]));
778814
}
779815
}
780816

781817
/* imported/implemented */
782-
hash = lyht_hash_multi(hash, (char *)&mod->implemented, sizeof mod->implemented);
818+
hash = lyht_hash_multi(hash, (char *)&mods[i]->implemented, sizeof mods[i]->implemented);
783819
}
784820

785821
ctx->mod_hash = lyht_hash_multi(hash, NULL, 0);
822+
823+
cleanup:
824+
free(mods);
786825
}
787826

788827
LIBYANG_API_DEF ly_module_imp_clb

src/context.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -414,11 +414,10 @@ LIBYANG_API_DECL LY_ERR ly_ctx_unset_options(struct ly_ctx *ctx, uint32_t option
414414
LIBYANG_API_DECL uint16_t ly_ctx_get_change_count(const struct ly_ctx *ctx);
415415

416416
/**
417-
* @brief Get the hash of all the modules in the context. Since order of the modules is significant,
418-
* even when 2 contexts have the same modules but loaded in a different order, the hash will differ.
417+
* @brief Get the hash of all the modules in the context.
419418
*
420419
* Hash consists of all module names (1), their revisions (2), all enabled features (3), and their
421-
* imported/implemented state (4).
420+
* imported/implemented state (4). Context module order is not significant.
422421
*
423422
* @param[in] ctx Context to be examined.
424423
* @return Context modules hash.

0 commit comments

Comments
 (0)