re-implement chunk_table b-tree function callbacks
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user