re-implement chunk_table b-tree function callbacks

This commit is contained in:
2025-02-24 15:55:26 +00:00
parent 10e031ba9e
commit 4808a8abe7
2 changed files with 202 additions and 103 deletions

View File

@@ -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 <string.h>
#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

View File

@@ -7,41 +7,20 @@
#include <blue/core/hash.h>
#include <stdio.h>
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);