eddy_em: (Default)
[personal profile] eddy_em
Закинул код на гитхаб. Помимо старого hashtest добавил еще hashgen, который может генерировать по заданной таблице команд заголовочный файл и исходник, принимающий пользовательскую строку на вход, вычисляющий хеш команды (первое слово) и запускающий соответствующую функцию. Можно проверить это при помощи test.c.

Проверять на словаре с 43000 словами, конечно, можно, но код получается дюже длинный (за 41мс оно мне сгенерило исходник размером в 8МБ - 300тыс строк - и заголовочник на 2.5МБ). Поэтому для примера беру компактный словарик:
hello
world
what
put
change
set
         clear
reset
  get
out
in

и запускаю time ./hashgen -Fd testdic. Через 2мс получаю заголовочный файл:
int parsecmd(char *cmdwargs);

#define CMD_CHANGE      (3110904043)
#define CMD_CLEAR       (2063720716)
#define CMD_GET         (2963126085)
#define CMD_HELLO       (3433426201)
#define CMD_IN          (89558876)
#define CMD_OUT         (2963261277)
#define CMD_PUT         (2963277918)
#define CMD_RESET       (1907803304)
#define CMD_SET         (2963325777)
#define CMD_WHAT        (25570233)
#define CMD_WORLD       (3313868845)

и исходник:
#include <stdint.h>
#include <stddef.h>
#include "hash.h"

#ifndef _U_
#define _U_ __attribute__((__unused__))
#endif

#ifndef TRUE_INLINE
#define TRUE_INLINE  __attribute__((always_inline)) static inline
#endif

TRUE_INLINE int fn_change(_U_ uint32_t hash,  _U_ char *args){ // change (3110904043)
    return 1;
}

TRUE_INLINE int fn_clear(_U_ uint32_t hash,  _U_ char *args){ // clear (2063720716)
    return 1;
}

TRUE_INLINE int fn_get(_U_ uint32_t hash,  _U_ char *args){ // get (2963126085)
    return 1;
}

TRUE_INLINE int fn_hello(_U_ uint32_t hash,  _U_ char *args){ // hello (3433426201)
    return 1;
}

TRUE_INLINE int fn_in(_U_ uint32_t hash,  _U_ char *args){ // in (89558876)
    return 1;
}

TRUE_INLINE int fn_out(_U_ uint32_t hash,  _U_ char *args){ // out (2963261277)
    return 1;
}

TRUE_INLINE int fn_put(_U_ uint32_t hash,  _U_ char *args){ // put (2963277918)
    return 1;
}

TRUE_INLINE int fn_reset(_U_ uint32_t hash,  _U_ char *args){ // reset (1907803304)
    return 1;
}

TRUE_INLINE int fn_set(_U_ uint32_t hash,  _U_ char *args){ // set (2963325777)
    return 1;
}

TRUE_INLINE int fn_what(_U_ uint32_t hash,  _U_ char *args){ // what (25570233)
    return 1;
}

TRUE_INLINE int fn_world(_U_ uint32_t hash,  _U_ char *args){ // world (3313868845)
    return 1;
}

static uint32_t hashf(const char *str){
    uint32_t hash = 5381;
    uint32_t c;
    while((c = (uint32_t)*str++))
        hash = ((hash << 7) + hash) + c;
    return hash;
}

int parsecmd(char *cmdwargs){
    if(!cmdwargs || !*cmdwargs) return 0;
    char cmd[32];
    int i = 0;
    char *args = cmdwargs;
    while(*args && *args < 33) ++args;
    if(!args || !*args) return 0;
    while(*args > 33 && i < 31){
        cmd[i++] = *args++;
    }
    cmd[i] = 0;
    if(i == 31) args = NULL;
    if(args){
        while(*args && *args < 33) ++args;
        if(!*args) args = NULL;
    }
    uint32_t h = hashf(cmd);
    switch(h){
        case CMD_CHANGE:
            return fn_change(h, args);
        break;
        case CMD_CLEAR:
            return fn_clear(h, args);
        break;
        case CMD_GET:
            return fn_get(h, args);
        break;
        case CMD_HELLO:
            return fn_hello(h, args);
        break;
        case CMD_IN:
            return fn_in(h, args);
        break;
        case CMD_OUT:
            return fn_out(h, args);
        break;
        case CMD_PUT:
            return fn_put(h, args);
        break;
        case CMD_RESET:
            return fn_reset(h, args);
        break;
        case CMD_SET:
            return fn_set(h, args);
        break;
        case CMD_WHAT:
            return fn_what(h, args);
        break;
        case CMD_WORLD:
            return fn_world(h, args);
        break;
        default: return 0;
    }
    return 0;
}


Остается лишь заполнить содержимое пустых функций. Можно собрать тест и проверить:
gcc test.c hash.c -o test
./test "hell1o clear ass asdlf"
hell1o clear ass asdlf not found
./test "hello clear ass asdlf"
All OK

May 2025

S M T W T F S
    123
45678910
11121314151617
1819202122 2324
25262728293031

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated May. 25th, 2025 03:49 pm
Powered by Dreamwidth Studios