pike.git / src / multiset.h

version» Context lines:

pike.git/src/multiset.h:11:    *    * Created by Martin Stjernholm 2001-05-07    */      /* #define TEST_MULTISET */      #include "svalue.h"   #include "dmalloc.h"   #include "rbtree.h"    - /* Keep this defined so that code can test which multiset API is in use. */ - #define PIKE_NEW_MULTISETS -  +    /* Note: Don't access the ind svalue (or at least not its type field)    * in the following directly, since the rbtree flags overlay that. Use    * assign_multiset_index_no_free() or similar instead. */      struct msnode_ind   {    struct msnode_ind *prev, *next; /* Must be first. */    struct svalue ind; /* Must be second. */   };    - struct msnode_indval - { -  struct msnode_indval *prev, *next; /* Must be first. */ -  struct svalue ind; /* Must be second. */ -  struct svalue val; - }; -  +    union msnode   {    struct msnode_ind i; -  struct msnode_indval iv; +  struct rb_node_hdr rb_hdr;   };      #define MULTISET_FLAG_MARKER 0x1000   #define MULTISET_FLAG_MASK (RB_FLAG_MASK | MULTISET_FLAG_MARKER)   /* The flag marker is used to reliably nail direct uses of the ind    * type field. */      struct multiset_data   { -  INT32 refs, noval_refs; - #ifdef PIKE_RUN_UNLOCKED - #error multiset_data has not been adapted for running unlocked. - #endif +  GC_MARKER_MEMBERS; +  INT32 noval_refs;    union msnode *root, *free_list;    struct svalue cmp_less;    INT32 size, allocsize;    TYPE_FIELD ind_types;    TYPE_FIELD val_types; /* Always BIT_INT in valueless multisets. */    INT16 flags;    union msnode nodes[1];   };      struct multiset   { -  PIKE_MEMORY_OBJECT_MEMBERS; +  GC_MARKER_MEMBERS;    struct multiset_data *msd;    struct multiset *next, *prev;    INT32 node_refs;   };      /* Data structure notes:    *    * o The node free list through multiset_data.free_list is singly    * linked by the next pointers. Nodes on the free list are either    * free or deleted (see below). Free nodes have ind.type set to
pike.git/src/multiset.h:131:    * some combinations of node references and shared data blocks that    * results in deleted nodes on the free list even after all node    * references are gone.    *    * The prev and ind.u.ptr pointers in deleted nodes point to the    * previous and next neighbor, respectively, of the node at the    * time it was deleted. Thus the relative position of the node is    * 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 -  +    extern struct multiset *first_multiset;   extern struct multiset *gc_internal_multiset;      PMOD_EXPORT void multiset_clear_node_refs (struct multiset *l);      #ifdef PIKE_DEBUG   /* To get good type checking. */ - static INLINE union msnode *msnode_check (union msnode *x) + static inline union msnode PIKE_UNUSED_ATTRIBUTE *msnode_check (union msnode *x)    {return x;}   PMOD_EXPORT extern const char msg_no_multiset_flag_marker[];   #else   #define msnode_check(X) ((union msnode *) (X))   #endif      #define MULTISET_STEP_FUNC(FUNC, NODE) \ -  ((union msnode *) FUNC ((struct rb_node_hdr *) msnode_check (NODE))) +  ((union msnode *) FUNC (&(msnode_check(NODE)->rb_hdr)))   #define low_multiset_first(MSD) MULTISET_STEP_FUNC (rb_first, (MSD)->root)   #define low_multiset_last(MSD) MULTISET_STEP_FUNC (rb_last, (MSD)->root)   #define low_multiset_prev(NODE) MULTISET_STEP_FUNC (rb_prev, NODE)   #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); +  ((union msnode *) rb_get_nth (&((MSD)->root->rb_hdr), (N)))      #define low_assign_multiset_index_no_free(TO, NODE) do { \    struct svalue *_ms_index_to_ = (TO); \    *_ms_index_to_ = msnode_check (NODE)->i.ind; \    DO_IF_DEBUG ( \    if (!(TYPEOF(*_ms_index_to_) & MULTISET_FLAG_MARKER)) \    Pike_fatal (msg_no_multiset_flag_marker); \    ); \    SET_SVAL_TYPE(*_ms_index_to_, \    TYPEOF(*_ms_index_to_) & ~MULTISET_FLAG_MASK); \
pike.git/src/multiset.h:188:   #define low_push_multiset_index(NODE) \    low_assign_multiset_index_no_free (Pike_sp++, (NODE))   #define low_use_multiset_index(NODE, VAR) \    ((VAR) = msnode_check (NODE)->i.ind, \    DO_IF_DEBUG (TYPEOF(VAR) & MULTISET_FLAG_MARKER ? 0 : \    (Pike_fatal (msg_no_multiset_flag_marker), 0) COMMA) \    SET_SVAL_TYPE((VAR), TYPEOF(VAR) & ~MULTISET_FLAG_MASK), \    &(VAR))      #define low_get_multiset_value(MSD, NODE) \ -  ((MSD)->flags & MULTISET_INDVAL ? &(NODE)->iv.val : \ -  /* Caller better not try to change this. */ \ +  (/* Caller better not try to change this. */ \    (struct svalue *) &svalue_int_one) - #define low_set_multiset_value(MSD, NODE, VAL) do { \ -  if ((MSD)->flags & MULTISET_INDVAL) \ -  assign_svalue (&(NODE)->iv.val, VAL); \ -  } while (0) +       #define OFF2MSNODE(MSD, OFFSET) \ -  ((MSD)->flags & MULTISET_INDVAL ? \ -  (union msnode *) (&(MSD)->nodes->iv + (OFFSET)) : \ -  (union msnode *) (&(MSD)->nodes->i + (OFFSET))) +  ((MSD)->nodes + (OFFSET))   #define MSNODE2OFF(MSD, NODE) \ -  ((MSD)->flags & MULTISET_INDVAL ? \ -  &(NODE)->iv - &(MSD)->nodes->iv : &(NODE)->i - &(MSD)->nodes->i) +  ((NODE) - (MSD)->nodes)      PMOD_EXPORT INT32 multiset_sizeof (struct multiset *l);   #define l_sizeof(L) multiset_sizeof (L)   #define multiset_ind_types(L) ((L)->msd->ind_types)   #define multiset_val_types(L) ((L)->msd->val_types)   #define multiset_get_flags(L) ((L)->msd->flags)   #define multiset_get_cmp_less(L) (&(L)->msd->cmp_less) - #define multiset_indval(L) ((L)->msd->flags & MULTISET_INDVAL) +       /* This is somewhat faster than using multiset_sizeof just to    * check whether or not the multiset has no elements at all. */   #define multiset_is_empty(L) (!(L)->msd->root)      #if defined(USE_DLL) && defined(DYNAMIC_MODULE)   /* Use the function in modules so we don't have to export the block    * alloc stuff. */   #define free_multiset(M) do_free_multiset (M)   #else
pike.git/src/multiset.h:299:    * (even when cmp_less isn't used), the multiset may change during the    * search in it. If that happens for a destructive operation, it's    * remade in one way or the other to ensure that the change has been    * made in the multiset that is current upon return. This normally has    * no caller visible effects, except for multiset_add_after, which    * might fail to add the requested entry (it returns less than zero in    * that case).    */      /* 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);   PMOD_EXPORT ptrdiff_t multiset_next (struct multiset *l, ptrdiff_t nodepos);      #ifdef PIKE_DEBUG   PMOD_EXPORT extern const char msg_multiset_no_node_refs[];   #endif      #define add_msnode_ref(L) do {(L)->node_refs++;} while (0)
pike.git/src/multiset.h:344:    low_assign_multiset_index (TO, _ms_node_); \    } while (0)   #define push_multiset_index(L, NODEPOS) \    assign_multiset_index_no_free (Pike_sp++, (L), (NODEPOS))   #define use_multiset_index(L, NODEPOS, VAR) \    ((VAR) = access_msnode ((L), (NODEPOS))->i.ind, \    SET_SVAL_TYPE((VAR), TYPEOF(VAR) & ~MULTISET_FLAG_MASK), \    &(VAR))      #define get_multiset_value(L, NODEPOS) \ -  ((L)->msd->flags & MULTISET_INDVAL ? \ -  &access_msnode ((L), (NODEPOS))->iv.val : \ -  /* Caller better not try to change this. */ \ +  (/* Caller better not try to change this. */ \    (struct svalue *) &svalue_int_one) - #define set_multiset_value(L, NODEPOS, VAL) do { \ -  if ((L)->msd->flags & MULTISET_INDVAL) \ -  assign_svalue (&access_msnode ((L), (NODEPOS))->iv.val, VAL); \ -  } while (0) +    /* Note: It's intentional that the value is silently ignored for    * index-only multisets. */      #define assign_multiset_value_no_free(TO, L, NODEPOS) \    assign_svalue_no_free (TO, get_multiset_value (L, NODEPOS))   #define assign_multiset_value(TO, L, NODEPOS) \    assign_svalue (TO, get_multiset_value (L, NODEPOS))   #define push_multiset_value(L, NODEPOS) \    push_svalue (get_multiset_value (L, NODEPOS))      #define allocate_multiset(allocsize, flags, cmp_less) \    dmalloc_touch (struct multiset *, \    real_allocate_multiset ((allocsize), (flags), (cmp_less)))      PMOD_EXPORT struct multiset *real_allocate_multiset (int allocsize,    int flags,    struct svalue *cmp_less);   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);   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); -  + 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,    struct multiset *b,    int operation);   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); + void describe_multiset (struct byte_buffer *buf, struct multiset *l, struct processing *p, int indent);   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);   struct multiset *copy_multiset_recursively (struct multiset *l,    struct mapping *p);   PMOD_EXPORT ptrdiff_t multiset_get_nth (struct multiset *l, size_t n);    - PMOD_EXPORT void visit_multiset (struct multiset *l, int action); + PMOD_EXPORT void visit_multiset (struct multiset *l, int action, void *extra);   unsigned gc_touch_all_multisets (void);   void gc_check_all_multisets (void);   void gc_mark_multiset_as_referenced (struct multiset *l);   void gc_mark_all_multisets (void);   void gc_zap_ext_weak_refs_in_multisets (void);   void real_gc_cycle_check_multiset (struct multiset *l, int weak);   void gc_cycle_check_all_multisets (void);   size_t gc_free_all_unreferenced_multisets (void);    - #define visit_multiset_ref(L, REF_TYPE) \ + #define visit_multiset_ref(L, REF_TYPE, EXTRA) \    visit_ref (pass_multiset (L), (REF_TYPE), \ -  (visit_thing_fn *) &visit_multiset, NULL) +  (visit_thing_fn *) &visit_multiset, (EXTRA))   #define gc_cycle_check_multiset(X, WEAK) \    gc_cycle_enqueue ((gc_cycle_check_cb *) real_gc_cycle_check_multiset, (X), (WEAK))      #ifdef PIKE_DEBUG   void check_multiset (struct multiset *l, int safe);   void check_all_multisets (int safe);   void debug_dump_multiset (struct multiset *l);   #endif      void count_memory_in_multisets (size_t *num, size_t *size);   void init_multiset (void);   void exit_multiset (void);   void test_multiset (void);      #endif /* MULTISET_H */