From b68413577a9a409736e29cb71bee79a6933a65ae Mon Sep 17 00:00:00 2001 From: Per Hedbor <ph@opera.com> Date: Mon, 5 May 2014 12:25:34 +0200 Subject: [PATCH] Removed support for changing of comparators and values (partially) from multisets. This saved 60Kb binary size, and presumably speeds up the code since a lot of tests will have been removed compile-time. --- src/builtin_functions.c | 6 +- src/multiset.c | 1103 +++++---------------------------------- src/multiset.h | 43 +- src/operators.c | 2 +- 4 files changed, 142 insertions(+), 1012 deletions(-) diff --git a/src/builtin_functions.c b/src/builtin_functions.c index 2040b9ab12..73b679bba9 100644 --- a/src/builtin_functions.c +++ b/src/builtin_functions.c @@ -8698,8 +8698,7 @@ PMOD_EXPORT void f_map(INT32 args) Pike_sp[-args]=Pike_sp[0]; /* move it back */ f_map(args); - /* FIXME: Handle multisets with values like mappings. */ - push_multiset (mkmultiset_2 (Pike_sp[-1].u.array, NULL, NULL)); + push_multiset (mkmultiset (Pike_sp[-1].u.array)); free_array (Pike_sp[-2].u.array); dmalloc_touch_svalue(Pike_sp-1); Pike_sp[-2] = Pike_sp[-1]; @@ -9137,8 +9136,7 @@ PMOD_EXPORT void f_filter(INT32 args) Pike_sp[-args]=Pike_sp[0]; /* move it back */ f_filter(args); - /* FIXME: Handle multisets with values like mappings. */ - push_multiset (mkmultiset_2 (Pike_sp[-1].u.array, NULL, NULL)); + push_multiset (mkmultiset (Pike_sp[-1].u.array)); free_array (Pike_sp[-2].u.array); Pike_sp[-2] = Pike_sp[-1]; dmalloc_touch_svalue(Pike_sp-1); diff --git a/src/multiset.c b/src/multiset.c index 1188b11b12..d449c7b493 100644 --- a/src/multiset.c +++ b/src/multiset.c @@ -68,6 +68,8 @@ static INLINE struct msnode_ind *msnode_ind_check (struct msnode_ind *x) static INLINE struct msnode_indval *msnode_indval_check (struct msnode_indval *x) {return x;} +static union msnode *low_multiset_find_eq (struct multiset *l, struct svalue *key); + #define sub_extra_ref(X) do { \ if (!sub_ref (X)) Pike_fatal ("Got too few refs to " #X ".\n"); \ } while (0) @@ -290,6 +292,9 @@ PMOD_EXPORT void count_memory_in_multisets (size_t * n, size_t * s) { *s += (size_t) datasize; } + +static void multiset_delete_node (struct multiset *l, ptrdiff_t nodepos); + /* Note: The returned block has no refs. */ #ifdef PIKE_DEBUG #define low_alloc_multiset_data(ALLOCSIZE, FLAGS) \ @@ -874,7 +879,7 @@ PMOD_EXPORT INT32 multiset_sizeof (struct multiset *l) return size; } -PMOD_EXPORT struct multiset *real_allocate_multiset (int allocsize, +struct multiset *real_allocate_multiset (int allocsize, int flags, struct svalue *cmp_less) { @@ -943,16 +948,10 @@ enum find_types { FIND_KEY_DESTRUCTED }; -static enum find_types low_multiset_find_le_gt ( - struct multiset_data *msd, struct svalue *key, union msnode **found); -static enum find_types low_multiset_find_lt_ge ( - struct multiset_data *msd, struct svalue *key, union msnode **found); static enum find_types low_multiset_track_eq ( struct multiset_data *msd, struct svalue *key, struct rbstack_ptr *track); static enum find_types low_multiset_track_le_gt ( struct multiset_data *msd, struct svalue *key, struct rbstack_ptr *track); -static enum find_types low_multiset_track_lt_ge ( - struct multiset_data *msd, struct svalue *key, struct rbstack_ptr *track); static void midflight_remove_node_fast (struct multiset *l, struct rbstack_ptr *track, @@ -1066,7 +1065,7 @@ PMOD_EXPORT void multiset_set_flags (struct multiset *l, int flags) } } -PMOD_EXPORT void multiset_set_cmp_less (struct multiset *l, +static void multiset_set_cmp_less (struct multiset *l, struct svalue *cmp_less) { struct multiset_data *old = l->msd; @@ -1181,6 +1180,9 @@ again: add_ref (l->msd = new.msd); } } +static struct multiset *mkmultiset_2 (struct array *indices, + struct array *values, + struct svalue *cmp_less); PMOD_EXPORT struct multiset *mkmultiset (struct array *indices) { @@ -1189,7 +1191,7 @@ PMOD_EXPORT struct multiset *mkmultiset (struct array *indices) } /* values may be NULL to make a multiset with indices only. */ -PMOD_EXPORT struct multiset *mkmultiset_2 (struct array *indices, +static struct multiset *mkmultiset_2 (struct array *indices, struct array *values, struct svalue *cmp_less) { @@ -1324,7 +1326,7 @@ PMOD_EXPORT int msnode_is_deleted (struct multiset *l, ptrdiff_t nodepos) return TYPEOF(node->i.ind) == T_DELETED; } -union msnode *low_multiset_find_eq (struct multiset *l, struct svalue *key) +static union msnode *low_multiset_find_eq (struct multiset *l, struct svalue *key) { struct multiset_data *msd = l->msd; struct rb_node_hdr *node; @@ -1462,473 +1464,6 @@ done: return RBNODE (node); } -PMOD_EXPORT ptrdiff_t multiset_find_eq (struct multiset *l, struct svalue *key) -{ - union msnode *node = low_multiset_find_eq (l, key); - debug_malloc_touch (l); - debug_malloc_touch (l->msd); - check_svalue (key); - if (node) { - add_msnode_ref (l); - return MSNODE2OFF (l->msd, node); - } - return -1; -} - -static enum find_types low_multiset_find_le_gt ( - struct multiset_data *msd, struct svalue *key, union msnode **found) -{ - struct rb_node_hdr *node = HDR (msd->root); - enum find_types find_type; - - /* Note: Similar code in low_multiset_track_le_gt. */ - -#ifdef PIKE_DEBUG - /* Allow zero refs too since that's used during initial building. */ - if (msd->refs == 1) Pike_fatal ("Copy-on-write assumed here.\n"); -#endif - - if (!(node = HDR (msd->root))) { - *found = NULL; - find_type = FIND_NOROOT; - } - - else { - if (TYPEOF(msd->cmp_less) == T_INT) { - struct svalue tmp; - LOW_RB_FIND_NEQ ( - node, - { - low_use_multiset_index (RBNODE (node), tmp); - if (IS_DESTRUCTED (&tmp)) { - *found = RBNODE (node); - return FIND_DESTRUCTED; - } - /* TODO: Use special variant of set_svalue_cmpfun so we - * don't have to copy the index svalues. */ - INTERNAL_CMP (key, &tmp, cmp_res); - /* Note: CMPFUN_UNORDERED > 0 - treated as equal. */ - cmp_res = cmp_res >= 0 ? 1 : -1; - }, - {*found = RBNODE (node); find_type = FIND_LESS; goto done;}, - {*found = RBNODE (node); find_type = FIND_GREATER; goto done;}); - /* NOT REACHED */ - } - - else { - LOW_RB_FIND_NEQ ( - node, - { - push_svalue (key); - low_push_multiset_index (RBNODE (node)); - if (IS_DESTRUCTED (sp - 1)) { - pop_2_elems(); - *found = RBNODE (node); - return FIND_DESTRUCTED; - } - EXTERNAL_CMP (&msd->cmp_less); - cmp_res = UNSAFE_IS_ZERO (sp - 1) ? 1 : -1; - pop_stack(); - }, - {*found = RBNODE (node); find_type = FIND_LESS; goto done;}, - {*found = RBNODE (node); find_type = FIND_GREATER; goto done;}); - /* NOT REACHED */ - } - } - -done: - if (IS_DESTRUCTED (key)) { - *found = NULL; - return FIND_KEY_DESTRUCTED; - } - return find_type; -} - -static enum find_types low_multiset_find_lt_ge ( - struct multiset_data *msd, struct svalue *key, union msnode **found) -{ - struct rb_node_hdr *node = HDR (msd->root); - enum find_types find_type; - - /* Note: Similar code in low_multiset_track_lt_ge. */ - -#ifdef PIKE_DEBUG - /* Allow zero refs too since that's used during initial building. */ - if (msd->refs == 1) Pike_fatal ("Copy-on-write assumed here.\n"); -#endif - - if (!(node = HDR (msd->root))) { - *found = NULL; - find_type = FIND_NOROOT; - } - - else { - if (TYPEOF(msd->cmp_less) == T_INT) { - struct svalue tmp; - LOW_RB_FIND_NEQ ( - node, - { - low_use_multiset_index (RBNODE (node), tmp); - if (IS_DESTRUCTED (&tmp)) { - *found = RBNODE (node); - return FIND_DESTRUCTED; - } - /* TODO: Use special variant of set_svalue_cmpfun so we - * don't have to copy the index svalues. */ - INTERNAL_CMP (&tmp, key, cmp_res); - /* Note: CMPFUN_UNORDERED > 0 - treated as equal. */ - cmp_res = cmp_res >= 0 ? -1 : 1; - }, - {*found = RBNODE (node); find_type = FIND_LESS; goto done;}, - {*found = RBNODE (node); find_type = FIND_GREATER; goto done;}); - /* NOT REACHED */ - } - - else { - LOW_RB_FIND_NEQ ( - node, - { - low_push_multiset_index (RBNODE (node)); - if (IS_DESTRUCTED (sp - 1)) { - pop_stack(); - *found = RBNODE (node); - return FIND_DESTRUCTED; - } - push_svalue (key); - EXTERNAL_CMP (&msd->cmp_less); - cmp_res = UNSAFE_IS_ZERO (sp - 1) ? -1 : 1; - pop_stack(); - }, - {*found = RBNODE (node); find_type = FIND_LESS; goto done;}, - {*found = RBNODE (node); find_type = FIND_GREATER; goto done;}); - /* NOT REACHED */ - } - } - -done: - if (IS_DESTRUCTED (key)) { - *found = NULL; - return FIND_KEY_DESTRUCTED; - } - return find_type; -} - -PMOD_EXPORT ptrdiff_t multiset_find_lt (struct multiset *l, struct svalue *key) -{ - struct multiset_data *msd = l->msd; - union msnode *node; - ONERROR uwp; - - debug_malloc_touch (l); - debug_malloc_touch (msd); - check_svalue (key); - - add_ref (msd); - SET_ONERROR (uwp, free_indirect_multiset_data, &msd); - - while (1) { - enum find_types find_type = low_multiset_find_lt_ge (msd, key, &node); -#ifdef TEST_MULTISET_TRACKING_PATHS - find_type = FIND_DESTRUCTED; -#endif - - if (l->msd != msd) /* Multiset changed; try again. */ - MOVE_MSD_REF_AND_FREE (l, msd); - else - switch (find_type) { - case FIND_LESS: - case FIND_NOROOT: - case FIND_KEY_DESTRUCTED: - goto done; - case FIND_GREATER: /* Got greater or equal - step back one. */ - node = INODE (node->i.prev); - goto done; - - case FIND_DESTRUCTED: { - /* Try again with tracking to be able to remove the - * destructed node. */ - RBSTACK_INIT (rbstack); - while (1) { - find_type = low_multiset_track_lt_ge (msd, key, &rbstack); - if (l->msd != msd) - MOVE_MSD_REF_AND_FREE (l, msd); - else - switch (find_type) { - case FIND_LESS: - case FIND_NOROOT: - case FIND_KEY_DESTRUCTED: - node = RBNODE (RBSTACK_PEEK (rbstack)); - RBSTACK_FREE (rbstack); - goto done; - case FIND_GREATER: - node = INODE (RBNODE (RBSTACK_PEEK (rbstack))->i.prev); - RBSTACK_FREE (rbstack); - goto done; - case FIND_DESTRUCTED: - sub_extra_ref (msd); - midflight_remove_node_fast (l, &rbstack, 0); - msd = l->msd; - add_ref (msd); - /* Let's stay in tracking mode - if there's one - * destructed index, there might be many. */ - break; - default: DO_IF_DEBUG (Pike_fatal ("Invalid find_type.\n")); - } - } - /* NOT REACHED */ - } - - default: DO_IF_DEBUG (Pike_fatal ("Invalid find_type.\n")); - } - } - -done: - UNSET_ONERROR (uwp); - sub_extra_ref (msd); - if (node) { - add_msnode_ref (l); - return MSNODE2OFF (msd, node); - } - else return -1; -} - -PMOD_EXPORT ptrdiff_t multiset_find_ge (struct multiset *l, struct svalue *key) -{ - struct multiset_data *msd = l->msd; - union msnode *node; - ONERROR uwp; - - debug_malloc_touch (l); - debug_malloc_touch (msd); - check_svalue (key); - - add_ref (msd); - SET_ONERROR (uwp, free_indirect_multiset_data, &msd); - - while (1) { - enum find_types find_type = low_multiset_find_lt_ge (msd, key, &node); -#ifdef TEST_MULTISET_TRACKING_PATHS - find_type = FIND_DESTRUCTED; -#endif - - if (l->msd != msd) /* Multiset changed; try again. */ - MOVE_MSD_REF_AND_FREE (l, msd); - else - switch (find_type) { - case FIND_LESS: /* Got less - step forward one. */ - node = INODE (node->i.next); - goto done; - case FIND_NOROOT: - case FIND_KEY_DESTRUCTED: - case FIND_GREATER: - goto done; - - case FIND_DESTRUCTED: { - /* Try again with tracking to be able to remove the - * destructed node. */ - RBSTACK_INIT (rbstack); - while (1) { - find_type = low_multiset_track_lt_ge (msd, key, &rbstack); - if (l->msd != msd) - MOVE_MSD_REF_AND_FREE (l, msd); - else - switch (find_type) { - case FIND_LESS: - node = INODE (RBNODE (RBSTACK_PEEK (rbstack))->i.next); - RBSTACK_FREE (rbstack); - goto done; - case FIND_NOROOT: - case FIND_KEY_DESTRUCTED: - case FIND_GREATER: - node = RBNODE (RBSTACK_PEEK (rbstack)); - RBSTACK_FREE (rbstack); - goto done; - case FIND_DESTRUCTED: - sub_extra_ref (msd); - midflight_remove_node_fast (l, &rbstack, 0); - msd = l->msd; - add_ref (msd); - /* Let's stay in tracking mode - if there's one - * destructed index, there might be many. */ - break; - default: DO_IF_DEBUG (Pike_fatal ("Invalid find_type.\n")); - } - } - /* NOT REACHED */ - } - - default: DO_IF_DEBUG (Pike_fatal ("Invalid find_type.\n")); - } - } - -done: - UNSET_ONERROR (uwp); - sub_extra_ref (msd); - if (node) { - add_msnode_ref (l); - return MSNODE2OFF (msd, node); - } - else return -1; -} - -PMOD_EXPORT ptrdiff_t multiset_find_le (struct multiset *l, struct svalue *key) -{ - struct multiset_data *msd = l->msd; - union msnode *node; - ONERROR uwp; - - debug_malloc_touch (l); - debug_malloc_touch (msd); - check_svalue (key); - - add_ref (msd); - SET_ONERROR (uwp, free_indirect_multiset_data, &msd); - - while (1) { - enum find_types find_type = low_multiset_find_le_gt (msd, key, &node); -#ifdef TEST_MULTISET_TRACKING_PATHS - find_type = FIND_DESTRUCTED; -#endif - - if (l->msd != msd) /* Multiset changed; try again. */ - MOVE_MSD_REF_AND_FREE (l, msd); - else - switch (find_type) { - case FIND_LESS: - case FIND_NOROOT: - case FIND_KEY_DESTRUCTED: - goto done; - case FIND_GREATER: /* Got greater - step back one. */ - node = INODE (node->i.prev); - goto done; - - case FIND_DESTRUCTED: { - /* Try again with tracking to be able to remove the - * destructed node. */ - RBSTACK_INIT (rbstack); - while (1) { - find_type = low_multiset_track_le_gt (msd, key, &rbstack); - if (l->msd != msd) - MOVE_MSD_REF_AND_FREE (l, msd); - else - switch (find_type) { - case FIND_LESS: - case FIND_NOROOT: - case FIND_KEY_DESTRUCTED: - node = RBNODE (RBSTACK_PEEK (rbstack)); - RBSTACK_FREE (rbstack); - goto done; - case FIND_GREATER: - node = INODE (RBNODE (RBSTACK_PEEK (rbstack))->i.prev); - RBSTACK_FREE (rbstack); - goto done; - case FIND_DESTRUCTED: - sub_extra_ref (msd); - midflight_remove_node_fast (l, &rbstack, 0); - msd = l->msd; - add_ref (msd); - /* Let's stay in tracking mode - if there's one - * destructed index, there might be many. */ - break; - default: DO_IF_DEBUG (Pike_fatal ("Invalid find_type.\n")); - } - } - /* NOT REACHED */ - } - - default: DO_IF_DEBUG (Pike_fatal ("Invalid find_type.\n")); - } - } - -done: - UNSET_ONERROR (uwp); - sub_extra_ref (msd); - if (node) { - add_msnode_ref (l); - return MSNODE2OFF (msd, node); - } - else return -1; -} - -PMOD_EXPORT ptrdiff_t multiset_find_gt (struct multiset *l, struct svalue *key) -{ - struct multiset_data *msd = l->msd; - union msnode *node; - ONERROR uwp; - - debug_malloc_touch (l); - debug_malloc_touch (msd); - check_svalue (key); - - add_ref (msd); - SET_ONERROR (uwp, free_indirect_multiset_data, &msd); - - while (1) { - enum find_types find_type = low_multiset_find_le_gt (msd, key, &node); -#ifdef TEST_MULTISET_TRACKING_PATHS - find_type = FIND_DESTRUCTED; -#endif - - if (l->msd != msd) /* Multiset changed; try again. */ - MOVE_MSD_REF_AND_FREE (l, msd); - else - switch (find_type) { - case FIND_LESS: /* Got less or equal - step forward one. */ - node = INODE (node->i.next); - goto done; - case FIND_NOROOT: - case FIND_KEY_DESTRUCTED: - case FIND_GREATER: - goto done; - - case FIND_DESTRUCTED: { - /* Try again with tracking to be able to remove the - * destructed node. */ - RBSTACK_INIT (rbstack); - while (1) { - find_type = low_multiset_track_le_gt (msd, key, &rbstack); - if (l->msd != msd) - MOVE_MSD_REF_AND_FREE (l, msd); - else - switch (find_type) { - case FIND_LESS: - node = INODE (RBNODE (RBSTACK_PEEK (rbstack))->i.next); - RBSTACK_FREE (rbstack); - goto done; - case FIND_NOROOT: - case FIND_KEY_DESTRUCTED: - case FIND_GREATER: - node = RBNODE (RBSTACK_PEEK (rbstack)); - RBSTACK_FREE (rbstack); - goto done; - case FIND_DESTRUCTED: - sub_extra_ref (msd); - midflight_remove_node_fast (l, &rbstack, 0); - msd = l->msd; - add_ref (msd); - /* Let's stay in tracking mode - if there's one - * destructed index, there might be many. */ - break; - default: DO_IF_DEBUG (Pike_fatal ("Invalid find_type.\n")); - } - } - /* NOT REACHED */ - } - - default: DO_IF_DEBUG (Pike_fatal ("Invalid find_type.\n")); - } - } - -done: - UNSET_ONERROR (uwp); - sub_extra_ref (msd); - if (node) { - add_msnode_ref (l); - return MSNODE2OFF (msd, node); - } - else return -1; -} - PMOD_EXPORT ptrdiff_t multiset_first (struct multiset *l) { struct multiset_data *msd = l->msd; @@ -2329,79 +1864,6 @@ done: return find_type; } -static enum find_types low_multiset_track_lt_ge ( - struct multiset_data *msd, struct svalue *key, struct rbstack_ptr *track) -{ - struct rb_node_hdr *node = HDR (msd->root); - struct rbstack_ptr rbstack = *track; - enum find_types find_type; - ONERROR uwp; - - /* Note: Similar code in low_multiset_find_lt_ge. */ - -#ifdef PIKE_DEBUG - /* Allow zero refs too since that's used during initial building. */ - if (msd->refs == 1) Pike_fatal ("Copy-on-write assumed here.\n"); - if (!msd->root) Pike_fatal ("Tree assumed to not be empty here.\n"); -#endif - - SET_ONERROR (uwp, rbstack_do_free, track); - - if (TYPEOF(msd->cmp_less) == T_INT) { - struct svalue tmp; - LOW_RB_TRACK_NEQ ( - rbstack, node, - { - low_use_multiset_index (RBNODE (node), tmp); - if (IS_DESTRUCTED (&tmp)) { - UNSET_ONERROR (uwp); - *track = rbstack; - return FIND_DESTRUCTED; - } - /* TODO: Use special variant of set_svalue_cmpfun so we don't - * have to copy the index svalues. */ - INTERNAL_CMP (low_use_multiset_index (RBNODE (node), tmp), key, - cmp_res); - /* Note: CMPFUN_UNORDERED > 0 - treated as equal. */ - cmp_res = cmp_res >= 0 ? -1 : 1; - }, - {find_type = FIND_LESS; goto done;}, - {find_type = FIND_GREATER; goto done;}); - /* NOT REACHED */ - } - - else { - LOW_RB_TRACK_NEQ ( - rbstack, node, - { - low_push_multiset_index (RBNODE (node)); - if (IS_DESTRUCTED (sp - 1)) { - pop_2_elems(); - UNSET_ONERROR (uwp); - *track = rbstack; - return FIND_DESTRUCTED; - } - push_svalue (key); - EXTERNAL_CMP (&msd->cmp_less); - cmp_res = UNSAFE_IS_ZERO (sp - 1) ? -1 : 1; - pop_stack(); - }, - {find_type = FIND_LESS; goto done;}, - {find_type = FIND_GREATER; goto done;}); - /* NOT REACHED */ - } - -done: - UNSET_ONERROR (uwp); - if (IS_DESTRUCTED (key)) { - RBSTACK_FREE (rbstack); - *track = rbstack; - return FIND_KEY_DESTRUCTED; - } - *track = rbstack; - return find_type; -} - PMOD_EXPORT void multiset_fix_type_field (struct multiset *l) { struct multiset_data *msd = l->msd; @@ -2466,175 +1928,47 @@ static void check_multiset_type_fields (struct multiset *l) } #endif -PMOD_EXPORT void multiset_insert (struct multiset *l, - struct svalue *ind) -{ - debug_malloc_touch (l); - debug_malloc_touch (l->msd); - dmalloc_touch_svalue (ind); - multiset_insert_2 (l, ind, NULL, 1); -} - #define ADD_NODE(MSD, RBSTACK, NEW, IND, VAL, FIND_TYPE) do { \ - assign_svalue_no_free (&NEW->i.ind, IND); \ - MSD->ind_types |= 1 << TYPEOF(*(IND)); \ - DO_IF_DEBUG (SET_SVAL_TYPE(NEW->i.ind, \ - TYPEOF(NEW->i.ind) | \ - MULTISET_FLAG_MARKER)); \ - if (MSD->flags & MULTISET_INDVAL) { \ - if (VAL) { \ - assign_svalue_no_free (&NEW->iv.val, VAL); \ - MSD->val_types |= 1 << TYPEOF(*(VAL)); \ - } \ - else { \ - SET_SVAL(NEW->iv.val, T_INT, NUMBER_NUMBER, integer, 1); \ - MSD->val_types |= BIT_INT; \ - } \ - } \ - switch (FIND_TYPE) { \ - case FIND_LESS: \ - low_rb_link_at_next (PHDR (&MSD->root), RBSTACK, HDR (NEW)); \ - break; \ - case FIND_GREATER: \ - low_rb_link_at_prev (PHDR (&MSD->root), RBSTACK, HDR (NEW)); \ - break; \ - case FIND_NOROOT: \ - MSD->root = NEW; \ - low_rb_init_root (HDR (NEW)); \ - break; \ - default: DO_IF_DEBUG (Pike_fatal ("Invalid find_type.\n")); \ - } \ - } while (0) - -/* val may be zero. If the multiset has values, the integer 1 will be - * used as value in that case. val is ignored if the multiset has no - * values. The value of an existing entry will be replaced iff replace - * is nonzero (done under the assumption the caller has one value - * lock), otherwise nothing will be done in that case. Nothing is - * done if ind is destructed. */ -PMOD_EXPORT ptrdiff_t multiset_insert_2 (struct multiset *l, - struct svalue *ind, - struct svalue *val, - int replace) -{ - struct multiset_data *msd = l->msd; - union msnode *new; - enum find_types find_type; - ONERROR uwp; - RBSTACK_INIT (rbstack); - - /* Note: Similar code in multiset_add, multiset_add_after, - * multiset_delete_2 and multiset_delete_node. */ - -#ifdef PIKE_DEBUG - debug_malloc_touch (l); - debug_malloc_touch (msd); - check_svalue (ind); - if (val) check_svalue (val); -#endif - - SET_ONERROR (uwp, free_indirect_multiset_data, &msd); - - while (1) { - if (!msd->root) { - if (IS_DESTRUCTED (ind)) { - UNSET_ONERROR (uwp); - return -1; - } - if (prepare_for_add (l, l->node_refs)) msd = l->msd; - ALLOC_MSNODE (msd, l->node_refs, new); - find_type = FIND_NOROOT; - goto insert; - } - - if (!msd->free_list && !l->node_refs && msd->refs == 1) { - /* Enlarge now if possible, anticipating there will be an - * insert. Otherwise we either have to redo the search or don't - * use a rebalancing resize. */ -#ifdef PIKE_DEBUG - if (d_flag > 1) check_multiset (l, 1); -#endif - l->msd = resize_multiset_data (msd, ENLARGE_SIZE (msd->allocsize), 0); - msd = l->msd; - } -#if 0 - else - if (msd->size == msd->allocsize) - fputs ("Can't rebalance multiset tree in multiset_insert_2\n", stderr); -#endif - - add_ref (msd); - find_type = low_multiset_track_eq (msd, ind, &rbstack); - - if (l->msd != msd) { - RBSTACK_FREE (rbstack); - if (!sub_ref (msd)) free_multiset_data (msd); - msd = l->msd; - } - - else - switch (find_type) { - case FIND_LESS: - case FIND_GREATER: - sub_extra_ref (msd); - if (prepare_for_add (l, 1)) { - rbstack_shift (rbstack, HDR (msd->nodes), HDR (l->msd->nodes)); - msd = l->msd; - } - ALLOC_MSNODE (msd, l->node_refs, new); - goto insert; - - case FIND_EQUAL: { - struct rb_node_hdr *node = RBSTACK_PEEK (rbstack); - RBSTACK_FREE (rbstack); - UNSET_ONERROR (uwp); - sub_extra_ref (msd); - if (replace && msd->flags & MULTISET_INDVAL) { - if (prepare_for_value_change (l, 1)) { - node = SHIFT_HDRPTR (node, msd, l->msd); - msd = l->msd; - } - if (val) { - assign_svalue (&RBNODE (node)->iv.val, val); - msd->val_types |= 1 << TYPEOF(*val); - } - else { - free_svalue (&RBNODE (node)->iv.val); - SET_SVAL(RBNODE (node)->iv.val, T_INT, NUMBER_NUMBER, - integer, 1); - msd->val_types |= BIT_INT; - } - } - return MSNODE2OFF (msd, RBNODE (node)); - } - - case FIND_DESTRUCTED: - sub_extra_ref (msd); - midflight_remove_node_fast (l, &rbstack, 0); - msd = l->msd; - break; - - case FIND_KEY_DESTRUCTED: - sub_extra_ref (msd); - UNSET_ONERROR (uwp); - return -1; - - default: DO_IF_DEBUG (Pike_fatal ("Invalid find_type.\n")); - } - } - -insert: - UNSET_ONERROR (uwp); - ADD_NODE (msd, rbstack, new, ind, val, find_type); - return MSNODE2OFF (msd, new); -} + assign_svalue_no_free (&NEW->i.ind, IND); \ + MSD->ind_types |= 1 << TYPEOF(*(IND)); \ + DO_IF_DEBUG (SET_SVAL_TYPE(NEW->i.ind, \ + TYPEOF(NEW->i.ind) | \ + MULTISET_FLAG_MARKER)); \ + if (MSD->flags & MULTISET_INDVAL) { \ + if (VAL) { \ + assign_svalue_no_free (&NEW->iv.val, VAL); \ + MSD->val_types |= 1 << TYPEOF(*(VAL)); \ + } \ + else { \ + SET_SVAL(NEW->iv.val, T_INT, NUMBER_NUMBER, integer, 1); \ + MSD->val_types |= BIT_INT; \ + } \ + } \ + switch (FIND_TYPE) { \ + case FIND_LESS: \ + low_rb_link_at_next (PHDR (&MSD->root), RBSTACK, HDR (NEW)); \ + break; \ + case FIND_GREATER: \ + low_rb_link_at_prev (PHDR (&MSD->root), RBSTACK, HDR (NEW)); \ + break; \ + case FIND_NOROOT: \ + MSD->root = NEW; \ + low_rb_init_root (HDR (NEW)); \ + break; \ + default: DO_IF_DEBUG (Pike_fatal ("Invalid find_type.\n")); \ + } \ + } while (0) /* val may be zero. If the multiset has values, the integer 1 will be - * used as value then. val is ignored if the multiset has no values. - * Nothing is done if ind is destructed. */ -PMOD_EXPORT ptrdiff_t multiset_add (struct multiset *l, - struct svalue *ind, - struct svalue *val) + * used as value in that case. val is ignored if the multiset has no + * values. The value of an existing entry will be replaced iff replace + * is nonzero (done under the assumption the caller has one value + * lock), otherwise nothing will be done in that case. Nothing is + * done if ind is destructed. */ +static ptrdiff_t multiset_insert_2 (struct multiset *l, + struct svalue *ind, + struct svalue *val, + int replace) { struct multiset_data *msd = l->msd; union msnode *new; @@ -2642,7 +1976,7 @@ PMOD_EXPORT ptrdiff_t multiset_add (struct multiset *l, ONERROR uwp; RBSTACK_INIT (rbstack); - /* Note: Similar code in multiset_insert_2, multiset_add_after, + /* Note: Similar code in multiset_add, multiset_add_after, * multiset_delete_2 and multiset_delete_node. */ #ifdef PIKE_DEBUG @@ -2663,16 +1997,13 @@ PMOD_EXPORT ptrdiff_t multiset_add (struct multiset *l, if (prepare_for_add (l, l->node_refs)) msd = l->msd; ALLOC_MSNODE (msd, l->node_refs, new); find_type = FIND_NOROOT; - goto add; + goto insert; } - if (!msd->free_list && !l->node_refs) { - /* Enlarge now if possible. Otherwise we either have to redo the - * search or don't use a rebalancing resize. */ - if (msd->refs > 1) { - l->msd = copy_multiset_data (msd); - MOVE_MSD_REF (l, msd); - } + if (!msd->free_list && !l->node_refs && msd->refs == 1) { + /* Enlarge now if possible, anticipating there will be an + * insert. Otherwise we either have to redo the search or don't + * use a rebalancing resize. */ #ifdef PIKE_DEBUG if (d_flag > 1) check_multiset (l, 1); #endif @@ -2682,11 +2013,11 @@ PMOD_EXPORT ptrdiff_t multiset_add (struct multiset *l, #if 0 else if (msd->size == msd->allocsize) - fputs ("Can't rebalance multiset tree in multiset_add\n", stderr); + fputs ("Can't rebalance multiset tree in multiset_insert_2\n", stderr); #endif add_ref (msd); - find_type = low_multiset_track_le_gt (msd, ind, &rbstack); + find_type = low_multiset_track_eq (msd, ind, &rbstack); if (l->msd != msd) { RBSTACK_FREE (rbstack); @@ -2704,7 +2035,31 @@ PMOD_EXPORT ptrdiff_t multiset_add (struct multiset *l, msd = l->msd; } ALLOC_MSNODE (msd, l->node_refs, new); - goto add; + goto insert; + + case FIND_EQUAL: { + struct rb_node_hdr *node = RBSTACK_PEEK (rbstack); + RBSTACK_FREE (rbstack); + UNSET_ONERROR (uwp); + sub_extra_ref (msd); + if (replace && msd->flags & MULTISET_INDVAL) { + if (prepare_for_value_change (l, 1)) { + node = SHIFT_HDRPTR (node, msd, l->msd); + msd = l->msd; + } + if (val) { + assign_svalue (&RBNODE (node)->iv.val, val); + msd->val_types |= 1 << TYPEOF(*val); + } + else { + free_svalue (&RBNODE (node)->iv.val); + SET_SVAL(RBNODE (node)->iv.val, T_INT, NUMBER_NUMBER, + integer, 1); + msd->val_types |= BIT_INT; + } + } + return MSNODE2OFF (msd, RBNODE (node)); + } case FIND_DESTRUCTED: sub_extra_ref (msd); @@ -2721,12 +2076,21 @@ PMOD_EXPORT ptrdiff_t multiset_add (struct multiset *l, } } -add: +insert: UNSET_ONERROR (uwp); ADD_NODE (msd, rbstack, new, ind, val, find_type); return MSNODE2OFF (msd, new); } +PMOD_EXPORT void multiset_insert (struct multiset *l, + struct svalue *ind) +{ + debug_malloc_touch (l); + debug_malloc_touch (l->msd); + dmalloc_touch_svalue (ind); + multiset_insert_2 (l, ind, NULL, 1); +} + #define TEST_LESS(MSD, A, B, CMP_RES) do { \ if (TYPEOF(MSD->cmp_less) == T_INT) \ INTERNAL_CMP (A, B, CMP_RES); \ @@ -2739,217 +2103,6 @@ add: } \ } while (0) -/* val may be zero. If the multiset has values, the integer 1 will be - * used as value then. val is ignored if the multiset has no values. - * The new entry is added first if nodepos < 0. - * - * -1 is returned if the entry couldn't be added after the specified - * node because that would break the order. This is always checked, - * since it might occur due to concurrent changes of the multiset. - * - * Nothing is done if ind is destructed. -1 is returned in that case - * too. - * - * Otherwise the offset of the new node is returned (as usual). */ -PMOD_EXPORT ptrdiff_t multiset_add_after (struct multiset *l, - ptrdiff_t nodepos, - struct svalue *ind, - struct svalue *val) -{ - struct multiset_data *msd = l->msd; - union msnode *new; - struct rb_node_hdr *node; - enum find_types find_type; - int cmp_res; - struct svalue tmp; - ONERROR uwp; - RBSTACK_INIT (rbstack); - - /* Note: Similar code in multiset_insert_2, multiset_add, - * multiset_delete_2 and multiset_delete_node. */ - -#ifdef PIKE_DEBUG - debug_malloc_touch (l); - debug_malloc_touch (msd); - check_svalue (ind); - if (val) check_svalue (val); - if (nodepos >= 0) check_msnode (l, nodepos, 1); -#endif - - SET_ONERROR (uwp, free_indirect_multiset_data, &msd); - - while (1) { - if (!(node = HDR (msd->root))) { - if (IS_DESTRUCTED (ind)) { - UNSET_ONERROR (uwp); - return -1; - } - if (prepare_for_add (l, l->node_refs)) msd = l->msd; - ALLOC_MSNODE (msd, l->node_refs, new); - find_type = FIND_NOROOT; - goto add; - } - - if (nodepos < 0) { - ONERROR uwp2; - - add_node_first: - SET_ONERROR (uwp2, do_sub_msnode_ref, l); - - while (1) { - add_ref (msd); - add_msnode_ref (l); - - LOW_RB_TRACK_FIRST (rbstack, node); - low_use_multiset_index (RBNODE (node), tmp); - if (!IS_DESTRUCTED (&tmp)) break; - - sub_msnode_ref (l); - assert (l->msd == msd); - sub_extra_ref (msd); - midflight_remove_node_fast (l, &rbstack, 0); - } - - TEST_LESS (msd, &tmp, ind, cmp_res); - - if (l->msd != msd) { - /* The multiset changed. Must redo the compare unless the - * same node still is the first one. */ - node = SHIFT_HDRPTR (node, msd, l->msd); - if (node != HDR (low_multiset_first (l->msd))) { - RBSTACK_FREE (rbstack); - UNSET_ONERROR (uwp2); - continue; - } - rbstack_shift (rbstack, HDR (msd->nodes), HDR (l->msd->nodes)); - MOVE_MSD_REF_AND_FREE (l, msd); - } - - UNSET_ONERROR (uwp2); - sub_msnode_ref (l); - assert (l->msd == msd); - sub_extra_ref (msd); - if (cmp_res < 0) {UNSET_ONERROR (uwp); return -1;} - - if (prepare_for_add (l, 1)) { - rbstack_shift (rbstack, HDR (msd->nodes), HDR (l->msd->nodes)); - msd = l->msd; - } - ALLOC_MSNODE (msd, l->node_refs, new); - find_type = FIND_GREATER; - goto add; - } - - else { - int cmp_res; - union msnode *existing = OFF2MSNODE (msd, nodepos); - - while (TYPEOF(existing->i.ind) == T_DELETED) { - existing = DELETED_PREV (existing); - if (!existing) goto add_node_first; - } - - add_ref (msd); - - { /* Compare against the following node. */ - union msnode *next = existing; - do { - next = low_multiset_next (next); - if (!next) break; - low_use_multiset_index (next, tmp); - } while (IS_DESTRUCTED (&tmp)); - if (next) { - TEST_LESS (msd, &tmp, ind, cmp_res); - if (l->msd != msd) { - if (!sub_ref (msd)) free_multiset_data (msd); - msd = l->msd; - continue; - } - if (cmp_res < 0) { - UNSET_ONERROR (uwp); - sub_extra_ref (msd); - return -1; - } - } - } - - find_type = low_multiset_track_le_gt (msd, ind, &rbstack); - - if (l->msd != msd) goto multiset_changed; - - switch (find_type) { - case FIND_DESTRUCTED: - sub_extra_ref (msd); - midflight_remove_node_fast (l, &rbstack, 0); - msd = l->msd; - continue; - - case FIND_KEY_DESTRUCTED: - sub_extra_ref (msd); - UNSET_ONERROR (uwp); - return -1; - - default: break; /* Avoid compiler warning. */ - } - - /* Step backwards until the existing node is found, or until - * we're outside the range of compare-wise equal nodes. */ - node = RBSTACK_PEEK (rbstack); - cmp_res = 0; - while (RBNODE (node) != existing) { - low_use_multiset_index (RBNODE (node), tmp); - if (IS_DESTRUCTED (&tmp)) { - sub_extra_ref (msd); - midflight_remove_node_fast (l, &rbstack, 1); - msd = l->msd; - add_ref (msd); - } - else { - TEST_LESS (msd, &tmp, ind, cmp_res); - if (cmp_res < 0) break; - LOW_RB_TRACK_PREV (rbstack, node); - } - if (!node) {cmp_res = -1; break;} - } - - if (l->msd != msd) goto multiset_changed; - UNSET_ONERROR (uwp); - sub_extra_ref (msd); - - if (cmp_res < 0) return -1; - - if (prepare_for_add (l, 1)) { - rbstack_shift (rbstack, HDR (msd->nodes), HDR (l->msd->nodes)); - node = SHIFT_HDRPTR (node, msd, l->msd); - msd = l->msd; - } - ALLOC_MSNODE (msd, l->node_refs, new); - - /* Find a node to link on to. */ - if (node->flags & RB_THREAD_NEXT) - find_type = FIND_LESS; - else { - node = node->next; - RBSTACK_PUSH (rbstack, node); - while (!(node->flags & RB_THREAD_PREV)) { - node = node->prev; - RBSTACK_PUSH (rbstack, node); - } - find_type = FIND_GREATER; - } - goto add; - - multiset_changed: - RBSTACK_FREE (rbstack); - if (!sub_ref (msd)) free_multiset_data (msd); - msd = l->msd; - } - } - -add: - ADD_NODE (msd, rbstack, new, ind, val, find_type); - return MSNODE2OFF (msd, new); -} PMOD_EXPORT int multiset_delete (struct multiset *l, struct svalue *ind) @@ -3048,7 +2201,7 @@ not_found: } /* Frees the node reference that nodepos represents. */ -PMOD_EXPORT void multiset_delete_node (struct multiset *l, +static void multiset_delete_node (struct multiset *l, ptrdiff_t nodepos) { struct multiset_data *msd = l->msd; @@ -3151,21 +2304,6 @@ PMOD_EXPORT struct svalue *multiset_lookup (struct multiset *l, else return NULL; } - -struct array *multiset_indices (struct multiset *l) -{ - debug_malloc_touch (l); - debug_malloc_touch (l->msd); - return multiset_range_indices (l, -1, -1); -} - -struct array *multiset_values (struct multiset *l) -{ - debug_malloc_touch (l); - debug_malloc_touch (l->msd); - return multiset_range_values (l, -1, -1); -} - #define GET_RANGE_SIZE_AND_END(BEGPOS, ENDPOS, MSD, MSD_SIZE, RANGE_SIZE, END) do { \ if (BEGPOS < 0 && ENDPOS < 0) { \ RANGE_SIZE = MSD_SIZE; \ @@ -3218,7 +2356,7 @@ struct array *multiset_values (struct multiset *l) * the next nondeleted node is used instead, which is found in the * same way as multiset_next. Vice versa for endpos. If the * beginning is after the end then the empty array is returned. */ -struct array *multiset_range_indices (struct multiset *l, +static struct array *multiset_range_indices (struct multiset *l, ptrdiff_t begpos, ptrdiff_t endpos) { struct multiset_data *msd; @@ -3273,7 +2411,7 @@ struct array *multiset_range_indices (struct multiset *l, * the next nondeleted node is used instead, which is found in the * same way as multiset_next. Vice versa for endpos. If the * beginning is after the end then the empty array is returned. */ -struct array *multiset_range_values (struct multiset *l, +static struct array *multiset_range_values (struct multiset *l, ptrdiff_t begpos, ptrdiff_t endpos) { struct multiset_data *msd; @@ -3332,6 +2470,21 @@ struct array *multiset_range_values (struct multiset *l, return values; } + +struct array *multiset_indices (struct multiset *l) +{ + debug_malloc_touch (l); + debug_malloc_touch (l->msd); + return multiset_range_indices (l, -1, -1); +} + +struct array *multiset_values (struct multiset *l) +{ + debug_malloc_touch (l); + debug_malloc_touch (l->msd); + return multiset_range_values (l, -1, -1); +} + /* Eliminates all pointers to destructed objects. If an index is such * a pointer then the node is removed. */ PMOD_EXPORT void check_multiset_for_destruct (struct multiset *l) @@ -4087,17 +3240,6 @@ void describe_multiset (struct multiset *l, struct processing *p, int indent) } } -void simple_describe_multiset (struct multiset *l) -{ - dynamic_buffer save_buf; - char *desc; - init_buf(&save_buf); - describe_multiset (l, NULL, 2); - desc = simple_free_buf(&save_buf); - fprintf (stderr, "%s\n", desc); - free (desc); -} - int multiset_is_constant (struct multiset *l, struct processing *p) { struct multiset_data *msd = l->msd; @@ -4482,14 +3624,14 @@ void gc_check_all_multisets (void) } while ((node = low_multiset_next (node))); \ break; \ \ - case MULTISET_WEAK_VALUES: \ + /* case MULTISET_WEAK_VALUES: \ do { \ low_use_multiset_index (node, ind); \ debug_gc_check_svalues (&ind, 1, " as multiset index"); \ INDVAL (debug_gc_check_weak_svalues (&node->iv.val, 1, \ " as multiset value")); \ } while ((node = low_multiset_next (node))); \ - break; \ + break; \ \ default: \ do { \ @@ -4498,7 +3640,7 @@ void gc_check_all_multisets (void) INDVAL (debug_gc_check_weak_svalues (&node->iv.val, 1, \ " as multiset value")); \ } while ((node = low_multiset_next (node))); \ - break; \ + break;*/ \ } \ gc_checked_as_weak (msd); \ } @@ -4650,6 +3792,7 @@ static void gc_unlink_msnode_shared (struct multiset_data *msd, N_REC (VAL, 1); \ } while (0) +#if MULTISET_WEAK_VALUES #define GC_REC_IV_WEAK_VAL(IND, VAL, REMOVE, N_REC, W_REC, N_TST, W_TST) do { \ if ((REMOVE = N_TST (IND))) /* Don't recurse now. */ \ gc_free_svalue (VAL); \ @@ -4667,6 +3810,7 @@ static void gc_unlink_msnode_shared (struct multiset_data *msd, else \ W_REC (IND, 1); /* Now we can recurse the index. */ \ } while (0) +#endif void gc_mark_multiset_as_referenced (struct multiset *l) { @@ -4709,6 +3853,7 @@ void gc_mark_multiset_as_referenced (struct multiset *l) gc_mark, ind_types, val_types); gc_assert_checked_as_weak (msd); break; +#if MULTISET_WEAK_VALUES case MULTISET_WEAK_VALUES: GC_RECURSE (msd, m->flags & GC_MSD_GOT_NODE_REFS, GC_REC_I_WEAK_NONE, GC_REC_IV_WEAK_VAL, @@ -4720,6 +3865,7 @@ void gc_mark_multiset_as_referenced (struct multiset *l) GC_REC_I_WEAK_IND, GC_REC_IV_WEAK_BOTH, gc_mark, ind_types, val_types); gc_assert_checked_as_weak (msd); +#endif break; } @@ -4780,6 +3926,7 @@ void real_gc_cycle_check_multiset (struct multiset *l, int weak) gc_cycle_check, ind_types, val_types); gc_assert_checked_as_weak (msd); break; +#if MULTISET_WEAK_VALUES case MULTISET_WEAK_VALUES: GC_RECURSE (msd, m->flags & GC_MSD_GOT_NODE_REFS, GC_REC_I_WEAK_NONE, GC_REC_IV_WEAK_VAL, @@ -4792,6 +3939,7 @@ void real_gc_cycle_check_multiset (struct multiset *l, int weak) gc_cycle_check, ind_types, val_types); gc_assert_checked_as_weak (msd); break; +#endif } if (msd->refs == 1 && DO_SHRINK (msd, 0)) { @@ -5252,6 +4400,17 @@ static void debug_dump_indval_data (struct msnode_indval *node, node->val.u.refs, MSNODE2OFF (msd, IVNODE (node))); } +static void simple_describe_multiset (struct multiset *l) +{ + dynamic_buffer save_buf; + char *desc; + init_buf(&save_buf); + describe_multiset (l, NULL, 2); + desc = simple_free_buf(&save_buf); + fprintf (stderr, "%s\n", desc); + free (desc); +} + void debug_dump_multiset (struct multiset *l) { struct multiset_data *msd = l->msd; diff --git a/src/multiset.h b/src/multiset.h index 70fa1b83bf..591764fcae 100644 --- a/src/multiset.h +++ b/src/multiset.h @@ -138,12 +138,12 @@ struct multiset * remembered even after it has been deleted. */ -/* The following are compatible with PIKE_WEAK_INDICES and PIKE_WEAK_VALUES. */ #define MULTISET_WEAK_INDICES 2 -#define MULTISET_WEAK_VALUES 4 -#define MULTISET_WEAK 6 +#define MULTISET_WEAK 2 -#define MULTISET_INDVAL 8 +#define MULTISET_WEAK_VALUES 0 + +#define MULTISET_INDVAL 0 extern struct multiset *first_multiset; extern struct multiset *gc_internal_multiset; @@ -167,7 +167,6 @@ PMOD_EXPORT extern const char msg_no_multiset_flag_marker[]; #define low_multiset_next(NODE) MULTISET_STEP_FUNC (rb_next, NODE) #define low_multiset_get_nth(MSD, N) \ ((union msnode *) rb_get_nth ((struct rb_node_hdr *) (MSD)->root, (N))) -union msnode *low_multiset_find_eq (struct multiset *l, struct svalue *key); #define low_assign_multiset_index_no_free(TO, NODE) do { \ struct svalue *_ms_index_to_ = (TO); \ @@ -306,11 +305,6 @@ PMOD_EXPORT union msnode *debug_check_msnode ( */ /* Returns the node offset, or -1 if no match was found. */ -PMOD_EXPORT ptrdiff_t multiset_find_eq (struct multiset *l, struct svalue *key); -PMOD_EXPORT ptrdiff_t multiset_find_lt (struct multiset *l, struct svalue *key); -PMOD_EXPORT ptrdiff_t multiset_find_gt (struct multiset *l, struct svalue *key); -PMOD_EXPORT ptrdiff_t multiset_find_le (struct multiset *l, struct svalue *key); -PMOD_EXPORT ptrdiff_t multiset_find_ge (struct multiset *l, struct svalue *key); PMOD_EXPORT ptrdiff_t multiset_first (struct multiset *l); PMOD_EXPORT ptrdiff_t multiset_last (struct multiset *l); PMOD_EXPORT ptrdiff_t multiset_prev (struct multiset *l, ptrdiff_t nodepos); @@ -379,42 +373,22 @@ PMOD_EXPORT struct multiset *real_allocate_multiset (int allocsize, PMOD_EXPORT void do_free_multiset (struct multiset *l); PMOD_EXPORT void multiset_fix_type_field (struct multiset *l); PMOD_EXPORT void multiset_set_flags (struct multiset *l, int flags); -PMOD_EXPORT void multiset_set_cmp_less (struct multiset *l, - struct svalue *cmp_less); PMOD_EXPORT struct multiset *mkmultiset (struct array *indices); -PMOD_EXPORT struct multiset *mkmultiset_2 (struct array *indices, - struct array *values, - struct svalue *cmp_less); PMOD_EXPORT void multiset_insert (struct multiset *l, struct svalue *ind); -PMOD_EXPORT ptrdiff_t multiset_insert_2 (struct multiset *l, - struct svalue *ind, - struct svalue *val, - int replace); -PMOD_EXPORT ptrdiff_t multiset_add (struct multiset *l, - struct svalue *ind, - struct svalue *val); -PMOD_EXPORT ptrdiff_t multiset_add_after (struct multiset *l, - ptrdiff_t node, - struct svalue *ind, - struct svalue *val); PMOD_EXPORT int multiset_delete (struct multiset *l, struct svalue *ind); +#ifdef MULTISET_INDVAL PMOD_EXPORT int multiset_delete_2 (struct multiset *l, struct svalue *ind, struct svalue *removed_val); -PMOD_EXPORT void multiset_delete_node (struct multiset *l, - ptrdiff_t node); -PMOD_EXPORT int multiset_member (struct multiset *l, - struct svalue *key); PMOD_EXPORT struct svalue *multiset_lookup (struct multiset *l, struct svalue *key); +#endif +PMOD_EXPORT int multiset_member (struct multiset *l, + struct svalue *key); struct array *multiset_indices (struct multiset *l); struct array *multiset_values (struct multiset *l); -struct array *multiset_range_indices (struct multiset *l, - ptrdiff_t beg, ptrdiff_t end); -struct array *multiset_range_values (struct multiset *l, - ptrdiff_t beg, ptrdiff_t end); PMOD_EXPORT void check_multiset_for_destruct (struct multiset *l); PMOD_EXPORT struct multiset *copy_multiset (struct multiset *l); PMOD_EXPORT struct multiset *merge_multisets (struct multiset *a, @@ -424,7 +398,6 @@ PMOD_EXPORT struct multiset *add_multisets (struct svalue *argp, int count); PMOD_EXPORT int multiset_equal_p (struct multiset *a, struct multiset *b, struct processing *p); void describe_multiset (struct multiset *l, struct processing *p, int indent); -void simple_describe_multiset (struct multiset *l); int multiset_is_constant (struct multiset *l, struct processing *p); node *make_node_from_multiset (struct multiset *l); PMOD_EXPORT void f_aggregate_multiset (int args); diff --git a/src/operators.c b/src/operators.c index 2edf7f9253..04e1b41ce2 100644 --- a/src/operators.c +++ b/src/operators.c @@ -852,7 +852,7 @@ PMOD_EXPORT void o_cast(struct pike_type *type, INT32 run_time_type) do { push_multiset_index (tmp, nodepos); o_cast(itype, run_time_itype); - multiset_insert_2 (m, sp - 1, NULL, 0); + multiset_insert (m, sp - 1); pop_stack(); } while ((nodepos = multiset_next (tmp, nodepos)) >= 0); UNSET_ONERROR (uwp); -- GitLab