Commit d5c78593 authored by Nick Mathewson's avatar Nick Mathewson 🥔
Browse files

r13873@Kushana: nickm | 2007-07-31 10:54:05 -0700

 Split over-optimized digestmap_set code into a generic part and a digestmap-specific part.


svn:r11012
parent 484c8b77
Loading
Loading
Loading
Loading
+22 −27
Original line number Diff line number Diff line
@@ -769,8 +769,6 @@ digestmap_set(digestmap_t *map, const char *key, void *val)
{
#ifndef OPTIMIZED_DIGESTMAP_SET
  digestmap_entry_t *resolve;
#else
  digestmap_entry_t **resolve_ptr;
#endif
  digestmap_entry_t search;
  void *oldval;
@@ -792,31 +790,28 @@ digestmap_set(digestmap_t *map, const char *key, void *val)
    return NULL;
  }
#else
  /* XXXX020 We spend up to 5% of our time in this function, so the code
   * below is meant to optimize the check/alloc/set cycle by avoiding the
   * two trips to the hash table that we do in the unoptimized code above.
   * (Each of HT_INSERT and HT_FIND calls HT_SET_HASH and HT_FIND_P.)
   *
   * Unfortunately, doing this requires us to poke around inside hash-table
   * internals.  It would be nice to avoid that. */
  if (!map->head.hth_table ||
      map->head.hth_n_entries >= map->head.hth_load_limit)
    digestmap_impl_HT_GROW((&map->head), map->head.hth_n_entries+1);
  _HT_SET_HASH(&search, node, digestmap_entry_hash);
  resolve_ptr = _digestmap_impl_HT_FIND_P(&map->head, &search);
  if (*resolve_ptr) {
    oldval = (*resolve_ptr)->val;
    (*resolve_ptr)->val = val;
  /* We spend up to 5% of our time in this function, so the code below is
   * meant to optimize the check/alloc/set cycle by avoiding the two trips to
   * the hash table that we do in the unoptimized code above.  (Each of
   * HT_INSERT and HT_FIND calls HT_SET_HASH and HT_FIND_P.)
   */
  _HT_FIND_OR_INSERT(digestmap_impl, node, digestmap_entry_hash, &(map->head),
         digestmap_entry_t, &search, ptr,
         {
            /* we found an entry. */
            oldval = (*ptr)->val;
            (*ptr)->val = val;
            return oldval;
  } else {
    digestmap_entry_t *newent = tor_malloc_zero(sizeof(digestmap_entry_t));
         },
         {
           /* We didn't find the entry. */
           digestmap_entry_t *newent =
             tor_malloc_zero(sizeof(digestmap_entry_t));
           memcpy(newent->key, key, DIGEST_LEN);
           newent->val = val;
    newent->node.hte_hash = search.node.hte_hash;
    *resolve_ptr = newent;
    ++map->head.hth_n_entries;
           _HT_FOI_INSERT(node, &(map->head), &search, newent, ptr);
           return NULL;
  }
         });
#endif
}

+25 −0
Original line number Diff line number Diff line
@@ -382,6 +382,31 @@ ht_string_hash(const char *s)
    return 0;                                                           \
  }

/** Implements an over-optimized "find and insert if absent" block;
 * not meant for direct usage by typical code, or usage outside the critical
 * path.*/
#define _HT_FIND_OR_INSERT(name, field, hashfn, head, eltype, elm, var, y, n) \
  {                                                                     \
    struct name *_##var##_head = head;                                  \
    eltype **var;                                                       \
    if (!_##var##_head->hth_table ||                                    \
        _##var##_head->hth_n_entries >= _##var##_head->hth_load_limit)  \
      name##_HT_GROW(_##var##_head, _##var##_head->hth_n_entries+1);     \
    _HT_SET_HASH((elm), field, hashfn);                                \
    var = _##name##_HT_FIND_P(_##var##_head, (elm));                    \
    if (*var) {                                                         \
      y;                                                                \
    } else {                                                            \
      n;                                                                \
    }                                                                   \
  }
#define _HT_FOI_INSERT(field, head, elm, newent, var)       \
  {                                                         \
    newent->field.hte_hash = (elm)->field.hte_hash;         \
    *var = newent;                                          \
    ++((head)->hth_n_entries);                              \
  }

/*
 * Copyright 2005, Nick Mathewson.  Implementation logic is adapted from code
 * by Cristopher Clark, retrofit to allow drop-in memory management, and to