diff options
author | David Robillard <d@drobilla.net> | 2021-10-27 14:15:31 -0400 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2022-01-28 21:57:24 -0500 |
commit | 30487c277ac5d4be5786733ca7b98adb4c810ae9 (patch) | |
tree | f1b00a7725d74a594fcd91de2aea924485356528 /src/model.c | |
parent | 56cceb103dc633d6af957472945e792187a5dd4e (diff) | |
download | serd-30487c277ac5d4be5786733ca7b98adb4c810ae9.tar.gz serd-30487c277ac5d4be5786733ca7b98adb4c810ae9.tar.bz2 serd-30487c277ac5d4be5786733ca7b98adb4c810ae9.zip |
Add custom allocator support
Diffstat (limited to 'src/model.c')
-rw-r--r-- | src/model.c | 101 |
1 files changed, 73 insertions, 28 deletions
diff --git a/src/model.c b/src/model.c index 4e79fa77..1b1c144a 100644 --- a/src/model.c +++ b/src/model.c @@ -19,15 +19,16 @@ #include "caret.h" #include "compare.h" #include "cursor.h" +#include "memory.h" #include "statement.h" +#include "zix/allocator.h" #include "zix/btree.h" #include "zix/common.h" #include <assert.h> #include <stdbool.h> #include <stddef.h> -#include <stdlib.h> static const SerdQuad everything_pattern = {0, 0, 0, 0}; @@ -73,11 +74,15 @@ serd_model_add_index(SerdModel* const model, const SerdStatementOrder order) const unsigned* const ordering = orderings[order]; const ZixComparator comparator = serd_model_index_comparator(model, order); - model->indices[order] = zix_btree_new(NULL, comparator, ordering); + model->indices[order] = + zix_btree_new((ZixAllocator*)model->allocator, comparator, ordering); - ZixStatus zst = model->indices[order] ? ZIX_STATUS_SUCCESS : ZIX_STATUS_ERROR; + if (!model->indices[order]) { + return SERD_BAD_ALLOC; + } // Insert statements from the default index + ZixStatus zst = ZIX_STATUS_SUCCESS; if (order != model->default_order) { ZixBTree* const default_index = model->indices[model->default_order]; for (ZixBTreeIter i = zix_btree_begin(default_index); @@ -108,21 +113,38 @@ serd_model_drop_index(SerdModel* const model, const SerdStatementOrder order) return SERD_SUCCESS; } -SerdModel* -serd_model_new(SerdWorld* const world, - const SerdStatementOrder default_order, - const SerdModelFlags flags) +static SerdModel* +serd_model_new_with_allocator(SerdAllocator* const allocator, + SerdWorld* const world, + const SerdStatementOrder default_order, + const SerdModelFlags flags) { assert(world); - SerdModel* model = (SerdModel*)calloc(1, sizeof(struct SerdModelImpl)); + SerdNodes* const nodes = serd_nodes_new(allocator); + if (!nodes) { + return NULL; + } + + SerdModel* model = + (SerdModel*)serd_acalloc(allocator, 1, sizeof(struct SerdModelImpl)); + if (!model) { + serd_nodes_free(nodes); + return NULL; + } + + model->allocator = allocator; model->world = world; - model->nodes = serd_nodes_new(); + model->nodes = nodes; model->default_order = default_order; model->flags = flags; - serd_model_add_index(model, default_order); + if (serd_model_add_index(model, default_order)) { + serd_nodes_free(nodes); + serd_wfree(world, model); + return NULL; + } const ScanStrategy end_strategy = {SCAN_EVERYTHING, 0u, default_order}; @@ -135,12 +157,21 @@ serd_model_new(SerdWorld* const world, } SerdModel* -serd_model_copy(const SerdModel* const model) +serd_model_new(SerdWorld* const world, + const SerdStatementOrder default_order, + const SerdModelFlags flags) +{ + return serd_model_new_with_allocator( + serd_world_allocator(world), world, default_order, flags); +} + +SerdModel* +serd_model_copy(SerdAllocator* const allocator, const SerdModel* const model) { assert(model); - SerdModel* copy = - serd_model_new(model->world, model->default_order, model->flags); + SerdModel* copy = serd_model_new_with_allocator( + allocator, model->world, model->default_order, model->flags); SerdCursor* cursor = serd_model_begin(model); serd_model_insert_statements(copy, cursor); @@ -239,18 +270,23 @@ serd_model_drop_statement(SerdModel* const model, } } - if (statement->caret && statement->caret->file) { - serd_nodes_deref(model->nodes, statement->caret->file); + if (statement->caret && serd_caret_name(statement->caret)) { + serd_nodes_deref(model->nodes, serd_caret_name(statement->caret)); } - serd_statement_free(statement); + serd_statement_free(model->allocator, statement); } +typedef struct { + SerdAllocator* allocator; +} DestroyContext; + static void destroy_tree_statement(void* ptr, const void* user_data) { - (void)user_data; - serd_statement_free((SerdStatement*)ptr); + const DestroyContext* const ctx = (const DestroyContext*)user_data; + + serd_statement_free(ctx->allocator, (SerdStatement*)ptr); } void @@ -261,8 +297,9 @@ serd_model_free(SerdModel* const model) } // Free all statements (which are owned by the default index) - ZixBTree* const default_index = model->indices[model->default_order]; - zix_btree_clear(default_index, destroy_tree_statement, NULL); + ZixBTree* const default_index = model->indices[model->default_order]; + const DestroyContext ctx = {model->allocator}; + zix_btree_clear(default_index, destroy_tree_statement, &ctx); // Free indices themselves for (unsigned i = 0u; i < N_STATEMENT_ORDERS; ++i) { @@ -270,7 +307,7 @@ serd_model_free(SerdModel* const model) } serd_nodes_free(model->nodes); - free(model); + serd_wfree(model->world, model); } SerdWorld* @@ -323,7 +360,7 @@ serd_model_begin_ordered(const SerdModel* const model, const SerdCursor cursor = make_begin_cursor(model, order); - return serd_cursor_copy(&cursor); + return serd_cursor_copy(model->allocator, &cursor); } SerdCursor* @@ -524,7 +561,9 @@ serd_model_find(const SerdModel* const model, const SerdCursor cursor = serd_model_search(model, s, p, o, g); - return zix_btree_iter_is_end(cursor.iter) ? NULL : serd_cursor_copy(&cursor); + return zix_btree_iter_is_end(cursor.iter) + ? NULL + : serd_cursor_copy(model->allocator, &cursor); } const SerdNode* @@ -602,16 +641,20 @@ serd_model_ask(const SerdModel* const model, static SerdCaret* serd_model_intern_caret(SerdModel* const model, const SerdCaret* const caret) { - if (caret) { - SerdCaret* copy = (SerdCaret*)calloc(1, sizeof(SerdCaret)); + if (!caret) { + return NULL; + } + SerdCaret* const copy = + (SerdCaret*)serd_acalloc(model->allocator, 1, sizeof(SerdCaret)); + + if (copy) { copy->file = serd_nodes_intern(model->nodes, caret->file); copy->line = caret->line; copy->col = caret->col; - return copy; } - return NULL; + return copy; } SerdStatus @@ -624,7 +667,9 @@ serd_model_add_with_caret(SerdModel* const model, { assert(model); - SerdStatement* const statement = serd_statement_new(s, p, o, g, NULL); + SerdStatement* const statement = + serd_statement_new(model->allocator, s, p, o, g, NULL); + if (!statement) { return SERD_BAD_ALLOC; } |