more intelligent values for hashtable sizes.

This commit is contained in:
Enno Rehling 2008-04-24 18:14:14 +00:00
parent 23505d2b84
commit a2abcfe177
9 changed files with 96 additions and 78 deletions

View File

@ -211,17 +211,17 @@ bhash(building * b)
void
bunhash(building * b)
{
building **show;
building **show;
for (show = &buildhash[b->no % BMAXHASH]; *show; show = &(*show)->nexthash) {
if ((*show)->no == b->no)
break;
}
if (*show) {
assert(*show == b);
*show = (*show)->nexthash;
b->nexthash = 0;
}
for (show = &buildhash[b->no % BMAXHASH]; *show; show = &(*show)->nexthash) {
if ((*show)->no == b->no)
break;
}
if (*show) {
assert(*show == b);
*show = (*show)->nexthash;
b->nexthash = 0;
}
}
static building *

View File

@ -41,10 +41,10 @@ extern "C" {
/* for some good prime numbers, check http://www.math.niu.edu/~rusin/known-math/98/pi_x */
#ifndef MAXREGIONS
# define MAXREGIONS 262139 /* must be prime for hashing. */
# define MAXREGIONS 524287 /* must be prime for hashing. 262139 was a little small */
#endif
#ifndef MAXUNITS
# define MAXUNITS 524287 /* must be prime for hashing. */
# define MAXUNITS 1048573 /* must be prime for hashing. 524287 was >90% full */
#endif
#define MONSTER_FACTION 0 /* Die Partei, in der die Monster sind. */

View File

@ -42,6 +42,7 @@
/* util includes */
#include <util/attrib.h>
#include <util/goodies.h>
#include <util/lists.h>
#include <util/log.h>
#include <util/resolve.h>
@ -379,8 +380,10 @@ attrib_type at_moveblock = {
};
#define RMAXHASH 65521 /* last prime <2^16 */
static region *regionhash[RMAXHASH];
#define coor_hashkey(x, y) (unsigned int)((x<<16) + y)
#define RMAXHASH MAXREGIONS
static region * regionhash[RMAXHASH];
static region * delmarker = (region*)regionhash; /* a funny hack */
static unsigned int uidhash[MAXREGIONS];
unsigned int
@ -402,29 +405,49 @@ generate_region_id(void)
return uid;
}
#define HASH_STATISTICS 1
#if HASH_STATISTICS
static int hash_requests;
static int hash_misses;
#endif
static region *
rfindhash(short x, short y)
{
region *old;
for (old = regionhash[coor_hashkey(x, y) % RMAXHASH]; old; old = old->nexthash)
if (old->x == x && old->y == y)
return old;
return 0;
unsigned int rid = coor_hashkey(x, y);
#if HASH_STATISTICS
++hash_requests;
#endif
if (rid>=0) {
int key = HASH1(rid, RMAXHASH), gk = HASH2(rid, RMAXHASH);
while (regionhash[key]!=NULL && (regionhash[key]==delmarker || regionhash[key]->x!=x || regionhash[key]->y!=y)) {
key = (key + gk) % RMAXHASH;
#if HASH_STATISTICS
++hash_misses;
#endif
}
return regionhash[key];
}
return NULL;
}
void
rhash(region * r)
{
int key = coor_hashkey(r->x, r->y) % RMAXHASH;
region *old = regionhash[key];
unsigned int rid = coor_hashkey(r->x, r->y);
int key = HASH1(rid, RMAXHASH), gk = HASH2(rid, RMAXHASH);
while (regionhash[key]!=NULL && regionhash[key]!=delmarker && regionhash[key]!=r) {
key = (key + gk) % RMAXHASH;
}
assert(regionhash[key]!=r || !"trying to add the same region twice");
regionhash[key] = r;
r->nexthash = old;
}
void
runhash(region * r)
{
region **show;
unsigned int rid = coor_hashkey(r->x, r->y);
int key = HASH1(rid, RMAXHASH), gk = HASH2(rid, RMAXHASH);
#ifdef FAST_CONNECT
int d, di;
@ -437,16 +460,11 @@ runhash(region * r)
}
}
#endif
for (show = &regionhash[coor_hashkey(r->x, r->y) % RMAXHASH]; *show; show = &(*show)->nexthash) {
if ((*show)->x == r->x && (*show)->y == r->y) {
break;
}
}
if (*show) {
assert(*show == r);
*show = (*show)->nexthash;
r->nexthash = 0;
while (regionhash[key]!=NULL && regionhash[key]!=r) {
key = (key + gk) % RMAXHASH;
}
assert(regionhash[key]==r || !"trying to remove a unit that is not hashed");
regionhash[key] = delmarker;
}
region *

View File

@ -109,7 +109,6 @@ typedef struct region {
struct message_list *msgs;
} * individual_messages;
struct attrib *attribs;
struct region *nexthash;
struct donation * donations;
const struct terrain_type * terrain;
struct rawmaterial * resources;
@ -142,7 +141,6 @@ typedef struct {
} moveblock;
#define reg_hashkey(r) (r->index)
#define coor_hashkey(x, y) (abs(x + 0x100 * y))
int distance(const struct region*, const struct region*);
int koor_distance(int ax, int ay, int bx, int by) ;

