forked from github/server
alternative implementation for dfindhash that doesn't use as much memory.
do not set u->faction = NULL for deleted units.
This commit is contained in:
parent
3e2c630c3f
commit
f946d50001
6 changed files with 68 additions and 61 deletions
|
@ -336,40 +336,6 @@ void write_faction_reference(const faction * f, struct storage *store)
|
||||||
WRITE_INT(store, f ? f->no : 0);
|
WRITE_INT(store, f ? f->no : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DMAXHASH 7919
|
|
||||||
typedef struct dead {
|
|
||||||
struct dead *nexthash;
|
|
||||||
faction *f;
|
|
||||||
int no;
|
|
||||||
} dead;
|
|
||||||
|
|
||||||
static dead *deadhash[DMAXHASH];
|
|
||||||
|
|
||||||
void dhash(int no, faction * f)
|
|
||||||
{
|
|
||||||
dead *hash = (dead *)calloc(1, sizeof(dead));
|
|
||||||
dead *old = deadhash[no % DMAXHASH];
|
|
||||||
hash->no = no;
|
|
||||||
hash->f = f;
|
|
||||||
deadhash[no % DMAXHASH] = hash;
|
|
||||||
hash->nexthash = old;
|
|
||||||
}
|
|
||||||
|
|
||||||
faction *dfindhash(int no)
|
|
||||||
{
|
|
||||||
dead *old;
|
|
||||||
|
|
||||||
if (no < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (old = deadhash[no % DMAXHASH]; old; old = old->nexthash) {
|
|
||||||
if (old->no == no) {
|
|
||||||
return old->f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_flist(faction **fp) {
|
void free_flist(faction **fp) {
|
||||||
faction * flist = *fp;
|
faction * flist = *fp;
|
||||||
while (flist) {
|
while (flist) {
|
||||||
|
@ -868,6 +834,7 @@ int writepasswd(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_factions(void) {
|
void free_factions(void) {
|
||||||
|
#ifdef DMAXHASH
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i != DMAXHASH; ++i) {
|
for (i = 0; i != DMAXHASH; ++i) {
|
||||||
while (deadhash[i]) {
|
while (deadhash[i]) {
|
||||||
|
@ -876,6 +843,7 @@ void free_factions(void) {
|
||||||
free(d);
|
free(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
free_flist(&factions);
|
free_flist(&factions);
|
||||||
free_flist(&dead_factions);
|
free_flist(&dead_factions);
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,10 +180,6 @@ extern "C" {
|
||||||
|
|
||||||
struct faction *getfaction(void);
|
struct faction *getfaction(void);
|
||||||
|
|
||||||
/* looking up dead factions: */
|
|
||||||
void dhash(int no, struct faction * f);
|
|
||||||
struct faction *dfindhash(int no);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -191,29 +191,10 @@ static void test_set_origin_bug(CuTest *tc) {
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_deadhash(CuTest *tc) {
|
|
||||||
faction *f;
|
|
||||||
int no;
|
|
||||||
test_setup();
|
|
||||||
f = test_create_faction(0);
|
|
||||||
no = f->no;
|
|
||||||
CuAssertPtrEquals(tc, f, findfaction(no));
|
|
||||||
CuAssertPtrEquals(tc, NULL, dfindhash(42));
|
|
||||||
dhash(41, f);
|
|
||||||
dhash(42, f);
|
|
||||||
assert(f == factions);
|
|
||||||
destroyfaction(&factions);
|
|
||||||
CuAssertPtrEquals(tc, 0, findfaction(no));
|
|
||||||
CuAssertPtrEquals(tc, f, dfindhash(42));
|
|
||||||
CuAssertPtrEquals(tc, f, dfindhash(41));
|
|
||||||
test_cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
CuSuite *get_faction_suite(void)
|
CuSuite *get_faction_suite(void)
|
||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
CuSuite *suite = CuSuiteNew();
|
||||||
SUITE_ADD_TEST(suite, test_addfaction);
|
SUITE_ADD_TEST(suite, test_addfaction);
|
||||||
SUITE_ADD_TEST(suite, test_deadhash);
|
|
||||||
SUITE_ADD_TEST(suite, test_remove_empty_factions);
|
SUITE_ADD_TEST(suite, test_remove_empty_factions);
|
||||||
SUITE_ADD_TEST(suite, test_destroyfaction_allies);
|
SUITE_ADD_TEST(suite, test_destroyfaction_allies);
|
||||||
SUITE_ADD_TEST(suite, test_remove_empty_factions_alliance);
|
SUITE_ADD_TEST(suite, test_remove_empty_factions_alliance);
|
||||||
|
|
|
@ -366,6 +366,51 @@ int gift_items(unit * u, int flags)
|
||||||
|
|
||||||
static unit *deleted_units = NULL;
|
static unit *deleted_units = NULL;
|
||||||
|
|
||||||
|
#define DMAXHASH 7919
|
||||||
|
#undef DMAXHASH // TODO: makes dfindhash slow!
|
||||||
|
#ifdef DMAXHASH
|
||||||
|
typedef struct dead {
|
||||||
|
struct dead *nexthash;
|
||||||
|
faction *f;
|
||||||
|
int no;
|
||||||
|
} dead;
|
||||||
|
|
||||||
|
static dead *deadhash[DMAXHASH];
|
||||||
|
|
||||||
|
static void dhash(int no, faction * f)
|
||||||
|
{
|
||||||
|
dead *hash = (dead *)calloc(1, sizeof(dead));
|
||||||
|
dead *old = deadhash[no % DMAXHASH];
|
||||||
|
hash->no = no;
|
||||||
|
hash->f = f;
|
||||||
|
deadhash[no % DMAXHASH] = hash;
|
||||||
|
hash->nexthash = old;
|
||||||
|
}
|
||||||
|
|
||||||
|
faction *dfindhash(int no)
|
||||||
|
{
|
||||||
|
dead *old;
|
||||||
|
|
||||||
|
if (no < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (old = deadhash[no % DMAXHASH]; old; old = old->nexthash) {
|
||||||
|
if (old->no == no) {
|
||||||
|
return old->f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
struct faction *dfindhash(int no) {
|
||||||
|
unit *u = deleted_units;
|
||||||
|
while (u && u->no != no) {
|
||||||
|
u = u->next;
|
||||||
|
}
|
||||||
|
return u ? u->faction : NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int remove_unit(unit ** ulist, unit * u)
|
int remove_unit(unit ** ulist, unit * u)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
@ -379,8 +424,9 @@ int remove_unit(unit ** ulist, unit * u)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (u->number)
|
if (u->number) {
|
||||||
set_number(u, 0);
|
set_number(u, 0);
|
||||||
|
}
|
||||||
leave(u, true);
|
leave(u, true);
|
||||||
u->region = NULL;
|
u->region = NULL;
|
||||||
|
|
||||||
|
@ -393,11 +439,22 @@ int remove_unit(unit ** ulist, unit * u)
|
||||||
*ulist = u->next;
|
*ulist = u->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (u->prevF) {
|
||||||
|
u->prevF->nextF = u->nextF;
|
||||||
|
}
|
||||||
|
if (u->nextF) {
|
||||||
|
u->nextF->prevF = u->prevF;
|
||||||
|
}
|
||||||
|
u->nextF = 0;
|
||||||
|
u->prevF = 0;
|
||||||
|
|
||||||
u->next = deleted_units;
|
u->next = deleted_units;
|
||||||
deleted_units = u;
|
deleted_units = u;
|
||||||
|
#ifdef DMAXHASH
|
||||||
dhash(u->no, u->faction);
|
dhash(u->no, u->faction);
|
||||||
|
#endif
|
||||||
|
// u_setfaction(u, NULL);
|
||||||
|
|
||||||
u_setfaction(u, NULL);
|
|
||||||
u->region = NULL;
|
u->region = NULL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -174,6 +174,9 @@ extern "C" {
|
||||||
const struct region *r, bool noitem);
|
const struct region *r, bool noitem);
|
||||||
int remove_unit(struct unit **ulist, struct unit *u);
|
int remove_unit(struct unit **ulist, struct unit *u);
|
||||||
|
|
||||||
|
/* looking up dead units' factions: */
|
||||||
|
struct faction *dfindhash(int no);
|
||||||
|
|
||||||
#define GIFT_SELF 1<<0
|
#define GIFT_SELF 1<<0
|
||||||
#define GIFT_FRIENDS 1<<1
|
#define GIFT_FRIENDS 1<<1
|
||||||
#define GIFT_PEASANTS 1<<2
|
#define GIFT_PEASANTS 1<<2
|
||||||
|
|
|
@ -50,14 +50,16 @@ static void test_remove_empty_units_in_region(CuTest *tc) {
|
||||||
test_create_world();
|
test_create_world();
|
||||||
|
|
||||||
u = test_create_unit(test_create_faction(test_create_race("human")), findregion(0, 0));
|
u = test_create_unit(test_create_faction(test_create_race("human")), findregion(0, 0));
|
||||||
|
u = test_create_unit(u->faction, u->region);
|
||||||
|
CuAssertPtrNotNull(tc, u->nextF);
|
||||||
uid = u->no;
|
uid = u->no;
|
||||||
remove_empty_units_in_region(u->region);
|
remove_empty_units_in_region(u->region);
|
||||||
CuAssertPtrNotNull(tc, findunit(uid));
|
CuAssertPtrNotNull(tc, findunit(uid));
|
||||||
u->number = 0;
|
u->number = 0;
|
||||||
remove_empty_units_in_region(u->region);
|
remove_empty_units_in_region(u->region);
|
||||||
CuAssertPtrEquals(tc, 0, findunit(uid));
|
CuAssertPtrEquals(tc, 0, findunit(uid));
|
||||||
|
CuAssertPtrEquals(tc, 0, u->nextF);
|
||||||
CuAssertPtrEquals(tc, 0, u->region);
|
CuAssertPtrEquals(tc, 0, u->region);
|
||||||
CuAssertPtrEquals(tc, 0, u->faction);
|
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,7 +424,7 @@ static void test_remove_unit(CuTest *tc) {
|
||||||
CuAssertIntEquals(tc, 0, u->number);
|
CuAssertIntEquals(tc, 0, u->number);
|
||||||
CuAssertPtrEquals(tc, 0, u->region);
|
CuAssertPtrEquals(tc, 0, u->region);
|
||||||
CuAssertPtrEquals(tc, 0, u->items);
|
CuAssertPtrEquals(tc, 0, u->items);
|
||||||
CuAssertPtrEquals(tc, 0, u->faction);
|
CuAssertPtrEquals(tc, 0, u->nextF);
|
||||||
CuAssertPtrEquals(tc, 0, r->units);
|
CuAssertPtrEquals(tc, 0, r->units);
|
||||||
CuAssertPtrEquals(tc, 0, findunit(uno));
|
CuAssertPtrEquals(tc, 0, findunit(uno));
|
||||||
CuAssertPtrEquals(tc, f, dfindhash(uno));
|
CuAssertPtrEquals(tc, f, dfindhash(uno));
|
||||||
|
|
Loading…
Reference in a new issue