You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ffdb/hash_index.c

135 lines
3.2 KiB
C

#include "hash_index.h"
// Submodules
#include "collections/array.h"
#include "json/json.h"
#include "json/layout.h"
#include "sha256/sha256.h"
// Stdlib
#include <stdlib.h>
#include <stddef.h>
struct hash_index_entry
{
char* key;
int val;
};
extern struct json_field_type hash_index_entry_type;
#define OBJ_TYPE struct hash_index_entry
static struct json_object_field hash_index_entry_layout[] = {
JSON_FIELD_STRING( key, true ),
JSON_FIELD_INTEGER( val, true ),
//{ "key", offsetof( struct hash_index_entry, key ), true, &json_field_string },
//{ "val", offsetof( struct hash_index_entry, value ), true, &json_field_integer },
JSON_FIELD_END
};
#undef OBJ_TYPE
static void hash_index_entry_free( struct hash_index_entry* e )
{
if( !e ) { return; }
free(e->key);
free(e);
}
JSON_FIELD_TYPE_OBJECT_LAYOUT_WITH_DEFAULTS( hash_index_entry );
struct hash_index
{
struct {
struct hash_index_entry** items;
int count;
} entries;
};
#define OBJ_TYPE struct hash_index
static struct json_object_field hash_index_layout[] = {
JSON_FIELD_ARRAY_OF_TYPE( entries, true, hash_index_entry_type ),
//{ "entries", offsetof( struct hash_index, entries ), true, &json_field_array_of, &hash_index_entry_type },
JSON_FIELD_END,
};
#undef OBJ_TYPE
bool hash_index_set( const char* index, const char* key, int value )
{
char hash[65] = "";
sha256_easy_hash_hex( key, strlen(key), hash );
hash[5] = '\0';
char filename[512];
snprintf( filename, 512, "%s/%s.json", index, hash );
struct hash_index hi;
memset( &hi, 0, sizeof(hi) );
json_read_object_layout_from_file( filename, hash_index_layout, &hi );
struct hash_index_entry new_entry = {
.key = (char*)key,
.val = value,
};
// Overwrite existing entries
for( int i = 0; i < hi.entries.count; ++i ) {
struct hash_index_entry* entry = hi.entries.items[i];
printf( "\tentry[%d] = { .key = %s, .val = %d }\n", i, entry->key, entry->val );
if( 0 == strcmp( entry->key, key ) ) {
entry->val = value;
goto exists;
}
}
printf( "appending\n" );
struct hash_index_entry* ptr = &new_entry;
array_append( &hi.entries, sizeof(ptr), &ptr );
exists:
json_write_object_layout_to_file( filename, "\t", hash_index_layout, &hi );
for( int i = 0; i < hi.entries.count-1; ++i ) {
struct hash_index_entry* entry = hi.entries.items[i];
free(entry->key);
free(entry);
}
}
bool hash_index_get( const char* index, const char* key, int* value )
{
char hash[65] = "";
sha256_easy_hash_hex( key, strlen(key), hash );
hash[5] = '\0';
char filename[512];
snprintf( filename, 512, "%s/%s.json", index, hash );
struct hash_index hi;
memset( &hi, 0, sizeof(hi) );
if( !json_read_object_layout_from_file( filename, hash_index_layout, &hi ) ) {
return false;
}
/*
for( int i = 0; i < hi.entries.count; ++i ) {
struct hash_index_entry* entry = hi.entries.items[i];
printf( "\tentry[%d] = %p{ .uri = %s, .account_id = %d }\n", i, entry, entry->key, entry->val );
}
//*/
bool found = false;
*value = -1;
for( int i = 0; i < hi.entries.count; ++i ) {
struct hash_index_entry* entry = hi.entries.items[i];
if( 0 == strcmp(entry->key,key) ) {
*value = entry->val;
found = true;
}
free(entry->key);
free(entry);
}
free(hi.entries.items);
return found;
}