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

@@ -66,43 +66,39 @@ void mie_builder_put_record(
b_queue_push_back(&builder->b_module->m_records, &rec->r_base.v_entry); b_queue_push_back(&builder->b_module->m_records, &rec->r_base.v_entry);
} }
#if 0
void mie_builder_put_data(struct mie_builder *builder, struct mie_data *data) void mie_builder_put_data(struct mie_builder *builder, struct mie_data *data)
{ {
if (!builder->b_module) { if (!builder->b_module) {
return; return;
} }
b_queue_iterator it = {}; const char *data_name = data->d_base.v_name.n_str;
b_queue_foreach (&it, &builder->b_module->m_data) { struct mie_data *v = mie_module_get_data(builder->b_module, data_name);
struct mie_value *cur if (v) {
= b_unbox(struct mie_value, it.entry, v_entry);
if (!strcmp(cur->v_name.n_str, data->d_base.v_name.n_str)) {
return; return;
} }
}
b_queue_push_back(&builder->b_module->m_data, &data->d_base.v_entry); mie_module_put_data(builder->b_module, data);
} }
#endif
#if 0
void mie_builder_put_type(struct mie_builder *builder, struct mie_type *type) void mie_builder_put_type(struct mie_builder *builder, struct mie_type *type)
{ {
if (!builder->b_module) { if (!builder->b_module) {
return; return;
} }
b_queue_iterator it = {}; const char *type_name = type->t_base.v_name.n_str;
b_queue_foreach (&it, &builder->b_module->m_types) { struct mie_data *v = mie_module_get_data(builder->b_module, type_name);
struct mie_value *cur if (v) {
= b_unbox(struct mie_value, it.entry, v_entry);
if (!strcmp(cur->v_name.n_str, type->t_base.v_name.n_str)) {
return; return;
} }
}
b_queue_push_back(&builder->b_module->m_data, &type->t_base.v_entry); mie_module_put_data(builder->b_module, MIE_VALUE);
} }
#endif
void mie_builder_set_insert_point( void mie_builder_set_insert_point(
struct mie_builder *builder, struct mie_block *block) struct mie_builder *builder, struct mie_block *block)
@@ -127,7 +123,32 @@ struct mie_value *mie_builder_get_data_ptr(
return NULL; return NULL;
} }
mie_module_put_data(builder->b_module, data); mie_module_put_data(builder->b_module, data, data_ident);
}
return MIE_VALUE(data);
}
struct mie_value *mie_builder_get_string_ptr(
struct mie_builder *builder, const char *s)
{
if (!builder->b_module) {
return NULL;
}
struct mie_data *data = mie_module_get_string_ptr(builder->b_module, s);
if (!data) {
struct mie_type *str
= mie_ctx_get_type(builder->b_ctx, MIE_TYPE_STR);
struct mie_value *value = mie_ctx_get_string(builder->b_ctx, s);
data = mie_data_create_const((struct mie_const *)value);
if (!data) {
return NULL;
}
mie_module_put_data(builder->b_module, data, ".str");
} }
return MIE_VALUE(data); return MIE_VALUE(data);

View File

