Exemplo n.º 1
0
/* Search and, if missing, insert. */
void *
dwarf_tsearch(const void *key, void **headpin,
    int (*compar)(const void *, const void *))
{
    struct ts_entry *head = 0;
    struct ts_entry *root = 0;
    struct ts_entry *r = 0;
    int inserted = 0;

    if(!headpin) {
        return NULL;
    }
    head = (struct ts_entry *)*headpin;
    if(head) {
        root = head->rlink;
    }
    if(!head || !root) {
        if(!head) {
            head = allocate_ts_entry(0);
        }
        if(!head) {
            return NULL;
        }
        root = allocate_ts_entry(key);
        if(!root) {
            free(root);
            return NULL;
        }
        head->rlink = root;
        *headpin = head;
        return (void *)(&(root->keyptr));
    }
    root = head->rlink;
    r = tsearch_inner(key,root,compar,&inserted);
    if (!r) {
        return NULL;
    }
    /*  Was this found or inserted?
        Value is the same either way, but the pointer to return
        is not the same! */
    /* Discards const.  Required by the interface definition. */
    return (void *)&(r->keyptr);
}
Exemplo n.º 2
0
/* Search and, if missing, insert. */
void *
dwarf_tsearch(const void *key, void **headin,
    int (*compar)(const void *, const void *))
{
    struct ts_entry **headp = (struct ts_entry **)headin;
    struct ts_entry *head = 0;
    struct ts_entry *r = 0;
    int inserted = 0;
    /* kcomparv should be ignored */
    int kcomparv = 0;
    /* nullme won't be set. */
    struct ts_entry *nullme = 0;

    if (!headp) {
        return NULL;
    }
    head = *headp;
    if (!head) {
        struct ts_entry *root = 0;
        head = allocate_ts_entry(0);
        if(!head) {
            return NULL;
        }
        root = allocate_ts_entry(key);
        if(!root) {
            free(head);
            return NULL;
        }
        head->rlink = root;
        /* head->llink is used for the depth, as a count */
        /* head points to the special head node ... */
        *headin = head;
        return (void *)(&(root->keyptr));
    }
    r = tsearch_inner(key,head,compar,&inserted,&nullme,&kcomparv);
    if (!r) {
        return NULL;
    }
    return (void *)&(r->keyptr);
}
Exemplo n.º 3
0
/* Knuth step T5, the insert. */
static struct ts_entry *
tsearch_insert_k(const void *key,int kc,
    struct ts_entry *p)
{
    struct ts_entry *q = allocate_ts_entry(key);
    if (!q) {
        /* out of memory */
        return NULL;
    }
    setlink(p,kc,q);
    /* Non-NULL means inserted. */
    return q;
}
Exemplo n.º 4
0
/* Knuth step T5, the insert. */
static struct ts_entry *
tsearch_insert_k(const void *key,int kc,
    struct ts_entry *p)
{
    struct ts_entry *e = allocate_ts_entry(key);
    if (!e) {
        /* out of memory */
        return NULL;
    }
    if( kc < 0) {
        p->llink = e;
    } else {
        p->rlink = e;
    }
    /* Non-NULL means inserted. */
    return e;
}
Exemplo n.º 5
0
/*   Inner search of the hash and synonym chains.
  */
static struct ts_entry *
tsearch_inner( const void *key, struct hs_base* head,
               int (*compar)(const void *, const void *),
               const enum search_intent_t intent, int*inserted,
               /* owner_ptr used for delete.  Only set
                   if the to-be-deleted item is on a chain,
                   not in the hashtab. Points to the item
                   pointing to the to-be-deleted-item.*/
               struct ts_entry **owner_ptr)
{
    struct ts_entry *s =0;
    struct ts_entry *c =0;
    struct ts_entry *q =0;
    int kc = 0;
    unsigned long keyhash =  0;
    unsigned long hindx = 0;
    struct ts_entry *chain_parent = 0;

    if(! head->hashfunc_) {
        /* Not fully initialized. */
        return NULL;
    }
    keyhash =  head->hashfunc_(key);
    if (intent == want_insert) {
        if( head->record_count_ > head->allowed_fill_) {
            resize_table(head,compar);
        }
    }
    hindx = keyhash%head->tablesize_;
    s = &head->hashtab_[hindx];
    if(!s->entryused) {
        /* Not found. */
        if(intent != want_insert) {
            return NULL;
        }
        /*  Insert in the base hash table in an
            empty slot. */
        *inserted = 1;
        head->record_count_++;
        s->keyptr = (const void *)key;
        s->entryused = 1;
        s->next = 0;
        return s;
    }
    kc = compar(key,s->keyptr);
    if(kc == 0 ) {
        /* found! */
        if(want_delete) {
            *owner_ptr = 0;
        }
        return (void *)&(s->keyptr);
    }
    chain_parent = s;
    for(c = s->next; c; c = c->next)  {
        kc = compar(key,c->keyptr);
        if(kc == 0 ) {
            /* found! */
            if(want_delete) {
                *owner_ptr = chain_parent;
            }
            return (void *)&(c->keyptr);
        }
        chain_parent = c;
    }
    if(intent != want_insert) {
        return NULL;
    }
    /* Insert following head record of the chain. */
    q = allocate_ts_entry(key);
    if (!q) {
        return q;
    }
    q->next = s->next;
    s->next = q;
    head->record_count_++;
    *inserted = 1;
    return q;
}