micro optimizations.

removing a lot of mallocs through strdup  by replacing getcommand calls with get_command, which takes a buffer. only one left.
removing mkname calls with a static buffer for keyword-tokens.
commit the schema file I had lying around.
This commit is contained in:
Enno Rehling 2014-08-14 09:57:05 +02:00
parent 9ca206ec3f
commit dafe71f4b8
10 changed files with 3264 additions and 3166 deletions

6
schema.sql Normal file
View File

@ -0,0 +1,6 @@
CREATE TABLE email(id INTEGER PRIMARY KEY, md5 VARCHAR(32) UNIQUE NOT NULL, email VARCHAR(32), bounces INT DEFAULT 0, confirmed TIMESTAMP DEFAULT NULL);
CREATE TABLE faction (id INTEGER PRIMARY KEY, user_id INTEGER REFERENCES user(id), no INTEGER, name VARCHAR(64), game_id INTEGER REFERENCES game(id), race VARCHAR(10), lang CHAR(2));
CREATE TABLE faction_email (faction_id INTEGER REFERENCES faction(id), email_id INTEGER REFERENCES email(id));
CREATE TABLE game (id INTEGER PRIMARY KEY, name VARCHAR(20), last_turn INTEGER);
CREATE TABLE score (turn INTEGER, faction_id INTEGER REFERENCES faction(id), value INTEGER, UNIQUE(turn, faction_id));
CREATE TABLE user(id INTEGER PRIMARY KEY, email_id INTEGER REFERENCES email(id), creation TIMESTAMP DEFAULT CURRENT_TIMESTAMP);

File diff suppressed because it is too large Load Diff

View File

@ -28,74 +28,75 @@
#include <string.h> #include <string.h>
typedef struct command { typedef struct command {
parser fun; parser fun;
void *nodes; void *nodes;
} command; } command;
void *stree_find(const syntaxtree * stree, const struct locale *lang) void *stree_find(const syntaxtree * stree, const struct locale *lang)
{ {
while (stree) { while (stree) {
if (stree->lang == lang) if (stree->lang == lang)
return stree->root; return stree->root;
stree = stree->next; stree = stree->next;
} }
return NULL; return NULL;
} }
syntaxtree *stree_create(void) syntaxtree *stree_create(void)
{ {
syntaxtree *sroot = NULL; syntaxtree *sroot = NULL;
const struct locale *lang = locales; const struct locale *lang = locales;
while (lang) { while (lang) {
syntaxtree *stree = (syntaxtree *) malloc(sizeof(syntaxtree)); syntaxtree *stree = (syntaxtree *)malloc(sizeof(syntaxtree));
stree->lang = lang; stree->lang = lang;
stree->next = sroot; stree->next = sroot;
stree->root = 0; stree->root = 0;
sroot = stree; sroot = stree;
lang = nextlocale(lang); lang = nextlocale(lang);
} }
return sroot; return sroot;
} }
void void
add_command(void **keys, void *tnext, add_command(void **keys, void *tnext,
const char *str, parser fun) const char *str, parser fun)
{ {
command *cmd = (command *) malloc(sizeof(command)); command *cmd = (command *)malloc(sizeof(command));
variant var; variant var;
cmd->fun = fun; cmd->fun = fun;
cmd->nodes = tnext; cmd->nodes = tnext;
var.v = cmd; var.v = cmd;
addtoken(keys, str, var); addtoken(keys, str, var);
} }
static int do_command_i(const void *keys, struct unit *u, struct order *ord) static int do_command_i(const void *keys, struct unit *u, struct order *ord)
{ {
const char *c; const char *c;
variant var; variant var;
c = getstrtoken(); c = getstrtoken();
if (findtoken(keys, c, &var) == E_TOK_SUCCESS) { if (findtoken(keys, c, &var) == E_TOK_SUCCESS) {
command *cmd = (command *) var.v; command *cmd = (command *)var.v;
if (cmd->nodes && *c) { if (cmd->nodes && *c) {
assert(!cmd->fun); assert(!cmd->fun);
return do_command_i(cmd->nodes, u, ord); return do_command_i(cmd->nodes, u, ord);
} else if (cmd->fun) { }
cmd->fun(cmd->nodes, u, ord); else if (cmd->fun) {
return E_TOK_SUCCESS; cmd->fun(cmd->nodes, u, ord);
return E_TOK_SUCCESS;
}
} }
} return E_TOK_NOMATCH;
return E_TOK_NOMATCH;
} }
void do_command(const void *keys, struct unit *u, struct order *ord) void do_command(const void *keys, struct unit *u, struct order *ord)
{ {
init_tokens(ord); init_tokens(ord);
skip_token(); skip_token();
if (do_command_i(keys, u, ord) != E_TOK_SUCCESS) { if (do_command_i(keys, u, ord) != E_TOK_SUCCESS) {
char *cmd = getcommand(ord); char cmd[ORDERSIZE];
log_warning("%s failed command '%s'\n", unitname(u), cmd); get_command(ord, cmd, sizeof(cmd));
free(cmd); log_warning("%s failed command '%s'\n", unitname(u), cmd);
} }
} }