@@ -2,6 +2,22 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
struct mie_const *mie_const_create(struct mie_type *type)
{
struct mie_const *c = malloc(sizeof *c);
if (!c) {
return NULL;
}
memset(c, 0x0, sizeof *c);
mie_value_init(&c->c_base, MIE_VALUE_CONST);
c->c_type = type;
return c;
}
static struct mie_type *get_type(struct mie_value *v) static struct mie_type *get_type(struct mie_value *v)
{ {
struct mie_const *c = MIE_CONST(v); struct mie_const *c = MIE_CONST(v);

View File

@@ -1,5 +1,6 @@
#include "convert.h" #include "convert.h"
#include <blue/object/hashmap.h>
#include <inttypes.h> #include <inttypes.h>
#include <mie/alloca.h> #include <mie/alloca.h>
#include <mie/arg.h> #include <mie/arg.h>
@@ -153,7 +154,7 @@ static b_status write_operand_const(
break; break;
case MIE_TYPE_STR: case MIE_TYPE_STR:
case MIE_TYPE_ATOM: case MIE_TYPE_ATOM:
write_string(converter, c->c_v.v_str); write_string_f(converter, "\"%s\"", c->c_v.v_str);
break; break;
case MIE_TYPE_CLASS: case MIE_TYPE_CLASS:
write_string_f(converter, "@%s", value->v_name.n_str); write_string_f(converter, "@%s", value->v_name.n_str);
@@ -266,9 +267,10 @@ static b_status write_module(
write_char(converter, '\n'); write_char(converter, '\n');
} }
b_queue_foreach (&it, &mod->m_data) { b_hashmap_iterator it2;
struct mie_value *data b_hashmap_foreach(&it2, mod->m_data)
= b_unbox(struct mie_value, it.entry, v_entry); {
struct mie_value *data = it2.value->value_data;
status = write_value_to_text(converter, data); status = write_value_to_text(converter, data);
if (!B_OK(status)) { if (!B_OK(status)) {
@@ -276,7 +278,7 @@ static b_status write_module(
} }
} }
if (!b_queue_empty(&mod->m_data)) { if (!b_hashmap_is_empty(mod->m_data)) {
write_char(converter, '\n'); write_char(converter, '\n');
} }
@@ -552,7 +554,8 @@ static b_status write_data(
break; break;
case MIE_DATA_CONST: case MIE_DATA_CONST:
write_operand_const( write_operand_const(
converter, data->d_const.c_value, F_INCLUDE_TYPE); converter, MIE_VALUE(data->d_const.c_value),
F_INCLUDE_TYPE);
break; break;
default: default:
write_string(converter, "<unknown>"); write_string(converter, "<unknown>");

View File

@@ -43,6 +43,7 @@ struct mie_ctx *mie_ctx_create(void)
out->ctx_false = MIE_CONST(mie_ctx_get_int(out, 0, 1)); out->ctx_false = MIE_CONST(mie_ctx_get_int(out, 0, 1));
out->ctx_sel_cache = b_hashmap_create(free, free); out->ctx_sel_cache = b_hashmap_create(free, free);
out->ctx_string_cache = b_hashmap_create(free, free);
return out; return out;
} }
@@ -214,3 +215,38 @@ struct mie_value *mie_ctx_get_selector(struct mie_ctx *ctx, const char *sel)
return MIE_VALUE(sel_value); return MIE_VALUE(sel_value);
} }
struct mie_value *mie_ctx_get_string(struct mie_ctx *ctx, const char *s)
{
b_hashmap_key key = {
.key_data = s,
.key_size = strlen(s),
};
const b_hashmap_value *cache_entry
= b_hashmap_get(ctx->ctx_string_cache, &key);
if (cache_entry) {
return cache_entry->value_data;
}
struct mie_const *string_value = malloc(sizeof *string_value);
if (!string_value) {
return NULL;
}
mie_value_init(&string_value->c_base, MIE_VALUE_CONST);
string_value->c_type = mie_ctx_get_type(ctx, MIE_TYPE_STR);
string_value->c_v.v_str = b_strdup(s);
key.key_data = string_value->c_v.v_str;
b_hashmap_value hashmap_value = {
.value_data = string_value,
.value_size = sizeof *string_value,
};
b_hashmap_put(ctx->ctx_string_cache, &key, &hashmap_value);
return MIE_VALUE(string_value);
}

View File

