mie: implement caching and emitting string data

This commit is contained in:
2025-04-17 22:55:17 +01:00
parent abb7cfaf0e
commit 9cce4bf541
11 changed files with 211 additions and 58 deletions

View File

@@ -1,6 +1,9 @@
#include <blue/object/hashmap.h>
#include <mie/const.h>
#include <mie/data.h>
#include <mie/func.h>
#include <mie/module.h>
#include <mie/type.h>
#include <stdlib.h>
#include <string.h>
@@ -15,6 +18,10 @@ struct mie_module *mie_module_create(void)
mie_value_init(&out->m_base, MIE_VALUE_MODULE);
out->m_names = mie_name_map_create();
out->m_data = b_hashmap_create(NULL, NULL);
out->m_data_strings = b_hashmap_create(NULL, NULL);
return out;
}
@@ -23,27 +30,79 @@ void mie_module_add_function(struct mie_module *mod, struct mie_func *func)
b_queue_push_back(&mod->m_func, &func->f_base.v_entry);
}
struct mie_data *mie_module_get_data(struct mie_module *mod, const char *name)
struct mie_data *mie_module_get_string_ptr(struct mie_module *mod, const char *s)
{
b_queue_iterator it;
b_queue_foreach (&it, &mod->m_data) {
struct mie_data *data = (struct mie_data *)b_unbox(
struct mie_value, it.entry, v_entry);
if (!strcmp(data->d_base.v_name.n_str, name)) {
return data;
}
b_hashmap_key key = {
.key_data = s,
.key_size = strlen(s),
};
const b_hashmap_value *entry = b_hashmap_get(mod->m_data_strings, &key);
if (entry) {
return entry->value_data;
}
return NULL;
}
enum b_status mie_module_put_data(struct mie_module *mod, struct mie_data *data)
struct mie_data *mie_module_get_data(struct mie_module *mod, const char *name)
{
/* TODO enforce unique names */
b_queue_push_back(&mod->m_data, &data->d_base.v_entry);
b_hashmap_key key = {
.key_data = name,
.key_size = strlen(name),
};
const b_hashmap_value *entry = b_hashmap_get(mod->m_data, &key);
if (entry) {
return entry->value_data;
}
/* don't search m_data_strings, as it is keyed by the string contents
* rather than the data entry name, and its entries are duplicated in
* m_data anyway */
return NULL;
}
enum b_status mie_module_put_data(
struct mie_module *mod, struct mie_data *data, const char *name)
{
struct mie_value *v
= mie_module_generate_value_name(mod, MIE_VALUE(data), name);
b_hashmap_key key = {
.key_data = v->v_name.n_str,
.key_size = strlen(name),
};
b_hashmap_value value = {
.value_data = data,
.value_size = sizeof *data,
};
b_hashmap_put(mod->m_data, &key, &value);
if (data->d_type != MIE_DATA_CONST) {
return B_SUCCESS;
}
struct mie_const *const_data = data->d_const.c_value;
if (const_data->c_type->t_id == MIE_TYPE_STR) {
key.key_data = const_data->c_v.v_str;
key.key_size = strlen(key.key_data);
b_hashmap_put(mod->m_data_strings, &key, &value);
}
return B_SUCCESS;
}
struct mie_value *mie_module_generate_value_name(
struct mie_module *mod, struct mie_value *val, const char *hint)
{
struct mie_name *name = mie_name_map_put(mod->m_names, &val->v_name, hint);
return b_unbox(struct mie_value, name, v_name);
}
static void cleanup(struct mie_value *value)
{
struct mie_module *module = MIE_MODULE(value);
@@ -56,13 +115,6 @@ static void cleanup(struct mie_value *value)
mie_value_destroy(v);
}
b_queue_iterator_begin(&module->m_data, &it);
while (b_queue_iterator_is_valid(&it)) {
struct mie_value *v = b_unbox(struct mie_value, it.entry, v_entry);
b_queue_iterator_erase(&it);
mie_value_destroy(v);
}
b_queue_iterator_begin(&module->m_types, &it);
while (b_queue_iterator_is_valid(&it)) {
struct mie_value *v = b_unbox(struct mie_value, it.entry, v_entry);
@@ -76,6 +128,9 @@ static void cleanup(struct mie_value *value)
b_queue_iterator_erase(&it);
mie_value_destroy(v);
}
b_hashmap_release(module->m_data_strings);
b_hashmap_release(module->m_data);
}
const struct mie_value_type module_value_type = {