mirror of
https://github.com/libretro/RetroArch
synced 2025-02-28 12:40:23 +00:00
(libretro-db) c_converter: use a hash based lookup in get_match_key.
This commit is contained in:
parent
d53a0c5994
commit
a0d2272e88
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
#include "libretrodb.h"
|
#include "libretrodb.h"
|
||||||
|
|
||||||
void dat_converter_exit(int rc)
|
static void dat_converter_exit(int rc)
|
||||||
{
|
{
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
exit(rc);
|
exit(rc);
|
||||||
@ -84,13 +84,13 @@ struct dat_converter_bt_node_t
|
|||||||
dat_converter_bt_node_t* left;
|
dat_converter_bt_node_t* left;
|
||||||
};
|
};
|
||||||
|
|
||||||
int dat_converter_cmp_func(const void *a, const void *b, void *ctx)
|
static int dat_converter_cmp_func(const void* a, const void* b, void* ctx)
|
||||||
{
|
{
|
||||||
return strcmp(a, b);
|
return strcmp(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
dat_converter_list_t* dat_converter_list_create(dat_converter_list_enum type)
|
static dat_converter_list_t* dat_converter_list_create(dat_converter_list_enum type)
|
||||||
{
|
{
|
||||||
dat_converter_list_t* list = malloc(sizeof(*list));
|
dat_converter_list_t* list = malloc(sizeof(*list));
|
||||||
list->type = type;
|
list->type = type;
|
||||||
@ -101,16 +101,16 @@ dat_converter_list_t* dat_converter_list_create(dat_converter_list_enum type)
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dat_converter_bt_node_free(dat_converter_bt_node_t* node)
|
static void dat_converter_bt_node_free(dat_converter_bt_node_t* node)
|
||||||
{
|
{
|
||||||
if(!node)
|
if (!node)
|
||||||
return;
|
return;
|
||||||
dat_converter_bt_node_free(node->left);
|
dat_converter_bt_node_free(node->left);
|
||||||
dat_converter_bt_node_free(node->right);
|
dat_converter_bt_node_free(node->right);
|
||||||
free(node);
|
free(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dat_converter_list_free(dat_converter_list_t* list)
|
static void dat_converter_list_free(dat_converter_list_t* list)
|
||||||
{
|
{
|
||||||
if (!list)
|
if (!list)
|
||||||
return;
|
return;
|
||||||
@ -136,12 +136,13 @@ void dat_converter_list_free(dat_converter_list_t* list)
|
|||||||
free(list);
|
free(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
dat_converter_bt_node_t* dat_converter_bt_node_insert(dat_converter_list_t* list, dat_converter_bt_node_t** node, dat_converter_map_t* map)
|
static dat_converter_bt_node_t* dat_converter_bt_node_insert(dat_converter_list_t* list, dat_converter_bt_node_t** node,
|
||||||
|
dat_converter_map_t* map)
|
||||||
{
|
{
|
||||||
assert(map->key);
|
assert(map->key);
|
||||||
assert(list->type == DAT_CONVERTER_MAP_LIST);
|
assert(list->type == DAT_CONVERTER_MAP_LIST);
|
||||||
|
|
||||||
if(!*node)
|
if (!*node)
|
||||||
{
|
{
|
||||||
*node = calloc(1, sizeof(dat_converter_bt_node_t));
|
*node = calloc(1, sizeof(dat_converter_bt_node_t));
|
||||||
return *node;
|
return *node;
|
||||||
@ -149,17 +150,17 @@ dat_converter_bt_node_t* dat_converter_bt_node_insert(dat_converter_list_t* list
|
|||||||
|
|
||||||
int diff = (*node)->hash - map->hash;
|
int diff = (*node)->hash - map->hash;
|
||||||
|
|
||||||
if(!diff)
|
if (!diff)
|
||||||
diff = strcmp(list->values[(*node)->index].map.key, map->key);
|
diff = strcmp(list->values[(*node)->index].map.key, map->key);
|
||||||
|
|
||||||
if(diff < 0)
|
if (diff < 0)
|
||||||
return dat_converter_bt_node_insert(list, &(*node)->left, map);
|
return dat_converter_bt_node_insert(list, &(*node)->left, map);
|
||||||
else if(diff > 0)
|
else if (diff > 0)
|
||||||
return dat_converter_bt_node_insert(list, &(*node)->right, map);
|
return dat_converter_bt_node_insert(list, &(*node)->right, map);
|
||||||
|
|
||||||
/* found match */
|
/* found match */
|
||||||
|
|
||||||
if(list->values[(*node)->index].map.type == DAT_CONVERTER_LIST_MAP)
|
if (list->values[(*node)->index].map.type == DAT_CONVERTER_LIST_MAP)
|
||||||
dat_converter_list_free(list->values[(*node)->index].map.value.list);
|
dat_converter_list_free(list->values[(*node)->index].map.value.list);
|
||||||
|
|
||||||
list->values[(*node)->index].map = *map;
|
list->values[(*node)->index].map = *map;
|
||||||
@ -168,7 +169,7 @@ dat_converter_bt_node_t* dat_converter_bt_node_insert(dat_converter_list_t* list
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void dat_converter_list_append(dat_converter_list_t* dst, void* item)
|
static void dat_converter_list_append(dat_converter_list_t* dst, void* item)
|
||||||
{
|
{
|
||||||
if (dst->count == dst->capacity)
|
if (dst->count == dst->capacity)
|
||||||
{
|
{
|
||||||
@ -192,13 +193,13 @@ void dat_converter_list_append(dat_converter_list_t* dst, void* item)
|
|||||||
case DAT_CONVERTER_MAP_LIST:
|
case DAT_CONVERTER_MAP_LIST:
|
||||||
{
|
{
|
||||||
dat_converter_map_t* map = (dat_converter_map_t*) item;
|
dat_converter_map_t* map = (dat_converter_map_t*) item;
|
||||||
if(!map->key)
|
if (!map->key)
|
||||||
dst->values[dst->count].map = *map;
|
dst->values[dst->count].map = *map;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
map->hash = djb2_calculate(map->key);
|
map->hash = djb2_calculate(map->key);
|
||||||
dat_converter_bt_node_t* new_node = dat_converter_bt_node_insert(dst, &dst->bt_root, map);
|
dat_converter_bt_node_t* new_node = dat_converter_bt_node_insert(dst, &dst->bt_root, map);
|
||||||
if(new_node)
|
if (new_node)
|
||||||
{
|
{
|
||||||
dst->values[dst->count].map = *map;
|
dst->values[dst->count].map = *map;
|
||||||
new_node->index = dst->count;
|
new_node->index = dst->count;
|
||||||
@ -221,7 +222,7 @@ void dat_converter_list_append(dat_converter_list_t* dst, void* item)
|
|||||||
dst->count++;
|
dst->count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
dat_converter_list_t* dat_converter_lexer(char* src, const char* dat_path)
|
static dat_converter_list_t* dat_converter_lexer(char* src, const char* dat_path)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
@ -286,7 +287,7 @@ dat_converter_list_t* dat_converter_lexer(char* src, const char* dat_path)
|
|||||||
return token_list;
|
return token_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
dat_converter_list_t* dat_parser_table(dat_converter_list_item_t** start_token)
|
static dat_converter_list_t* dat_parser_table(dat_converter_list_item_t** start_token)
|
||||||
{
|
{
|
||||||
dat_converter_list_t* parsed_table = dat_converter_list_create(DAT_CONVERTER_MAP_LIST);
|
dat_converter_list_t* parsed_table = dat_converter_list_create(DAT_CONVERTER_MAP_LIST);
|
||||||
dat_converter_map_t map = {0};
|
dat_converter_map_t map = {0};
|
||||||
@ -356,52 +357,43 @@ dat_converter_list_t* dat_parser_table(dat_converter_list_item_t** start_token)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* dat_converter_get_match_key(dat_converter_list_t* list, const char* match_key)
|
typedef struct dat_converter_match_key_t dat_converter_match_key_t;
|
||||||
|
struct dat_converter_match_key_t
|
||||||
|
{
|
||||||
|
char* value;
|
||||||
|
uint32_t hash;
|
||||||
|
dat_converter_match_key_t* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char* dat_converter_get_match_key(dat_converter_list_t* list, dat_converter_match_key_t* match_key)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const char* res;
|
|
||||||
char* key;
|
assert(match_key);
|
||||||
char* dot;
|
|
||||||
|
|
||||||
if (list->type != DAT_CONVERTER_MAP_LIST)
|
if (list->type != DAT_CONVERTER_MAP_LIST)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
key = strdup(match_key);
|
for (i = 0; i < list->count; i++)
|
||||||
dot = strchr(key, '.');
|
|
||||||
|
|
||||||
if (dot)
|
|
||||||
{
|
{
|
||||||
*dot = '\0';
|
if(list->values[i].map.hash == match_key->hash)
|
||||||
for (i = 0; i < list->count; i++)
|
{
|
||||||
if (!strcmp(list->values[i].map.key, key))
|
assert(!strcmp(list->values[i].map.key, match_key->value));
|
||||||
{
|
|
||||||
if (list->values[i].map.type == DAT_CONVERTER_LIST_MAP)
|
|
||||||
{
|
|
||||||
res = dat_converter_get_match_key(list->values[i].map.value.list, dot + 1);
|
|
||||||
free(key);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (i = 0; i < list->count; i++)
|
|
||||||
if (!strcmp(list->values[i].map.key, key))
|
|
||||||
{
|
|
||||||
if ((list->values[i].map.type == DAT_CONVERTER_STRING_MAP))
|
|
||||||
{
|
|
||||||
free(key);
|
|
||||||
return list->values[i].map.value.string;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if(match_key->next)
|
||||||
|
return dat_converter_get_match_key(list->values[i].map.value.list, match_key->next);
|
||||||
|
else if ((list->values[i].map.type == DAT_CONVERTER_STRING_MAP))
|
||||||
|
return list->values[i].map.value.string;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dat_converter_list_t* dat_converter_parser(dat_converter_list_t* target, dat_converter_list_t* lexer_list, const char* match_key)
|
static dat_converter_list_t* dat_converter_parser(dat_converter_list_t* target, dat_converter_list_t* lexer_list,
|
||||||
|
dat_converter_match_key_t* match_key)
|
||||||
{
|
{
|
||||||
bool skip = true;
|
bool skip = true;
|
||||||
dat_converter_list_item_t* current = lexer_list->values;
|
dat_converter_list_item_t* current = lexer_list->values;
|
||||||
@ -436,13 +428,19 @@ dat_converter_list_t* dat_converter_parser(dat_converter_list_t* target, dat_con
|
|||||||
current++;
|
current++;
|
||||||
map.value.list = dat_parser_table(¤t);
|
map.value.list = dat_parser_table(¤t);
|
||||||
if (!skip)
|
if (!skip)
|
||||||
{
|
{
|
||||||
if (match_key)
|
if (match_key)
|
||||||
{
|
{
|
||||||
map.key = dat_converter_get_match_key(map.value.list, match_key);
|
map.key = dat_converter_get_match_key(map.value.list, match_key);
|
||||||
if(!map.key)
|
if (!map.key)
|
||||||
{
|
{
|
||||||
printf("missing match key '%s' in one of the entries\n", match_key);
|
printf("missing match key '");
|
||||||
|
while(match_key->next)
|
||||||
|
{
|
||||||
|
printf("%s.", match_key->value);
|
||||||
|
match_key = match_key->next;
|
||||||
|
}
|
||||||
|
printf("%s' in one of the entries\n", match_key->value);
|
||||||
dat_converter_exit(1);
|
dat_converter_exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -675,7 +673,7 @@ static int value_provider(dat_converter_list_item_t** current_item, struct rmsgp
|
|||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
const char* rdb_path;
|
const char* rdb_path;
|
||||||
const char* match_key = NULL;
|
dat_converter_match_key_t* match_key = NULL;
|
||||||
RFILE* rdb_file;
|
RFILE* rdb_file;
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
@ -690,9 +688,31 @@ int main(int argc, char** argv)
|
|||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
|
|
||||||
if (argc > 1)
|
if (argc > 1 && **argv)
|
||||||
{
|
{
|
||||||
match_key = *argv;
|
dat_converter_match_key_t* current_mk;
|
||||||
|
char* dot;
|
||||||
|
|
||||||
|
match_key = malloc(sizeof(*match_key));
|
||||||
|
match_key->value = strdup(*argv);
|
||||||
|
match_key->next = NULL;
|
||||||
|
current_mk = match_key;
|
||||||
|
|
||||||
|
dot = match_key->value;
|
||||||
|
while (*dot++)
|
||||||
|
{
|
||||||
|
if (*dot == '.')
|
||||||
|
{
|
||||||
|
*dot++ = '\0';
|
||||||
|
current_mk->hash = djb2_calculate(current_mk->value);
|
||||||
|
current_mk->next = malloc(sizeof(*match_key));
|
||||||
|
current_mk = current_mk->next;
|
||||||
|
current_mk->value = dot;
|
||||||
|
current_mk->next = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
current_mk->hash = djb2_calculate(current_mk->value);
|
||||||
|
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
@ -702,7 +722,7 @@ int main(int argc, char** argv)
|
|||||||
char** dat_buffer = dat_buffers;
|
char** dat_buffer = dat_buffers;
|
||||||
dat_converter_list_t* dat_parser_list = NULL;
|
dat_converter_list_t* dat_parser_list = NULL;
|
||||||
|
|
||||||
while(argc)
|
while (argc)
|
||||||
{
|
{
|
||||||
dat_converter_list_t* dat_lexer_list;
|
dat_converter_list_t* dat_lexer_list;
|
||||||
size_t dat_file_size;
|
size_t dat_file_size;
|
||||||
@ -751,10 +771,20 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
dat_converter_list_free(dat_parser_list);
|
dat_converter_list_free(dat_parser_list);
|
||||||
|
|
||||||
while(dat_count--)
|
while (dat_count--)
|
||||||
free(dat_buffers[dat_count]);
|
free(dat_buffers[dat_count]);
|
||||||
free(dat_buffers);
|
free(dat_buffers);
|
||||||
|
|
||||||
|
if(match_key)
|
||||||
|
free(match_key->value);
|
||||||
|
|
||||||
|
while(match_key)
|
||||||
|
{
|
||||||
|
dat_converter_match_key_t* next = match_key->next;
|
||||||
|
free(match_key);
|
||||||
|
match_key = next;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user