From 4808a8abe778014aa7bfc24b4654dd16286d26e5 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Mon, 24 Feb 2025 15:55:26 +0000 Subject: [PATCH] re-implement chunk_table b-tree function callbacks --- src/chunk-table.c | 268 +++++++++++++++++++++++++++++++++------------- src/chunk-table.h | 37 ++----- 2 files changed, 202 insertions(+), 103 deletions(-) diff --git a/src/chunk-table.c b/src/chunk-table.c index 4f0dd1a..b0c2395 100644 --- a/src/chunk-table.c +++ b/src/chunk-table.c @@ -1,12 +1,11 @@ #include "chunk-table.h" #include "b-tree.h" -#include "pipeline.h" -#include "read.h" +#include "bin.h" +#include "tag.h" #include -#if 0 struct cache_entry { b_btree_node e_node; ec3_chunk_id e_id; @@ -87,14 +86,17 @@ static int node_init(struct chunk_table *tab, struct ec3_chunk_group *n) static int tree_get_node(struct b_tree *p, unsigned long id, b_tree_node *n) { struct chunk_table *table = (struct chunk_table *)p; - if (table->tab_mode != CHUNK_TABLE_READ) { + size_t cluster_size + = ec3_cluster_size_id_to_bytes(table->tab_cluster_size); + + size_t nr_read; + enum ec3_status status + = ec3_tag_ioctx_read_cluster(table->tab_ctab, id, n, &nr_read); + + if (status != EC3_SUCCESS) { return -1; } - size_t nr_read; - ec3_tag_reader_read(table->tab_read.ctab, id, 1, n, &nr_read); - - size_t cluster_size = ec3_get_cluster_size(table->tab_cluster_size); return nr_read == cluster_size ? 0 : -1; } @@ -104,108 +106,244 @@ static int tree_put_node( const b_tree_node *n) { struct chunk_table *table = (struct chunk_table *)p; - size_t offset = table->t_offset + (id * sizeof(struct ec3_chunk_group)); - fseek(table->t_storage, offset, SEEK_SET); - size_t r = fwrite( + size_t cluster_size + = ec3_cluster_size_id_to_bytes(table->tab_cluster_size); + + size_t nr_written = 0; + enum ec3_status status = ec3_tag_ioctx_write_cluster( + table->tab_ctab, + id, n, - sizeof(struct ec3_chunk_group), - 1, - table->t_storage); - return r == 1 ? 0 : -1; + cluster_size, + &nr_written); + + return status == EC3_SUCCESS ? 0 : -1; } static long tree_alloc_node(struct b_tree *p) { struct chunk_table *table = (struct chunk_table *)p; - size_t pos = ftell(table->t_storage); - fseek(table->t_storage, 0, SEEK_END); - size_t len = ftell(table->t_storage); + size_t cluster_size + = ec3_cluster_size_id_to_bytes(table->tab_cluster_size); + + size_t nr_clusters; + enum ec3_status status + = ec3_tag_ioctx_get_nr_clusters(table->tab_ctab, &nr_clusters); + + if (status != EC3_SUCCESS) { + return -1; + } struct ec3_chunk_group *n = (struct ec3_chunk_group *)b_tree_cache_alloc_node(p); - node_init(n); + node_init(table, n); - fwrite(&n, sizeof *n, 1, table->t_storage); + size_t nr_written = 0; + status = ec3_tag_ioctx_write_cluster( + table->tab_ctab, + nr_clusters, + n, + cluster_size, + &nr_written); - fseek(table->t_storage, pos, SEEK_SET); + if (status != EC3_SUCCESS) { + return -1; + } - len /= sizeof *n; - table->t_nr_groups++; - - return (long)len; + return (long)nr_clusters; } -static unsigned long node_get_nr_entries(b_tree_node *n) +static unsigned long node_get_nr_entries(struct b_tree *tree, b_tree_node *n) { struct ec3_chunk_group *node = (struct ec3_chunk_group *)n; return b_i16_btoh(node->g_nr_chunks); } -static void node_set_nr_entries(b_tree_node *n, unsigned long val) +static void node_set_nr_entries( + struct b_tree *tree, + b_tree_node *n, + unsigned long val) { struct ec3_chunk_group *node = (struct ec3_chunk_group *)n; node->g_nr_chunks = b_i16_htob(val); } -static b_tree_node_entry *node_get_entry(b_tree_node *n, unsigned long index) +static b_tree_node_entry *node_get_entry( + struct b_tree *tree, + b_tree_node *n, + unsigned long index) { + struct chunk_table *table = (struct chunk_table *)table; struct ec3_chunk_group *node = (struct ec3_chunk_group *)n; - return (b_tree_node_entry *)&node->g_chunks[index]; + + switch (table->tab_cluster_size) { + case EC3_CLUSTER_4K: + return (b_tree_node_entry *)&node->g_4k.g_chunks[index]; + case EC3_CLUSTER_8K: + return (b_tree_node_entry *)&node->g_8k.g_chunks[index]; + case EC3_CLUSTER_16K: + return (b_tree_node_entry *)&node->g_16k.g_chunks[index]; + case EC3_CLUSTER_32K: + return (b_tree_node_entry *)&node->g_32k.g_chunks[index]; + case EC3_CLUSTER_64K: + return (b_tree_node_entry *)&node->g_64k.g_chunks[index]; + default: + return NULL; + } } static void node_set_entry( + struct b_tree *tree, b_tree_node *n, unsigned long index, const b_tree_node_entry *entry) { + struct chunk_table *table = (struct chunk_table *)table; struct ec3_chunk_group *node = (struct ec3_chunk_group *)n; - memmove(&node->g_chunks[index], entry, sizeof(struct ec3_chunk)); + + switch (table->tab_cluster_size) { + case EC3_CLUSTER_4K: + memmove(&node->g_4k.g_chunks[index], + entry, + sizeof(struct ec3_chunk)); + break; + case EC3_CLUSTER_8K: + memmove(&node->g_8k.g_chunks[index], + entry, + sizeof(struct ec3_chunk)); + break; + case EC3_CLUSTER_16K: + memmove(&node->g_16k.g_chunks[index], + entry, + sizeof(struct ec3_chunk)); + break; + case EC3_CLUSTER_32K: + memmove(&node->g_32k.g_chunks[index], + entry, + sizeof(struct ec3_chunk)); + break; + case EC3_CLUSTER_64K: + memmove(&node->g_64k.g_chunks[index], + entry, + sizeof(struct ec3_chunk)); + break; + default: + break; + } } -static void node_kill_entry(b_tree_node *n, unsigned long index) +static void node_kill_entry( + struct b_tree *tree, + b_tree_node *n, + unsigned long index) { + struct chunk_table *table = (struct chunk_table *)table; struct ec3_chunk_group *node = (struct ec3_chunk_group *)n; - memset(&node->g_chunks[index], 0x0, sizeof(struct ec3_chunk)); + + switch (table->tab_cluster_size) { + case EC3_CLUSTER_4K: + memset(&node->g_4k.g_chunks[index], + 0x0, + sizeof(struct ec3_chunk)); + break; + case EC3_CLUSTER_8K: + memset(&node->g_8k.g_chunks[index], + 0x0, + sizeof(struct ec3_chunk)); + break; + case EC3_CLUSTER_16K: + memset(&node->g_16k.g_chunks[index], + 0x0, + sizeof(struct ec3_chunk)); + break; + case EC3_CLUSTER_32K: + memset(&node->g_32k.g_chunks[index], + 0x0, + sizeof(struct ec3_chunk)); + break; + case EC3_CLUSTER_64K: + memset(&node->g_64k.g_chunks[index], + 0x0, + sizeof(struct ec3_chunk)); + break; + default: + break; + } } -static unsigned long node_get_child(b_tree_node *n, unsigned long index) +static unsigned long node_get_child( + struct b_tree *tree, + b_tree_node *n, + unsigned long index) { + struct chunk_table *table = (struct chunk_table *)table; struct ec3_chunk_group *node = (struct ec3_chunk_group *)n; - b_i32 enc_child = node->g_child_offsets[index]; - unsigned long child = b_i32_btoh(enc_child); + unsigned long child = EC3_INVALID_OFFSET; + + switch (table->tab_cluster_size) { + case EC3_CLUSTER_4K: + child = b_i32_btoh(node->g_4k.g_child_offsets[index]); + break; + case EC3_CLUSTER_8K: + child = b_i32_btoh(node->g_8k.g_child_offsets[index]); + break; + case EC3_CLUSTER_16K: + child = b_i32_btoh(node->g_16k.g_child_offsets[index]); + break; + case EC3_CLUSTER_32K: + child = b_i32_btoh(node->g_32k.g_child_offsets[index]); + break; + case EC3_CLUSTER_64K: + child = b_i32_btoh(node->g_64k.g_child_offsets[index]); + break; + default: + return B_TREE_INVALID_PTR; + } + return child == EC3_INVALID_OFFSET ? B_TREE_INVALID_PTR : child; } static void node_set_child( + struct b_tree *tree, b_tree_node *n, unsigned long index, unsigned long ptr) { + struct chunk_table *table = (struct chunk_table *)table; struct ec3_chunk_group *node = (struct ec3_chunk_group *)n; - unsigned long child = ptr == B_TREE_INVALID_PTR ? EC3_INVALID_OFFSET - : (uint16_t)ptr; - node->g_child_offsets[index] = b_i32_htob(child); + unsigned long child + = ptr == B_TREE_INVALID_PTR ? EC3_INVALID_OFFSET : ptr; + + switch (table->tab_cluster_size) { + case EC3_CLUSTER_4K: + node->g_4k.g_child_offsets[index] = b_i32_htob(child); + break; + case EC3_CLUSTER_8K: + node->g_8k.g_child_offsets[index] = b_i32_htob(child); + break; + case EC3_CLUSTER_16K: + node->g_16k.g_child_offsets[index] = b_i32_htob(child); + break; + case EC3_CLUSTER_32K: + node->g_32k.g_child_offsets[index] = b_i32_htob(child); + break; + case EC3_CLUSTER_64K: + node->g_64k.g_child_offsets[index] = b_i32_htob(child); + break; + default: + break; + } } static int entry_compare( + const struct b_tree *tree, const b_tree_node_entry *e0, const b_tree_node_entry *e1) { struct ec3_chunk *a = (struct ec3_chunk *)e0, *b = (struct ec3_chunk *)e1; - unsigned long a_id = b_i32_btoh(a->c_id); - unsigned long b_id = b_i32_btoh(b->c_id); - - if (a_id < b_id) { - return -1; - } - - if (a_id > b_id) { - return 1; - } - - return 0; + return memcmp(a->c_id, b->c_id, sizeof a->c_id); } static const struct b_tree_ops cluster_table_ops = { @@ -224,33 +362,16 @@ static const struct b_tree_ops cluster_table_ops = { .entry_compare = entry_compare, }; -enum ec3_status chunk_table_init_read( - struct ec3_tag_reader *ctab, - struct ec3_tag_reader *cdat, - size_t cluster_size, +enum ec3_status chunk_table_init( + struct ec3_tag_ioctx *ctab, + struct ec3_tag_ioctx *cdat, + enum ec3_cluster_size cluster_size, struct chunk_table *tab) { memset(tab, 0x0, sizeof *tab); - tab->tab_mode = CHUNK_TABLE_READ; - tab->tab_read.ctab = ctab; - tab->tab_read.cdat = cdat; - tab->tab_cluster_size = cluster_size; - - return EC3_SUCCESS; -} - -enum ec3_status chunk_table_init_write( - struct ec3_tag_writer *ctab, - struct ec3_tag_writer *cdat, - size_t cluster_size, - struct chunk_table *tab) -{ - memset(tab, 0x0, sizeof *tab); - - tab->tab_mode = CHUNK_TABLE_WRITE; - tab->tab_write.ctab = ctab; - tab->tab_write.cdat = cdat; + tab->tab_ctab = ctab; + tab->tab_cdat = cdat; tab->tab_cluster_size = cluster_size; return EC3_SUCCESS; @@ -277,4 +398,3 @@ enum ec3_status chunk_table_put( { return EC3_SUCCESS; } -#endif diff --git a/src/chunk-table.h b/src/chunk-table.h index efe8dca..1d7b8b3 100644 --- a/src/chunk-table.h +++ b/src/chunk-table.h @@ -7,41 +7,20 @@ #include #include -struct ec3_tag_reader; -struct ec3_tag_writer; - -enum chunk_table_mode { - CHUNK_TABLE_READ, - CHUNK_TABLE_WRITE, -}; +struct ec3_tag_ioctx; struct chunk_table { - enum chunk_table_mode tab_mode; - unsigned int tab_cluster_size; + enum ec3_cluster_size tab_cluster_size; b_btree tab_cache; - union { - struct { - struct ec3_tag_reader *ctab; - struct ec3_tag_reader *cdat; - } tab_read; - - struct { - struct ec3_tag_writer *ctab; - struct ec3_tag_writer *cdat; - } tab_write; - }; + struct ec3_tag_ioctx *tab_ctab; + struct ec3_tag_ioctx *tab_cdat; }; -extern enum ec3_status chunk_table_init_read( - struct ec3_tag_reader *ctab, - struct ec3_tag_reader *cdat, - size_t cluster_size, - struct chunk_table *tab); -extern enum ec3_status chunk_table_init_write( - struct ec3_tag_writer *ctab, - struct ec3_tag_writer *cdat, - size_t cluster_size, +extern enum ec3_status chunk_table_init( + struct ec3_tag_ioctx *ctab, + struct ec3_tag_ioctx *cdat, + enum ec3_cluster_size cluster_size, struct chunk_table *tab); extern void chunk_table_finish(struct chunk_table *tab);