From 2b5b9f446f14c47478954538ef99dc81ff3d538b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 15 Feb 2001 02:41:47 +0000 Subject: [PATCH] =?UTF-8?q?Extrem-Speedup=20f=C3=BCr=20den=20token-parser.?= =?UTF-8?q?=20Kleine=20=C3=84nderungen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/kernel/building.c | 5 +- src/common/kernel/curse.c | 5 +- src/common/kernel/eressea.c | 108 +++++++++++++++++++---------------- src/common/kernel/eressea.h | 2 +- src/common/kernel/item.c | 9 ++- src/common/kernel/magic.c | 9 ++- src/common/modules/gmcmd.c | 3 +- src/common/triggers/shock.c | 11 +--- src/common/util/umlaut.c | 82 ++++++++++++++++++-------- src/common/util/umlaut.h | 23 ++++---- 10 files changed, 146 insertions(+), 111 deletions(-) diff --git a/src/common/kernel/building.c b/src/common/kernel/building.c index a33cc6938..c56e1177a 100644 --- a/src/common/kernel/building.c +++ b/src/common/kernel/building.c @@ -1,6 +1,6 @@ /* vi: set ts=2: * - * $Id: building.c,v 1.6 2001/02/09 13:53:51 corwin Exp $ + * $Id: building.c,v 1.7 2001/02/15 02:41:46 enno Exp $ * Eressea PB(E)M host Copyright (C) 1998-2000 * Christian Schlittchen (corwin@amber.kn-bremen.de) * Katja Zedel (katze@felidae.kn-bremen.de) @@ -747,8 +747,7 @@ findbuildingtype(const char * name, const locale * lang) } bnames = bn; } - i = findtoken(&bn->names, name); - if (i==E_TOK_NOMATCH) return NULL; + if (findtoken(&bn->names, name, &i)==E_TOK_NOMATCH) return NULL; return (const building_type*)i; } diff --git a/src/common/kernel/curse.c b/src/common/kernel/curse.c index ee52a75b7..8e6b16745 100644 --- a/src/common/kernel/curse.c +++ b/src/common/kernel/curse.c @@ -1,6 +1,6 @@ /* vi: set ts=2: * - * $Id: curse.c,v 1.4 2001/02/03 13:45:32 enno Exp $ + * $Id: curse.c,v 1.5 2001/02/15 02:41:46 enno Exp $ * Eressea PB(E)M host Copyright (C) 1998-2000 * Christian Schlittchen (corwin@amber.kn-bremen.de) * Katja Zedel (katze@felidae.kn-bremen.de) @@ -166,7 +166,8 @@ ct_find(const char *c) /* TODO: findet nur curse_types, die auch in curse_data sind. * da fehlt noch ene registrierung wie für attrib_type */ - int i = (int)findtoken(&cursenames, c); + int i; + if (findtoken(&cursenames, c, (void**)&i)==E_TOK_NOMATCH) return NULL; if (i == -1 || cursedaten[i].name[0] == 0) { cursetype_list * ctl = cursetypes; while (ctl) { diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index da55b9df5..cdae73b57 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -1,6 +1,6 @@ /* vi: set ts=2: * - * $Id: eressea.c,v 1.14 2001/02/13 02:58:51 enno Exp $ + * $Id: eressea.c,v 1.15 2001/02/15 02:41:46 enno Exp $ * Eressea PB(E)M host Copyright (C) 1998-2000 * Christian Schlittchen (corwin@amber.kn-bremen.de) * Katja Zedel (katze@felidae.kn-bremen.de) @@ -1109,16 +1109,20 @@ struct tnode cursenames; skill_t findskill(const char *s) { - return (skill_t)findtoken(&tokens[UT_SKILL], s)-1; + int i; + if (findtoken(&tokens[UT_SKILL], s, (void**)&i)==E_TOK_NOMATCH) return NOSKILL; + return (skill_t)i; } keyword_t findkeyword(const char *s) { + int i; #ifdef AT_PERSISTENT if(*s == '@') s++; #endif - return (keyword_t) findtoken(&tokens[UT_KEYWORD], s)-1; + if (findtoken(&tokens[UT_KEYWORD], s, (void**)&i)==E_TOK_NOMATCH) return NOKEYWORD; + return (keyword_t) i; } keyword_t @@ -1136,13 +1140,15 @@ getkeyword (void) param_t findparam(const char *s) { - int p; const building_type * btype; - p = (int)findtoken(&tokens[UT_PARAM], s)-1; - if (p>=0) return (param_t)p; - btype = findbuildingtype(s, NULL); - if (btype!=NULL) return (param_t) P_BUILDING; - return NOPARAM; + + int i; + if (findtoken(&tokens[UT_PARAM], s, (void**)&i)==E_TOK_NOMATCH) { + btype = findbuildingtype(s, NULL); + if (btype!=NULL) return (param_t) P_BUILDING; + return NOPARAM; + } + return (param_t)i; } param_t @@ -1749,7 +1755,7 @@ use_birthdayamulet(region * r, unit * magician, strlist * cmdstrings) typedef struct t_umlaut { const char *txt; - unsigned char id; + int id; int typ; } t_umlaut; @@ -1801,17 +1807,17 @@ init_tokens(void) { int i; for (i=0;i!=MAXPARAMS;++i) - addtoken(&tokens[UT_PARAM], parameters[i], (void*)(i+1)); + addtoken(&tokens[UT_PARAM], parameters[i], (void*)i); for (i=0;i!=MAXSKILLS;++i) - addtoken(&tokens[UT_SKILL], skillnames[i], (void*)(i+1)); + addtoken(&tokens[UT_SKILL], skillnames[i], (void*)i); for (i=0;i!=MAXKEYWORDS;++i) - addtoken(&tokens[UT_KEYWORD], keywords[i], (void*)(i+1)); + addtoken(&tokens[UT_KEYWORD], keywords[i], (void*)i); for (i=0;umlaut[i].txt;++i) - addtoken(&tokens[umlaut[i].typ], umlaut[i].txt, (void*)(umlaut[i].id+1)); + addtoken(&tokens[umlaut[i].typ], umlaut[i].txt, (void*)umlaut[i].id); for (i=0; spelldaten[i].id != SPL_NOSPELL; i++) - addtoken(&spellnames, spelldaten[i].name, (void*)(i+1)); + addtoken(&spellnames, spelldaten[i].name, (void*)i); for (i=0; i!=MAXCURSE; i++){ - addtoken(&cursenames, cursedaten[i].name, (void*)(i+1)); + addtoken(&cursenames, cursedaten[i].name, (void*)i); } } @@ -2096,44 +2102,46 @@ resolve2(void) #endif +static void +init_directions(tnode * root) +{ + /* mit dieser routine kann man mehrere namen für eine direction geben, + * das ist für die hexes ideal. */ + const struct { + const char* name; + int direction; + } dirs [] = { + { "no", D_NORTHEAST}, + { "nw", D_NORTHWEST}, + { "nordosten", D_NORTHEAST}, + { "nordwesten", D_NORTHWEST}, + { "so", D_SOUTHEAST}, + { "sw", D_SOUTHWEST}, + { "südosten", D_SOUTHEAST}, + { "südwesten", D_SOUTHWEST}, + { "osten", D_EAST }, + { "westen",D_WEST }, + { NULL, NODIRECTION} + }; + int i; + for (i=0; dirs[i].direction!=NODIRECTION;++i) { + addtoken(root, dirs[i].name, (void*)dirs[i].direction); + } +} + direction_t finddirection(const char *s) { -#define MAXDIRNAMES 12 - static const char* dirs[MAXDIRNAMES] = { - "no", - "nw", - "nordosten", - "nordwesten", - "so", - "sw", - "suedosten", - "südosten", - "suedwesten", - "südwesten", - "osten", - "westen" - /* mit dieser routine kann man mehrere namen für eine direction geben, - * das ist für die hexes ideal. */ - }; - static const direction_t dir_xref[MAXDIRNAMES] = { - D_NORTHEAST, - D_NORTHWEST, - D_NORTHEAST, - D_NORTHWEST, - D_SOUTHEAST, - D_SOUTHWEST, - D_SOUTHEAST, - D_SOUTHEAST, - D_SOUTHWEST, - D_SOUTHWEST, - D_EAST, - D_WEST - }; - int uc = findstr(dirs, s, MAXDIRNAMES); + static boolean init = false; + static tnode dirnames; + int dir; - if (uc == -1) return NODIRECTION; - return dir_xref[uc]; + if (!init) init_directions(&dirnames); + + if (findtoken(&dirnames, s, (void**)&dir)==E_TOK_SUCCESS) { + return (direction_t)dir; + } + return NODIRECTION; } unit * diff --git a/src/common/kernel/eressea.h b/src/common/kernel/eressea.h index 5674ac62c..4502ee1a0 100644 --- a/src/common/kernel/eressea.h +++ b/src/common/kernel/eressea.h @@ -1105,7 +1105,7 @@ extern void guard(struct unit * u, unsigned int mask); typedef struct local_names { struct local_names * next; const struct locale * lang; - tnode names; + struct tnode names; } local_names; extern int maxworkingpeasants(const struct region * r); diff --git a/src/common/kernel/item.c b/src/common/kernel/item.c index 7b7acc3cd..aae485b11 100644 --- a/src/common/kernel/item.c +++ b/src/common/kernel/item.c @@ -1,6 +1,6 @@ /* vi: set ts=2: * - * $Id: item.c,v 1.11 2001/02/14 07:44:57 enno Exp $ + * $Id: item.c,v 1.12 2001/02/15 02:41:46 enno Exp $ * Eressea PB(E)M host Copyright (C) 1998-2000 * Christian Schlittchen (corwin@amber.kn-bremen.de) * Katja Zedel (katze@felidae.kn-bremen.de) @@ -2031,8 +2031,8 @@ findresourcetype(const char * name, const locale * lang) } rnames = rn; } - i = findtoken(&rn->names, name); - if (i==E_TOK_NOMATCH) return NULL; + + if (findtoken(&rn->names, name, &i)==E_TOK_NOMATCH) return NULL; return (const resource_type*)i; } @@ -2073,8 +2073,7 @@ finditemtype(const char * name, const locale * lang) } inames = in; } - i = findtoken(&in->names, name); - if (i==E_TOK_NOMATCH) return NULL; + if (findtoken(&in->names, name, &i)==E_TOK_NOMATCH) return NULL; return (const item_type*)i; } diff --git a/src/common/kernel/magic.c b/src/common/kernel/magic.c index 27a8bf299..105a61695 100644 --- a/src/common/kernel/magic.c +++ b/src/common/kernel/magic.c @@ -1,6 +1,6 @@ /* vi: set ts=2: * - * $Id: magic.c,v 1.7 2001/02/12 22:39:56 enno Exp $ + * $Id: magic.c,v 1.8 2001/02/15 02:41:46 enno Exp $ * Eressea PB(E)M host Copyright (C) 1998-2000 * Christian Schlittchen (corwin@amber.kn-bremen.de) * Katja Zedel (katze@felidae.kn-bremen.de) @@ -567,8 +567,8 @@ find_spellbyname(unit *u, char *s) spell *sp; int i; - m = get_mage(u); - if (!m) { + m = get_mage(u); + if (!m) { return (spell *) NULL; } @@ -579,8 +579,7 @@ find_spellbyname(unit *u, char *s) } } - i = (int)findtoken(&spellnames, s)-1; - if (i>=0 && getspell(u, spelldaten[i].id)) return &spelldaten[i]; + if (findtoken(&spellnames, s, (void**)&i) && getspell(u, spelldaten[i].id)) return &spelldaten[i]; return (spell *) NULL; } diff --git a/src/common/modules/gmcmd.c b/src/common/modules/gmcmd.c index de98a30b3..655373025 100644 --- a/src/common/modules/gmcmd.c +++ b/src/common/modules/gmcmd.c @@ -169,8 +169,7 @@ gm_command(const char * cmd, struct unit * u) i = min(16, c-cmd); strncpy(zText, cmd, i); zText[i]=0; - cm = (command*)findtoken(&g_keys, zText); - if (cm && cm->perform) cm->perform(++c, u); + if (findtoken(&g_keys, zText, (void**)&cm) && cm->perform) cm->perform(++c, u); } void diff --git a/src/common/triggers/shock.c b/src/common/triggers/shock.c index 2e9d739c2..4d881f430 100644 --- a/src/common/triggers/shock.c +++ b/src/common/triggers/shock.c @@ -1,6 +1,6 @@ /* vi: set ts=2: * - * $Id: shock.c,v 1.2 2001/01/26 16:19:41 enno Exp $ + * $Id: shock.c,v 1.3 2001/02/15 02:41:47 enno Exp $ * Eressea PB(E)M host Copyright (C) 1998-2000 * Christian Schlittchen (corwin@amber.kn-bremen.de) * Katja Zedel (katze@felidae.kn-bremen.de) @@ -49,18 +49,13 @@ static void shock_write(const trigger * t, FILE * F) { unit * u = (unit*)t->data.v; - fprintf(F, "%s ", itoa36(u->no)); + write_unit_reference(u, F); } static int shock_read(trigger * t, FILE * F) { - char zId[10]; - int i; - fscanf(F, "%s", zId); - i = atoi36(zId); - t->data.v = findunit(i); - if (t->data.v==NULL) ur_add((void*)i, &t->data.v, resolve_unit); + read_unit_reference((unit**)&t->data.v, F); return 1; } diff --git a/src/common/util/umlaut.c b/src/common/util/umlaut.c index 1cbc0d2dd..b7725b376 100644 --- a/src/common/util/umlaut.c +++ b/src/common/util/umlaut.c @@ -1,6 +1,6 @@ /* vi: set ts=2: * - * $Id: umlaut.c,v 1.4 2001/02/13 02:58:51 enno Exp $ + * $Id: umlaut.c,v 1.5 2001/02/15 02:41:47 enno Exp $ * Eressea PB(E)M host Copyright (C) 1998-2000 * Christian Schlittchen (corwin@amber.kn-bremen.de) * Katja Zedel (katze@felidae.kn-bremen.de) @@ -27,6 +27,15 @@ #include #include +typedef struct tref { + struct tref * nexthash; + char c; + struct tnode * node; +} tref; + +#define LEAF 1 /* leaf node for a word. always matches */ +#define SHARED 2 /* at least two words share the node */ + void addtoken(tnode * root, const char* str, void * id) { @@ -44,28 +53,43 @@ addtoken(tnode * root, const char* str, void * id) {'ß', "ss"}, { 0, 0 } }; - assert(id!=E_TOK_NOMATCH); - if (root->id!=E_TOK_NOMATCH && root->id!=id && !root->leaf) root->id=E_TOK_NOMATCH; if (!*str) { root->id = id; - root->leaf=1; + root->flags |= LEAF; } else { - tnode * tk; + tref * next; int index, i = 0; char c = *str; if (c<'a' || c>'z') c = (char)tolower((unsigned char)c); index = ((unsigned char)c) % 32; - tk = root->next[index]; - if (root->id==E_TOK_NOMATCH) root->id = id; - while (tk && tk->c != c) tk = tk->nexthash; - if (!tk) { - tk = calloc(1, sizeof(tnode)); - tk->id = E_TOK_NOMATCH; - tk->c = c; - tk->nexthash=root->next[index]; - root->next[index] = tk; + next = root->next[index]; + if (!root->flags) root->id = id; + while (next && next->c != c) next = next->nexthash; + if (!next) { + tref * ref; + char u = (char)toupper((unsigned char)c); + tnode * node = calloc(1, sizeof(tnode)); + + ref = malloc(sizeof(tref)); + ref->c = c; + ref->node = node; + ref->nexthash=root->next[index]; + root->next[index] = ref; + + if (u!=c) { + index = ((unsigned char)u) % 32; + ref = malloc(sizeof(tref)); + ref->c = u; + ref->node = node; + ref->nexthash = root->next[index]; + root->next[index] = ref; + } + next=ref; + } else { + next->node->flags |= SHARED; + if (next->node->flags & LEAF == 0) next->node->id = NULL; } - addtoken(tk, str+1, id); + addtoken(next->node, str+1, id); while (replace[i].str) { if (*str==replace[i].c) { strcat(strcpy(zText, replace[i].str), str+1); @@ -77,22 +101,32 @@ addtoken(tnode * root, const char* str, void * id) } } -void * -findtoken(tnode * tk, const char * str) +int +findtoken(tnode * tk, const char * str, void **result) { - if(*str == 0) return E_TOK_NOMATCH; + if (*str == 0) return E_TOK_NOMATCH; while (*str) { int index; + tref * ref; char c = *str; - if (c<'a' || c>'z') c = (char)tolower((unsigned char)c); + +/* if (c<'a' || c>'z') c = (char)tolower((unsigned char)c); */ index = ((unsigned char)c) % 32; - tk = tk->next[index]; - while (tk && tk->c!=c) tk = tk->nexthash; + ref = tk->next[index]; + while (ref && ref->c!=c) ref = ref->nexthash; ++str; - if (!tk) return E_TOK_NOMATCH; + if (!ref) return E_TOK_NOMATCH; + tk = ref->node; + if (tk && !(tk->flags & SHARED)) { + *result = tk->id; + return E_TOK_SUCCESS; + } } - return tk->id; + if (tk && (tk->flags & LEAF)) { + *result = tk->id; + return E_TOK_SUCCESS; + } + return E_TOK_NOMATCH; } - diff --git a/src/common/util/umlaut.h b/src/common/util/umlaut.h index 8f019dd8b..28973c828 100644 --- a/src/common/util/umlaut.h +++ b/src/common/util/umlaut.h @@ -1,6 +1,6 @@ /* vi: set ts=2: * - * $Id: umlaut.h,v 1.2 2001/01/26 16:19:41 enno Exp $ + * $Id: umlaut.h,v 1.3 2001/02/15 02:41:47 enno Exp $ * Eressea PB(E)M host Copyright (C) 1998-2000 * Christian Schlittchen (corwin@amber.kn-bremen.de) * Katja Zedel (katze@felidae.kn-bremen.de) @@ -14,18 +14,19 @@ #ifndef _UMLAUT_H #define _UMLAUT_H -typedef struct tnode tnode; -struct tnode { - struct tnode * nexthash; - struct tnode * next[32]; + +#define E_TOK_NOMATCH (-1) +#define E_TOK_SUCCESS 0 + +struct tref; + +typedef struct tnode { + struct tref * next[32]; + unsigned char flags; void * id; - char c; - unsigned char leaf; -}; +} tnode; -#define E_TOK_NOMATCH NULL - -void * findtoken(struct tnode * tk, const char * str); +int findtoken(struct tnode * tk, const char * str, void** result); void addtoken(struct tnode * root, const char* str, void * id); #endif