Branch: Tag:

2011-04-05

2011-04-05 12:20:06 by Arne Goedeke <el@laramies.com>

mapping: use power of two hashtables and a mixing function instead of
modulo prime

2:   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: mapping.c,v 1.218 2010/07/11 19:12:01 mast Exp $ + || $Id$   */      #include "global.h"
93:    INT32 e; \    /* Move the last keypair to the new hole. */ \    *k = *(md->free_list); \ -  h_ = k->hval % md->hashsize; \ +  h_ = k->hval & ( md->hashsize - 1); \    prev_ = md->hash + h_; \    DO_IF_DEBUG( \    if (!*prev_) { \
181:   #endif    if(size)    { -  hashsize=find_good_hash_size(size / AVG_LINK_LENGTH + 1); +  hashsize=find_next_power(size / AVG_LINK_LENGTH + 1);       e=MAPPING_DATA_SIZE(hashsize, size);   
324:       /* link */    h=k->hval; -  h%=md->hashsize; +  h&=md->hashsize - 1;    k->next=md->hash[h];    md->hash[h]=k;   
379:       /* link */    h=k->hval; -  h%=md->hashsize; +  h&=md->hashsize - 1;    k->next=md->hash[h];    md->hash[h]=k;   
534:    add_ref(md); \    if(md->hashsize) \    { \ -  h=h2 % md->hashsize; \ +  h=h2 & (md->hashsize - 1); \    DO_IF_DEBUG( if(d_flag > 1) check_mapping_type_fields(m); ) \    if(md->ind_types & ((1 << key->type) | BIT_OBJECT)) \    { \
557:    add_ref(md); \    if(md->hashsize) \    { \ -  h=h2 % md->hashsize; \ +  h=h2 & (md->hashsize-1); \    DO_IF_DEBUG( if(d_flag > 1) check_mapping_type_fields(m); ) \    if(md->ind_types & ((1 << key->type) | BIT_OBJECT)) \    { \ -  k2=omd->hash[h2 % omd->hashsize]; \ +  k2=omd->hash[h2 & (omd->hashsize - 1)]; \    prev= md->hash + h; \    for(;(k=*prev) && k2;(prev=&k->next),(k2=k2->next)) \    if(!(h2 == k->hval && is_identical(&k2->ind, &k->ind))) \
622:   #define PROPAGATE() do { \    if(md->refs==1) \    { \ -  h=h2 % md->hashsize; \ +  h=h2 & (md->hashsize - 1); \    *prev=k->next; \    k->next=md->hash[h]; \    md->hash[h]=k; \
784:    rehash(m, md->size * 2 + 2);    md=m->data;    } -  h=h2 % md->hashsize; +  h=h2 & ( md->hashsize - 1);       /* no need to lock here since we are not calling is_eq - Hubbe */   
908:    rehash(m, md->size * 2 + 2);    md=m->data;    } -  h=h2 % md->hashsize; +  h=h2 & ( md->hashsize - 1);       k=md->free_list;   #ifndef PIKE_MAPPING_KEYPAIR_LOOP
1469:    res = allocate_mapping(a_md->size);    SET_ONERROR(err, do_free_mapping, res);    NEW_MAPPING_LOOP(a_md) { -  size_t h = k->hval % b_md->hashsize; +  size_t h = k->hval & ( b_md->hashsize - 1);    struct keypair *k2;    for (k2 = b_md->hash[h]; k2; k2 = k2->next) {    if ((k2->hval == k->hval) && is_eq(&k2->ind, &k->ind)) {
1514:       /* Remove elements in res that aren't in a. */    NEW_MAPPING_LOOP(b_md) { -  size_t h = k->hval % a_md->hashsize; +  size_t h = k->hval & ( a_md->hashsize - 1);    struct keypair *k2;    for (k2 = a_md->hash[h]; k2; k2 = k2->next) {    if ((k2->hval == k->hval) && is_eq(&k2->ind, &k->ind)) {
1557:       /* Add elements in a that aren't in b. */    NEW_MAPPING_LOOP(a_md) { -  size_t h = k->hval % b_md->hashsize; +  size_t h = k->hval & ( b_md->hashsize - 1);    struct keypair *k2;    for (k2 = b_md->hash[h]; k2; k2 = k2->next) {    if ((k2->hval == k->hval) && is_eq(&k2->ind, &k->ind)) {
1614:       /* Add elements in a that aren't in b, and remove those that are. */    NEW_MAPPING_LOOP(a_md) { -  size_t h = k->hval % b_md->hashsize; +  size_t h = k->hval & ( b_md->hashsize - 1);    struct keypair *k2;    for (k2 = b_md->hash[h]; k2; k2 = k2->next) {    if ((k2->hval == k->hval) && is_eq(&k2->ind, &k->ind)) {
2483:    if (remove) { \    /* Find and unlink k. */ \    unsigned INT32 h_; \ -  h_ = k->hval % md->hashsize; \ +  h_ = k->hval & ( md->hashsize - 1); \    prev_ = md->hash + h_; \    DO_IF_DEBUG( \    if (!*prev_) { \