forked from github/server
more intelligent values for hashtable sizes.
This commit is contained in:
parent
23505d2b84
commit
a2abcfe177
9 changed files with 96 additions and 78 deletions
|
@ -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 *
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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 = ®ionhash[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 *
|
||||
|
|
|
@ -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) ;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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">
|
||||
|
|
Loading…
Reference in a new issue