@@ -33,6 +33,23 @@ struct mie_data *mie_data_create_extern_global(
return data; return data;
} }
struct mie_data *mie_data_create_const(struct mie_const *value)
{
struct mie_data *data = malloc(sizeof *data);
if (!data) {
return NULL;
}
memset(data, 0x0, sizeof *data);
mie_value_init(&data->d_base, MIE_VALUE_DATA);
data->d_type = MIE_DATA_CONST;
data->d_const.c_value = value;
return data;
}
static struct mie_type *get_type(struct mie_value *v) static struct mie_type *get_type(struct mie_value *v)
{ {
if (!ptr_type.t_id) { if (!ptr_type.t_id) {

View File

@@ -27,18 +27,6 @@ enum mie_builder_flags {
MIE_BUILDER_IGNORE_RESULT = 0x01u, MIE_BUILDER_IGNORE_RESULT = 0x01u,
}; };
extern struct mie_ctx *mie_ctx_create(void);
extern void mie_ctx_destroy(struct mie_ctx *ctx);
extern struct mie_type *mie_ctx_get_type(
struct mie_ctx *ctx, enum mie_type_id type_id);
extern struct mie_type *mie_ctx_get_int_type(
struct mie_ctx *ctx, unsigned int nr_bits);
extern struct mie_value *mie_ctx_get_bool(struct mie_ctx *ctx, bool val);
extern struct mie_value *mie_ctx_get_int(
struct mie_ctx *ctx, long long val, unsigned int nr_bits);
extern struct mie_value *mie_ctx_get_selector(struct mie_ctx *ctx, const char *sel);
extern struct mie_builder *mie_builder_create( extern struct mie_builder *mie_builder_create(
struct mie_ctx *ctx, struct mie_module *mod); struct mie_ctx *ctx, struct mie_module *mod);
extern void mie_builder_destroy(struct mie_builder *builder); extern void mie_builder_destroy(struct mie_builder *builder);
@@ -59,6 +47,8 @@ extern void mie_builder_set_insert_point(
extern struct mie_value *mie_builder_get_data_ptr( extern struct mie_value *mie_builder_get_data_ptr(
struct mie_builder *builder, const char *data_ident); struct mie_builder *builder, const char *data_ident);
extern struct mie_value *mie_builder_get_string_ptr(
struct mie_builder *builder, const char *s);
extern struct mie_value *mie_builder_ret( extern struct mie_value *mie_builder_ret(
struct mie_builder *builder, struct mie_value *val); struct mie_builder *builder, struct mie_value *val);

View File

@@ -18,4 +18,6 @@ struct mie_const {
} c_v; } c_v;
}; };
extern struct mie_const *mie_const_create(struct mie_type *type);
#endif #endif

View File

@@ -9,6 +9,7 @@ struct mie_ctx {
struct mie_type *ctx_types[__MIE_TYPE_COUNT]; struct mie_type *ctx_types[__MIE_TYPE_COUNT];
b_btree ctx_int_cache; b_btree ctx_int_cache;
struct b_hashmap *ctx_sel_cache; struct b_hashmap *ctx_sel_cache;
struct b_hashmap *ctx_string_cache;
}; };
extern struct mie_ctx *mie_ctx_create(void); extern struct mie_ctx *mie_ctx_create(void);
@@ -21,6 +22,7 @@ extern struct mie_type *mie_ctx_get_int_type(
extern struct mie_value *mie_ctx_get_bool(struct mie_ctx *ctx, bool val); extern struct mie_value *mie_ctx_get_bool(struct mie_ctx *ctx, bool val);
extern struct mie_value *mie_ctx_get_int( extern struct mie_value *mie_ctx_get_int(
struct mie_ctx *ctx, long long val, unsigned int nr_bits); struct mie_ctx *ctx, long long val, unsigned int nr_bits);
extern struct mie_value *mie_ctx_get_string(struct mie_ctx *ctx, const char *s);
extern struct mie_value *mie_ctx_get_selector(struct mie_ctx *ctx, const char *sel); extern struct mie_value *mie_ctx_get_selector(struct mie_ctx *ctx, const char *sel);
#endif #endif

View File

@@ -16,7 +16,7 @@ struct mie_data {
enum mie_data_type d_type; enum mie_data_type d_type;
union { union {
struct { struct {
struct mie_value *c_value; struct mie_const *c_value;
} d_const; } d_const;
struct { struct {
@@ -27,5 +27,6 @@ struct mie_data {
extern struct mie_data *mie_data_create_extern_global( extern struct mie_data *mie_data_create_extern_global(
struct mie_type *type, const char *ident); struct mie_type *type, const char *ident);
extern struct mie_data *mie_data_create_const(struct mie_const *value);
#endif #endif

View File

@@ -4,23 +4,33 @@
#define MIE_MODULE(p) ((struct mie_module *)(p)) #define MIE_MODULE(p) ((struct mie_module *)(p))
#include <blue/core/queue.h> #include <blue/core/queue.h>
#include <mie/name.h>
#include <mie/value.h> #include <mie/value.h>
struct mie_func; struct mie_func;
struct b_hashmap;
struct mie_module { struct mie_module {
struct mie_value m_base; struct mie_value m_base;
struct mie_name_map *m_names;
b_queue m_records; b_queue m_records;
b_queue m_data;
b_queue m_types; b_queue m_types;
b_queue m_func; b_queue m_func;
struct b_hashmap *m_data;
struct b_hashmap *m_data_strings;
}; };
extern struct mie_module *mie_module_create(void); extern struct mie_module *mie_module_create(void);
extern void mie_module_add_function(struct mie_module *mod, struct mie_func *func); extern void mie_module_add_function(struct mie_module *mod, struct mie_func *func);
extern struct mie_data *mie_module_get_string_ptr(
struct mie_module *mod, const char *s);
extern struct mie_data *mie_module_get_data( extern struct mie_data *mie_module_get_data(
struct mie_module *mod, const char *name); struct mie_module *mod, const char *name);
extern enum b_status mie_module_put_data( extern enum b_status mie_module_put_data(
struct mie_module *mod, struct mie_data *data); struct mie_module *mod, struct mie_data *data, const char *name);
extern struct mie_value *mie_module_generate_value_name(
struct mie_module *mod, struct mie_value *val, const char *hint);
#endif #endif

View File

@@ -1,6 +1,9 @@
#include <blue/object/hashmap.h>
#include <mie/const.h>
#include <mie/data.h> #include <mie/data.h>
#include <mie/func.h> #include <mie/func.h>
#include <mie/module.h> #include <mie/module.h>
#include <mie/type.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -15,6 +18,10 @@ struct mie_module *mie_module_create(void)
mie_value_init(&out->m_base, MIE_VALUE_MODULE); 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; 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); 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_hashmap_key key = {
b_queue_foreach (&it, &mod->m_data) { .key_data = s,
struct mie_data *data = (struct mie_data *)b_unbox( .key_size = strlen(s),
struct mie_value, it.entry, v_entry); };
if (!strcmp(data->d_base.v_name.n_str, name)) {
return data; const b_hashmap_value *entry = b_hashmap_get(mod->m_data_strings, &key);
} if (entry) {
return entry->value_data;
} }
return NULL; 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_hashmap_key key = {
b_queue_push_back(&mod->m_data, &data->d_base.v_entry); .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; 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) static void cleanup(struct mie_value *value)
{ {
struct mie_module *module = MIE_MODULE(value); struct mie_module *module = MIE_MODULE(value);
@@ -56,13 +115,6 @@ static void cleanup(struct mie_value *value)
mie_value_destroy(v); 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); b_queue_iterator_begin(&module->m_types, &it);
while (b_queue_iterator_is_valid(&it)) { while (b_queue_iterator_is_valid(&it)) {
struct mie_value *v = b_unbox(struct mie_value, it.entry, v_entry); 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); b_queue_iterator_erase(&it);
mie_value_destroy(v); 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 = { const struct mie_value_type module_value_type = {