diff --git a/mie/dialect/index/index-cache.c b/mie/dialect/index/index-cache.c new file mode 100644 index 0000000..366fea6 --- /dev/null +++ b/mie/dialect/index/index-cache.c @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include + +struct index_cache_entry { + b_btree_node e_node; + struct mie_index e_value; +}; + +struct mie_index_cache { + b_btree c_entries; +}; + +static B_BTREE_DEFINE_SIMPLE_INSERT( + struct index_cache_entry, e_node, e_value.i_value, put_index); +static B_BTREE_DEFINE_SIMPLE_GET( + struct index_cache_entry, size_t, e_node, e_value.i_value, get_index); + +static struct index_cache_entry *index_cache_entry_create( + struct mie_ctx *ctx, size_t val) +{ + struct index_cache_entry *out = malloc(sizeof *out); + if (!out) { + return NULL; + } + + out->e_value.i_value = val; + out->e_value.i_base.v_type = mie_ctx_get_type(ctx, "index", "index"); + if (!out->e_value.i_base.v_type) { + free(out); + return NULL; + } + + return out; +} + +struct mie_index_cache *mie_index_cache_create(void) +{ + struct mie_index_cache *out = malloc(sizeof *out); + if (!out) { + return NULL; + } + + memset(out, 0x0, sizeof *out); + return out; +} + +void mie_index_cache_destroy(struct mie_index_cache *cache) +{ + b_btree_node *cur = b_btree_first(&cache->c_entries); + while (cur) { + b_btree_node *next = b_btree_next(cur); + b_btree_delete(&cache->c_entries, cur); + + struct index_cache_entry *entry + = b_unbox(struct index_cache_entry, cur, e_node); + free(entry); + + cur = next; + } + + free(cache); +} + +struct mie_index *mie_index_cache_get( + struct mie_index_cache *cache, struct mie_ctx *ctx, size_t value) +{ + struct index_cache_entry *entry = get_index(&cache->c_entries, value); + if (!entry) { + entry = index_cache_entry_create(ctx, value); + + if (!entry) { + return NULL; + } + + put_index(&cache->c_entries, entry); + } + + return &entry->e_value; +} diff --git a/mie/dialect/index/index.c b/mie/dialect/index/index.c new file mode 100644 index 0000000..8fbd76a --- /dev/null +++ b/mie/dialect/index/index.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include + +struct index_type { + struct mie_type i_base; +}; + +static void value_print( + const struct mie_type *ty, const struct mie_value *value, b_stream *out) +{ + struct index_type *index_ty = (struct index_type *)ty; + struct mie_index *index_val = (struct mie_index *)value; + b_stream_write_fmt( + out, NULL, "%zu : %s", index_val->i_value, + index_ty->i_base.ty_def->ty_name); +} + +static void type_init(const struct mie_dialect_type *type_info, struct mie_type *type) +{ + type->ty_instance_size = sizeof(struct mie_index); + type->ty_value_print = value_print; +} + +static enum mie_status print( + const struct mie_dialect_type *def, const struct mie_type *ty, b_stream *out) +{ + return MIE_SUCCESS; +} + +static enum mie_status parse( + const struct mie_dialect_type *def, struct mie_parser *parser, + struct mie_type **out) +{ + return MIE_SUCCESS; +} + +MIE_DIALECT_TYPE_BEGIN(mie_index_index, "index") + MIE_DIALECT_TYPE_STRUCT(struct index_type); + MIE_DIALECT_TYPE_INIT(type_init); + MIE_DIALECT_TYPE_PRINT(print); + MIE_DIALECT_TYPE_PARSE(parse); +MIE_DIALECT_TYPE_END() + +MIE_DIALECT_BEGIN(mie_index, "index") + MIE_DIALECT_ADD_TYPE(mie_index_index); +MIE_DIALECT_END() diff --git a/mie/include/mie/dialect/index.h b/mie/include/mie/dialect/index.h new file mode 100644 index 0000000..3a73cbb --- /dev/null +++ b/mie/include/mie/dialect/index.h @@ -0,0 +1,26 @@ +#ifndef MIE_DIALECT_INDEX_H_ +#define MIE_DIALECT_INDEX_H_ + +#include +#include +#include +#include + +struct mie_ctx; +struct mie_dialect; + +struct mie_index { + struct mie_value i_base; + size_t i_value; +}; + +struct mie_index_cache; + +MIE_API struct mie_dialect *mie_index_dialect_create(struct mie_ctx *ctx); + +MIE_API struct mie_index_cache *mie_index_cache_create(void); +MIE_API void mie_index_cache_destroy(struct mie_index_cache *cache); +MIE_API struct mie_index *mie_index_cache_get( + struct mie_index_cache *cache, struct mie_ctx *ctx, size_t value); + +#endif