mie: implement caching and emitting string data
This commit is contained in:
@@ -66,43 +66,39 @@ void mie_builder_put_record(
|
||||
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)
|
||||
{
|
||||
if (!builder->b_module) {
|
||||
return;
|
||||
}
|
||||
|
||||
b_queue_iterator it = {};
|
||||
b_queue_foreach (&it, &builder->b_module->m_data) {
|
||||
struct mie_value *cur
|
||||
= b_unbox(struct mie_value, it.entry, v_entry);
|
||||
|
||||
if (!strcmp(cur->v_name.n_str, data->d_base.v_name.n_str)) {
|
||||
const char *data_name = data->d_base.v_name.n_str;
|
||||
struct mie_data *v = mie_module_get_data(builder->b_module, data_name);
|
||||
if (v) {
|
||||
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)
|
||||
{
|
||||
if (!builder->b_module) {
|
||||
return;
|
||||
}
|
||||
|
||||
b_queue_iterator it = {};
|
||||
b_queue_foreach (&it, &builder->b_module->m_types) {
|
||||
struct mie_value *cur
|
||||
= b_unbox(struct mie_value, it.entry, v_entry);
|
||||
|
||||
if (!strcmp(cur->v_name.n_str, type->t_base.v_name.n_str)) {
|
||||
const char *type_name = type->t_base.v_name.n_str;
|
||||
struct mie_data *v = mie_module_get_data(builder->b_module, type_name);
|
||||
if (v) {
|
||||
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(
|
||||
struct mie_builder *builder, struct mie_block *block)
|
||||
@@ -127,7 +123,32 @@ struct mie_value *mie_builder_get_data_ptr(
|
||||
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);
|
||||
|
||||
16
mie/const.c
16
mie/const.c
@@ -2,6 +2,22 @@
|
||||
#include <stdlib.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)
|
||||
{
|
||||
struct mie_const *c = MIE_CONST(v);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "convert.h"
|
||||
|
||||
#include <blue/object/hashmap.h>
|
||||
#include <inttypes.h>
|
||||
#include <mie/alloca.h>
|
||||
#include <mie/arg.h>
|
||||
@@ -153,7 +154,7 @@ static b_status write_operand_const(
|
||||
break;
|
||||
case MIE_TYPE_STR:
|
||||
case MIE_TYPE_ATOM:
|
||||
write_string(converter, c->c_v.v_str);
|
||||
write_string_f(converter, "\"%s\"", c->c_v.v_str);
|
||||
break;
|
||||
case MIE_TYPE_CLASS:
|
||||
write_string_f(converter, "@%s", value->v_name.n_str);
|
||||
@@ -266,9 +267,10 @@ static b_status write_module(
|
||||
write_char(converter, '\n');
|
||||
}
|
||||
|
||||
b_queue_foreach (&it, &mod->m_data) {
|
||||
struct mie_value *data
|
||||
= b_unbox(struct mie_value, it.entry, v_entry);
|
||||
b_hashmap_iterator it2;
|
||||
b_hashmap_foreach(&it2, mod->m_data)
|
||||
{
|
||||
struct mie_value *data = it2.value->value_data;
|
||||
status = write_value_to_text(converter, data);
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
@@ -552,7 +554,8 @@ static b_status write_data(
|
||||
break;
|
||||
case MIE_DATA_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;
|
||||
default:
|
||||
write_string(converter, "<unknown>");
|
||||
|
||||
36
mie/ctx.c
36
mie/ctx.c
@@ -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_sel_cache = b_hashmap_create(free, free);
|
||||
out->ctx_string_cache = b_hashmap_create(free, free);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
17
mie/data.c
17
mie/data.c
@@ -33,6 +33,23 @@ struct mie_data *mie_data_create_extern_global(
|
||||
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)
|
||||
{
|
||||
if (!ptr_type.t_id) {
|
||||
|
||||
@@ -27,18 +27,6 @@ enum mie_builder_flags {
|
||||
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(
|
||||
struct mie_ctx *ctx, struct mie_module *mod);
|
||||
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(
|
||||
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(
|
||||
struct mie_builder *builder, struct mie_value *val);
|
||||
|
||||
@@ -18,4 +18,6 @@ struct mie_const {
|
||||
} c_v;
|
||||
};
|
||||
|
||||
extern struct mie_const *mie_const_create(struct mie_type *type);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,6 +9,7 @@ struct mie_ctx {
|
||||
struct mie_type *ctx_types[__MIE_TYPE_COUNT];
|
||||
b_btree ctx_int_cache;
|
||||
struct b_hashmap *ctx_sel_cache;
|
||||
struct b_hashmap *ctx_string_cache;
|
||||
};
|
||||
|
||||
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_int(
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -16,7 +16,7 @@ struct mie_data {
|
||||
enum mie_data_type d_type;
|
||||
union {
|
||||
struct {
|
||||
struct mie_value *c_value;
|
||||
struct mie_const *c_value;
|
||||
} d_const;
|
||||
|
||||
struct {
|
||||
@@ -27,5 +27,6 @@ struct mie_data {
|
||||
|
||||
extern struct mie_data *mie_data_create_extern_global(
|
||||
struct mie_type *type, const char *ident);
|
||||
extern struct mie_data *mie_data_create_const(struct mie_const *value);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,23 +4,33 @@
|
||||
#define MIE_MODULE(p) ((struct mie_module *)(p))
|
||||
|
||||
#include <blue/core/queue.h>
|
||||
#include <mie/name.h>
|
||||
#include <mie/value.h>
|
||||
|
||||
struct mie_func;
|
||||
struct b_hashmap;
|
||||
|
||||
struct mie_module {
|
||||
struct mie_value m_base;
|
||||
struct mie_name_map *m_names;
|
||||
b_queue m_records;
|
||||
b_queue m_data;
|
||||
b_queue m_types;
|
||||
b_queue m_func;
|
||||
|
||||
struct b_hashmap *m_data;
|
||||
struct b_hashmap *m_data_strings;
|
||||
};
|
||||
|
||||
extern struct mie_module *mie_module_create(void);
|
||||
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(
|
||||
struct mie_module *mod, const char *name);
|
||||
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
|
||||
|
||||
91
mie/module.c
91
mie/module.c
@@ -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,25 +30,77 @@ 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)
|
||||
@@ -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 = {
|
||||
|
||||
Reference in New Issue
Block a user