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.
135 lines
3.2 KiB
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;
|
|
}
|
|
|