re-implement chunk_table b-tree function callbacks
This commit is contained in:
@@ -1,12 +1,11 @@
|
|||||||
#include "chunk-table.h"
|
#include "chunk-table.h"
|
||||||
|
|
||||||
#include "b-tree.h"
|
#include "b-tree.h"
|
||||||
#include "pipeline.h"
|
#include "bin.h"
|
||||||
#include "read.h"
|
#include "tag.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#if 0
|
|
||||||
struct cache_entry {
|
struct cache_entry {
|
||||||
b_btree_node e_node;
|
b_btree_node e_node;
|
||||||
ec3_chunk_id e_id;
|
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)
|
static int tree_get_node(struct b_tree *p, unsigned long id, b_tree_node *n)
|
||||||
{
|
{
|
||||||
struct chunk_table *table = (struct chunk_table *)p;
|
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;
|
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;
|
return nr_read == cluster_size ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,108 +106,244 @@ static int tree_put_node(
|
|||||||
const b_tree_node *n)
|
const b_tree_node *n)
|
||||||
{
|
{
|
||||||
struct chunk_table *table = (struct chunk_table *)p;
|
struct chunk_table *table = (struct chunk_table *)p;
|
||||||
size_t offset = table->t_offset + (id * sizeof(struct ec3_chunk_group));
|
size_t cluster_size
|
||||||
fseek(table->t_storage, offset, SEEK_SET);
|
= ec3_cluster_size_id_to_bytes(table->tab_cluster_size);
|
||||||
size_t r = fwrite(
|
|
||||||
|
size_t nr_written = 0;
|
||||||
|
enum ec3_status status = ec3_tag_ioctx_write_cluster(
|
||||||
|
table->tab_ctab,
|
||||||
|
id,
|
||||||
n,
|
n,
|
||||||
sizeof(struct ec3_chunk_group),
|
cluster_size,
|
||||||
1,
|
&nr_written);
|
||||||
table->t_storage);
|
|
||||||
return r == 1 ? 0 : -1;
|
return status == EC3_SUCCESS ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long tree_alloc_node(struct b_tree *p)
|
static long tree_alloc_node(struct b_tree *p)
|
||||||
{
|
{
|
||||||
struct chunk_table *table = (struct chunk_table *)p;
|
struct chunk_table *table = (struct chunk_table *)p;
|
||||||
size_t pos = ftell(table->t_storage);
|
size_t cluster_size
|
||||||
fseek(table->t_storage, 0, SEEK_END);
|
= ec3_cluster_size_id_to_bytes(table->tab_cluster_size);
|
||||||
size_t len = ftell(table->t_storage);
|
|
||||||
|
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 *n
|
||||||
= (struct ec3_chunk_group *)b_tree_cache_alloc_node(p);
|
= (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;
|
return (long)nr_clusters;
|
||||||
table->t_nr_groups++;
|
|
||||||
|
|
||||||
return (long)len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
struct ec3_chunk_group *node = (struct ec3_chunk_group *)n;
|
||||||
return b_i16_btoh(node->g_nr_chunks);
|
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;
|
struct ec3_chunk_group *node = (struct ec3_chunk_group *)n;
|
||||||
node->g_nr_chunks = b_i16_htob(val);
|
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;
|
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(
|
static void node_set_entry(
|
||||||
|
struct b_tree *tree,
|
||||||
b_tree_node *n,
|
b_tree_node *n,
|
||||||
unsigned long index,
|
unsigned long index,
|
||||||
const b_tree_node_entry *entry)
|
const b_tree_node_entry *entry)
|
||||||
{
|
{
|
||||||
|
struct chunk_table *table = (struct chunk_table *)table;
|
||||||
struct ec3_chunk_group *node = (struct ec3_chunk_group *)n;
|
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;
|
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;
|
struct ec3_chunk_group *node = (struct ec3_chunk_group *)n;
|
||||||
b_i32 enc_child = node->g_child_offsets[index];
|
unsigned long child = EC3_INVALID_OFFSET;
|
||||||
unsigned long child = b_i32_btoh(enc_child);
|
|
||||||
|
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;
|
return child == EC3_INVALID_OFFSET ? B_TREE_INVALID_PTR : child;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void node_set_child(
|
static void node_set_child(
|
||||||
|
struct b_tree *tree,
|
||||||
b_tree_node *n,
|
b_tree_node *n,
|
||||||
unsigned long index,
|
unsigned long index,
|
||||||
unsigned long ptr)
|
unsigned long ptr)
|
||||||
{
|
{
|
||||||
|
struct chunk_table *table = (struct chunk_table *)table;
|
||||||
struct ec3_chunk_group *node = (struct ec3_chunk_group *)n;
|
struct ec3_chunk_group *node = (struct ec3_chunk_group *)n;
|
||||||
unsigned long child = ptr == B_TREE_INVALID_PTR ? EC3_INVALID_OFFSET
|
unsigned long child
|
||||||
: (uint16_t)ptr;
|
= ptr == B_TREE_INVALID_PTR ? EC3_INVALID_OFFSET : ptr;
|
||||||
node->g_child_offsets[index] = b_i32_htob(child);
|
|
||||||
|
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(
|
static int entry_compare(
|
||||||
|
const struct b_tree *tree,
|
||||||
const b_tree_node_entry *e0,
|
const b_tree_node_entry *e0,
|
||||||
const b_tree_node_entry *e1)
|
const b_tree_node_entry *e1)
|
||||||
{
|
{
|
||||||
struct ec3_chunk *a = (struct ec3_chunk *)e0,
|
struct ec3_chunk *a = (struct ec3_chunk *)e0,
|
||||||
*b = (struct ec3_chunk *)e1;
|
*b = (struct ec3_chunk *)e1;
|
||||||
|
|
||||||
unsigned long a_id = b_i32_btoh(a->c_id);
|
return memcmp(a->c_id, b->c_id, sizeof 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct b_tree_ops cluster_table_ops = {
|
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,
|
.entry_compare = entry_compare,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ec3_status chunk_table_init_read(
|
enum ec3_status chunk_table_init(
|
||||||
struct ec3_tag_reader *ctab,
|
struct ec3_tag_ioctx *ctab,
|
||||||
struct ec3_tag_reader *cdat,
|
struct ec3_tag_ioctx *cdat,
|
||||||
size_t cluster_size,
|
enum ec3_cluster_size cluster_size,
|
||||||
struct chunk_table *tab)
|
struct chunk_table *tab)
|
||||||
{
|
{
|
||||||
memset(tab, 0x0, sizeof *tab);
|
memset(tab, 0x0, sizeof *tab);
|
||||||
|
|
||||||
tab->tab_mode = CHUNK_TABLE_READ;
|
tab->tab_ctab = ctab;
|
||||||
tab->tab_read.ctab = ctab;
|
tab->tab_cdat = cdat;
|
||||||
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_cluster_size = cluster_size;
|
tab->tab_cluster_size = cluster_size;
|
||||||
|
|
||||||
return EC3_SUCCESS;
|
return EC3_SUCCESS;
|
||||||
@@ -277,4 +398,3 @@ enum ec3_status chunk_table_put(
|
|||||||
{
|
{
|
||||||
return EC3_SUCCESS;
|
return EC3_SUCCESS;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -7,41 +7,20 @@
|
|||||||
#include <blue/core/hash.h>
|
#include <blue/core/hash.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
struct ec3_tag_reader;
|
struct ec3_tag_ioctx;
|
||||||
struct ec3_tag_writer;
|
|
||||||
|
|
||||||
enum chunk_table_mode {
|
|
||||||
CHUNK_TABLE_READ,
|
|
||||||
CHUNK_TABLE_WRITE,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct chunk_table {
|
struct chunk_table {
|
||||||
enum chunk_table_mode tab_mode;
|
enum ec3_cluster_size tab_cluster_size;
|
||||||
unsigned int tab_cluster_size;
|
|
||||||
b_btree tab_cache;
|
b_btree tab_cache;
|
||||||
|
|
||||||
union {
|
struct ec3_tag_ioctx *tab_ctab;
|
||||||
struct {
|
struct ec3_tag_ioctx *tab_cdat;
|
||||||
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;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern enum ec3_status chunk_table_init_read(
|
extern enum ec3_status chunk_table_init(
|
||||||
struct ec3_tag_reader *ctab,
|
struct ec3_tag_ioctx *ctab,
|
||||||
struct ec3_tag_reader *cdat,
|
struct ec3_tag_ioctx *cdat,
|
||||||
size_t cluster_size,
|
enum ec3_cluster_size 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,
|
|
||||||
struct chunk_table *tab);
|
struct chunk_table *tab);
|
||||||
extern void chunk_table_finish(struct chunk_table *tab);
|
extern void chunk_table_finish(struct chunk_table *tab);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user