Возможно, у меня много статических данных, включая внешние ключи к другим статическим данным, которые необходимо разрешить.Я хочу, чтобы файлы данных были скомпилированы как константы в мою программу.Я написал простой генератор кода C
, который принимает в качестве входных данных информацию о типе
Animal
string key
text description
~
Creature
string name
Animal animal
~
И данные
X
Neil
~
Animal
Bear
A bear is eating all the food.
.
Animal
Ostrich
An Ostrich is chilling.
.
Creature
Steve
Bear
Creature
Sam
Ostrich
Creature
Alice
Bear
И создает файл .h
из типаинформация,
/** Auto-generated from ./ by Loader. */
#include <stddef.h> /* size_t */
/* These are datatypes that are loaded from ./. */
struct AutoAnimal;
struct AutoCreature;
struct AutoAnimal {
const char *const key; /* key */
const char *const description;
};
struct AutoCreature {
const char *const name; /* key */
const struct AutoAnimal *animal;
};
/* Search. */
struct AutoAnimal *AutoAnimalSearch(const char *const animal);
struct AutoCreature *AutoCreatureSearch(const char *const creature);
и .c
из комбинированного типа информации и данных.Например, это разрешает внешний ключ для Alice
как &auto_animal[0]
, который является Bear
.
/** Auto-generated from ./ by Loader. */
#include <stdlib.h> /* bsearch */
#include <string.h> /* strcmp */
#include "x.h"
/*
./X.lore: "X" by Neil
*/
/* forward reference */
const struct AutoAnimal auto_animal[];
const struct AutoCreature auto_creature[];
/* loaded 5 lores */
const struct AutoAnimal auto_animal[] = {
{ "Bear", "A bear is eating all the food." },
{ "Ostrich", "An Ostrich is chilling." }
};
const int max_auto_animal = sizeof auto_animal / sizeof *auto_animal;
const struct AutoCreature auto_creature[] = {
{ "Alice", &auto_animal[0]/*Bear*/ },
{ "Sam", &auto_animal[1]/*Ostrich*/ },
{ "Steve", &auto_animal[0]/*Bear*/ }
};
const int max_auto_creature = sizeof auto_creature / sizeof *auto_creature;
static int animal_comp(const void *key, const void *elem) {
const char *const k = key;
const char *const e = ((const struct AutoAnimal *)elem)->key;
return strcmp(k, e);
}
struct AutoAnimal *AutoAnimalSearch(const char *const key) {
return bsearch(&key, auto_animal, max_auto_animal, sizeof *auto_animal, &animal_comp);
}
static int creature_comp(const char *const *key_ptr, const struct AutoCreature *elem) {
const char *const k = *key_ptr;
const char *const e = elem->name;
return strcmp(k, e);
}
struct AutoCreature *AutoCreatureSearch(const char *const key) {
return bsearch(&key, auto_creature, max_auto_creature, sizeof(struct AutoCreature), (int (*)(const void *, const void *))&creature_comp);
}
Выход отсортирован, так что я могу запустить bsearch
на нем.Если я свяжу программу с автоматически сгенерированным источником,
#include <stdlib.h>
#include <stdio.h>
#include "x.h"
int main(void) {
const struct AutoCreature *creatures[] = {
AutoCreatureSearch("Sam"),
AutoCreatureSearch("Alice"),
AutoCreatureSearch("Eve")
}, **ac, **ac_end, *c;
const size_t creatures_size = sizeof creatures / sizeof *creatures;
for(ac = creatures, ac_end = creatures + creatures_size; ac < ac_end; ac++){
if(!(c = *ac)) { printf("Creature is not on record.\n"); continue; }
printf("Creature %s is a(n) %s. %s\n", c->name, c->animal->key,
c->animal->description);
}
return EXIT_SUCCESS;
}
Это даст,
Creature Sam is a(n) Ostrich. An Ostrich is chilling.
Creature Alice is a(n) Bear. A bear is eating all the food.
Creature is not on record.
Однако мне не нужно искать.Я хотел бы запустить gperf
для всей «базы данных» и получить результаты в O(1)
.gperf
и мой загрузчик вывели код завершения C
, но я не могу разрешить внешние ключи, не зная позиций в другой таблице.Есть ли способ автоматизировать закрытие внешних ключей и идеальные хеш-таблицы, которые не требуют написания полноценного парсера для C
?