View File

@ -88,6 +88,7 @@ extern "C" {
#define ENCCHANCE 10 /* %-Chance für einmalige Zufallsbegegnung */ #define ENCCHANCE 10 /* %-Chance für einmalige Zufallsbegegnung */
#define DISPLAYSIZE 8192 /* max. Länge einer Beschreibung, incl trailing 0 */ #define DISPLAYSIZE 8192 /* max. Länge einer Beschreibung, incl trailing 0 */
#define ORDERSIZE (DISPLAYSIZE*2) /* max. length of an order */
#define NAMESIZE 128 /* max. Länge eines Namens, incl trailing 0 */ #define NAMESIZE 128 /* max. Länge eines Namens, incl trailing 0 */
#define IDSIZE 16 /* max. Länge einer no (als String), incl trailing 0 */ #define IDSIZE 16 /* max. Länge einer no (als String), incl trailing 0 */
#define KEYWORDSIZE 16 /* max. Länge eines Keyword, incl trailing 0 */ #define KEYWORDSIZE 16 /* max. Länge eines Keyword, incl trailing 0 */

View File

@ -93,7 +93,7 @@ keyword_t getkeyword(const order * ord)
* This is the inverse function to the parse_order command. Note that * This is the inverse function to the parse_order command. Note that
* keywords are expanded to their full length. * keywords are expanded to their full length.
*/ */
static char* get_command(const order *ord, char *sbuffer, size_t size) { char* get_command(const order *ord, char *sbuffer, size_t size) {
char *bufp = sbuffer; char *bufp = sbuffer;
const char *text = ORD_STRING(ord); const char *text = ORD_STRING(ord);
keyword_t kwd = ORD_KEYWORD(ord); keyword_t kwd = ORD_KEYWORD(ord);
@ -141,12 +141,6 @@ static char* get_command(const order *ord, char *sbuffer, size_t size) {
return sbuffer; return sbuffer;
} }
char *getcommand(const order * ord)
{
char sbuffer[DISPLAYSIZE * 2];
return _strdup(get_command(ord, sbuffer, sizeof(sbuffer)));
}
void free_order(order * ord) void free_order(order * ord)
{ {
if (ord != NULL) { if (ord != NULL) {
@ -423,6 +417,7 @@ bool is_repeated(const order * ord)
s = getstrtoken(); s = getstrtoken();
result = !isparam(s, lang, P_TEMP); result = !isparam(s, lang, P_TEMP);
parser_popstate(); parser_popstate();
// TODO: push/popstate is slow, we can do better.
break; break;
default: default:
result = 0; result = 0;
@ -589,6 +584,12 @@ void push_order(order ** ordp, order * ord)
*ordp = ord; *ordp = ord;
} }
static char *getcommand(const order * ord)
{
char cmd[ORDERSIZE];
return _strdup(get_command(ord, cmd, sizeof(cmd)));
}
void init_tokens(const struct order *ord) void init_tokens(const struct order *ord)
{ {
char *cmd = getcommand(ord); char *cmd = getcommand(ord);

View File

@ -50,13 +50,14 @@ extern "C" {
extern void push_order(struct order **olist, struct order *ord); extern void push_order(struct order **olist, struct order *ord);
/* access functions for orders */ /* access functions for orders */
extern keyword_t getkeyword(const order * ord); keyword_t getkeyword(const order * ord);
extern void set_order(order ** destp, order * src); void set_order(order ** destp, order * src);
extern char *getcommand(const order * ord); char *getcommand(const order * ord);
extern bool is_persistent(const order * ord); char* get_command(const order *ord, char *buffer, size_t size);
extern bool is_exclusive(const order * ord); bool is_persistent(const order * ord);
extern bool is_repeated(const order * ord); bool is_exclusive(const order * ord);
extern bool is_long(const order * ord); bool is_repeated(const order * ord);
bool is_long(const order * ord);
extern char *write_order(const order * ord, char *buffer, size_t size); extern char *write_order(const order * ord, char *buffer, size_t size);
extern void init_tokens(const struct order *ord); /* initialize token parsing */ extern void init_tokens(const struct order *ord); /* initialize token parsing */

File diff suppressed because it is too large Load Diff

View File

@ -10,10 +10,19 @@
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
static const char * keyword_key(int i) const char * keyword(keyword_t kwd)
{ {
assert(i<MAXKEYWORDS&& i>=0); static char result[KEYWORDSIZE];
return mkname("keyword", keywords[i]); if (!result[0]) {
strcpy(result, "keyword::");
}
strcpy(result+9, keywords[kwd]);
return result;
}
static const char * keyword_key(int kwd) {
assert(kwd < MAXKEYWORDS && kwd >= 0);
return keyword((keyword_t)kwd);
} }
void init_keyword(const struct locale *lang, keyword_t kwd, const char *str) { void init_keyword(const struct locale *lang, keyword_t kwd, const char *str) {
@ -28,8 +37,8 @@ void init_keywords(const struct locale *lang) {
keyword_t findkeyword(const char *s) { keyword_t findkeyword(const char *s) {
int i; int i;
for (i=0;i!=MAXKEYWORDS;++i) { for (i = 0; i != MAXKEYWORDS; ++i) {
if (strcmp(s, keywords[i])==0) { if (strcmp(s, keywords[i]) == 0) {
return (keyword_t)i; return (keyword_t)i;
} }
} }
@ -65,73 +74,73 @@ keyword_t get_keyword(const char *s, const struct locale *lang) {
static bool disabled_kwd[MAXKEYWORDS]; static bool disabled_kwd[MAXKEYWORDS];
void enable_keyword(keyword_t kwd, bool enabled) { void enable_keyword(keyword_t kwd, bool enabled) {
assert(kwd<MAXKEYWORDS); assert(kwd < MAXKEYWORDS);
disabled_kwd[kwd] = !enabled; disabled_kwd[kwd] = !enabled;
} }
bool keyword_disabled(keyword_t kwd) { bool keyword_disabled(keyword_t kwd) {
assert(kwd<MAXKEYWORDS); assert(kwd < MAXKEYWORDS);
return disabled_kwd[kwd]; return disabled_kwd[kwd];
} }
const char *keywords[MAXKEYWORDS] = { const char *keywords[MAXKEYWORDS] = {
"//", "//",
"banner", "banner",
"work", "work",
"attack", "attack",
"steal", "steal",
"besiege", "besiege",
"name", "name",
"use", "use",
"describe", "describe",
"enter", "enter",
"guard", "guard",
"message", "message",
"end", "end",
"ride", "ride",
"number", "number",
"follow", "follow",
"research", "research",
"give", "give",
"help", "help",
"fight", "fight",
"ready", "ready",
"buy", "buy",
"contact", "contact",
"teach", "teach",
"study", "study",
"make", "make",
"move", "move",
"password", "password",
"recruit", "recruit",
"reserve", "reserve",
"route", "route",
"sabotage", "sabotage",
"option", "option",
"spy", "spy",
"quit", "quit",
"hide", "hide",
"carry", "carry",
"tax", "tax",
"entertain", "entertain",
"sell", "sell",
"leave", "leave",
"forget", "forget",
"cast", "cast",
"show", "show",
"destroy", "destroy",
"grow", "grow",
"default", "default",
"origin", "origin",
"email", "email",
"piracy", "piracy",
"group", "group",
"sort", "sort",
"prefix", "prefix",
"plant", "plant",
"alliance", "alliance",
"claim", "claim",
"promote", "promote",
"pay", "pay",
}; };

View File

@ -80,7 +80,8 @@ void init_keywords(const struct locale *lang);
void init_keyword(const struct locale *lang, keyword_t kwd, const char *str); void init_keyword(const struct locale *lang, keyword_t kwd, const char *str);
bool keyword_disabled(keyword_t kwd); bool keyword_disabled(keyword_t kwd);
void enable_keyword(keyword_t kwd, bool enabled); void enable_keyword(keyword_t kwd, bool enabled);
#define keyword(kwd) mkname("keyword", keywords[kwd]) const char *keyword(keyword_t kwd);
// #define keyword(kwd) mkname("keyword", keywords[kwd])
#ifdef __cplusplus #ifdef __cplusplus
#endif #endif

View File

@ -53,7 +53,8 @@ void init_tokens_str(const char *initstr, char *cmd)
{ {
if (states == NULL) { if (states == NULL) {
states = malloc(sizeof(parser_state)); states = malloc(sizeof(parser_state));
} else if (states->current_cmd) { }
else if (states->current_cmd && states->current_cmd!=cmd) {
free(states->current_cmd); free(states->current_cmd);
} }
states->current_cmd = cmd; states->current_cmd = cmd;