View File

@ -118,6 +118,8 @@ extern const char * report_kampfstatus(const struct unit * u, const struct local
extern size_t f_regionid(const struct region * r, const struct faction * f, char * buffer, size_t size);
#define GR_PLURAL 0x01 /* grammar: plural */
#ifdef __cplusplus
}
#endif

View File

@ -77,40 +77,6 @@ static int hash_requests;
static int hash_misses;
#endif
/* benchmark:
* jenkins_hash: 5.25 misses/hit
* wang_hash: 5.33 misses/hit
*/
INLINE_FUNCTION unsigned int jenkins_hash(unsigned int a)
{
a = (a+0x7ed55d16) + (a<<12);
a = (a^0xc761c23c) ^ (a>>19);
a = (a+0x165667b1) + (a<<5);
a = (a+0xd3a2646c) ^ (a<<9);
a = (a+0xfd7046c5) + (a<<3);
a = (a^0xb55a4f09) ^ (a>>16);
return a;
}
INLINE_FUNCTION unsigned int wang_hash(unsigned int a)
{
a = ~a + (a << 15); // a = (a << 15) - a - 1;
a = a ^ (a >> 12);
a = a + (a << 2);
a = a ^ (a >> 4);
a = a * 2057; // a = (a + (a << 3)) + (a << 11);
a = a ^ (a >> 16);
return a;
}
#define HASH1(a, m) (jenkins_hash(a) % m)
#define HASH2(a, m) 1
/*
#define HASH1(a, m) ((a) % m)
#define HASH2(a, m) (m - 2 - a % (m-2))
*/
void
uhash(unit * u)
{

View File

@ -18,6 +18,10 @@
extern "C" {
#endif
extern boolean locale_check(void);
extern char * set_string(char **s, const char *neu);
extern int set_email(char** pemail, const char *newmail);
extern int *intlist_init(void);
extern int *intlist_add(int *i_p, int i);
extern int *intlist_find(int *i_p, int i);
@ -27,19 +31,27 @@ extern int *intlist_find(int *i_p, int i);
#else
extern unsigned int hashstring(const char* s);
extern const char *escape_string(const char * str, char * buffer, unsigned int len);
extern unsigned int jenkins_hash(unsigned int a);
extern unsigned int wang_hash(unsigned int a);
#endif
extern boolean locale_check(void);
extern char * set_string(char **s, const char *neu);
/* benchmark for units:
* JENKINS_HASH: 5.25 misses/hit (with good cache behavior)
* WANG_HASH: 5.33 misses/hit (with good cache behavior)
* KNUTH_HASH: 1.93 misses/hit (with bad cache behavior)
* CF_HASH: fucking awful!
*/
#define KNUTH_HASH1(a, m) ((a) % m)
#define KNUTH_HASH2(a, m) (m - 2 - a % (m-2))
#define CF_HASH1(a, m) ((a) % m)
#define CF_HASH2(a, m) (8 - ((a) & 7))
#define JENKINS_HASH1(a, m) (jenkins_hash(a) % m)
#define JENKINS_HASH2(a, m) 1
#define WANG_HASH1(a, m) (wang_hash(a) % m)
#define WANG_HASH2(a, m) 1
extern int set_email(char** pemail, const char *newmail);
/* fast strncat */
/* grammar constants: */
#define GR_PLURAL 0x01
/* 0x02-0x08 left unused for individual use */
#define GR_ARTICLE 0x10
#define GR_INDEFINITE_ARTICLE 0x20
#define HASH1 JENKINS_HASH1
#define HASH2 JENKINS_HASH2
#ifdef __cplusplus
}

View File

@ -56,3 +56,24 @@ escape_string(const char * str, char * buffer, unsigned int len)
return buffer;
}
INLINE_FUNCTION unsigned int jenkins_hash(unsigned int a)
{
a = (a+0x7ed55d16) + (a<<12);
a = (a^0xc761c23c) ^ (a>>19);
a = (a+0x165667b1) + (a<<5);
a = (a+0xd3a2646c) ^ (a<<9);
a = (a+0xfd7046c5) + (a<<3);
a = (a^0xb55a4f09) ^ (a>>16);
return a;
}
INLINE_FUNCTION unsigned int wang_hash(unsigned int a)
{
a = ~a + (a << 15); // a = (a << 15) - a - 1;
a = a ^ (a >> 12);
a = a + (a << 2);
a = a ^ (a >> 4);
a = a * 2057; // a = (a + (a << 3)) + (a << 11);
a = a ^ (a >> 16);
return a;
}

View File

@ -7605,6 +7605,7 @@
<arg name="amount" type="int"/>
</type>
<text locale="de">"$unit($mage) zaubert $spell($spell). $int($amount) Krieger verloren kurzzeitig ihr Gedächtnis."</text>
<text locale="en">"$unit($mage) casts $spell($spell). $int($amount) fighters are temporarily losing some of their memories."</text>
</message>
<message name="sp_shadowcall_effect" section="magic">