perf(io): avoid reopening v2 files during indexing
This commit is contained in:
77
src/ikv.c
77
src/ikv.c
@@ -225,6 +225,29 @@ static bool read_file_prefix(const char *path, uint8_t *prefix, size_t prefix_ca
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool open_file_with_prefix(const char *path, FILE **out_file, uint8_t *prefix, size_t prefix_capacity, size_t *out_size)
|
||||
{
|
||||
FILE *file = NULL;
|
||||
size_t size = 0u;
|
||||
|
||||
if (!path || !out_file || !prefix || prefix_capacity == 0u || !out_size)
|
||||
return false;
|
||||
|
||||
*out_file = NULL;
|
||||
*out_size = 0u;
|
||||
prefix[0] = 0u;
|
||||
|
||||
file = IKV_FOPEN(path, "rb");
|
||||
if (!file)
|
||||
return false;
|
||||
|
||||
size = IKV_FREAD(prefix, 1u, prefix_capacity - 1u, file);
|
||||
prefix[size] = 0u;
|
||||
*out_file = file;
|
||||
*out_size = size;
|
||||
return true;
|
||||
}
|
||||
|
||||
static char *ikv_strdup(const char *s)
|
||||
{
|
||||
if (!s)
|
||||
@@ -2279,16 +2302,38 @@ ikv_node_t *ikv_parse_string_version(const char *src, ikv_version_t version)
|
||||
|
||||
ikv_node_t *ikv_parse_file(const char *path)
|
||||
{
|
||||
FILE *file = NULL;
|
||||
uint8_t prefix[16] = {0};
|
||||
size_t prefix_size = 0u;
|
||||
ikv_version_t version = IKV_VERSION_UNKNOWN;
|
||||
|
||||
if (!read_file_prefix(path, prefix, sizeof(prefix), &prefix_size))
|
||||
if (!open_file_with_prefix(path, &file, prefix, sizeof(prefix), &prefix_size))
|
||||
return NULL;
|
||||
|
||||
version = ikv_detect_binary_version(prefix, prefix_size);
|
||||
if (version != IKV_VERSION_UNKNOWN)
|
||||
{
|
||||
ikv_node_t *root = NULL;
|
||||
|
||||
if (version == IKV_VERSION_2)
|
||||
{
|
||||
if (IKV_FSEEK(file, 0L, SEEK_SET) != 0)
|
||||
{
|
||||
IKV_FCLOSE(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
root = ikv2_parse_binary_stream(file);
|
||||
if (!root)
|
||||
IKV_FCLOSE(file);
|
||||
return root;
|
||||
}
|
||||
|
||||
IKV_FCLOSE(file);
|
||||
return ikvb_parse_file_version(path, version);
|
||||
}
|
||||
|
||||
IKV_FCLOSE(file);
|
||||
|
||||
version = ikv_detect_text_version((const char *)prefix);
|
||||
if (version == IKV_VERSION_UNKNOWN)
|
||||
@@ -2355,10 +2400,38 @@ ikv_node_t *ikvb_parse_memory_version(const void *data, size_t size, ikv_version
|
||||
|
||||
ikv_node_t *ikvb_parse_file(const char *path)
|
||||
{
|
||||
FILE *file = NULL;
|
||||
uint8_t prefix[16] = {0};
|
||||
size_t prefix_size = 0u;
|
||||
ikv_version_t version = ikv_detect_file_version(path, true);
|
||||
|
||||
if (version == IKV_VERSION_UNKNOWN)
|
||||
if (!open_file_with_prefix(path, &file, prefix, sizeof(prefix), &prefix_size))
|
||||
return NULL;
|
||||
|
||||
version = ikv_detect_binary_version(prefix, prefix_size);
|
||||
if (version == IKV_VERSION_UNKNOWN)
|
||||
{
|
||||
IKV_FCLOSE(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (version == IKV_VERSION_2)
|
||||
{
|
||||
ikv_node_t *root = NULL;
|
||||
|
||||
if (IKV_FSEEK(file, 0L, SEEK_SET) != 0)
|
||||
{
|
||||
IKV_FCLOSE(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
root = ikv2_parse_binary_stream(file);
|
||||
if (!root)
|
||||
IKV_FCLOSE(file);
|
||||
return root;
|
||||
}
|
||||
|
||||
IKV_FCLOSE(file);
|
||||
return ikvb_parse_file_version(path, version);
|
||||
}
|
||||
|
||||
|
||||
@@ -774,9 +774,8 @@ static bool ikv2_write_binary_file(const char *path, const ikv_node_t *root)
|
||||
return ok;
|
||||
}
|
||||
|
||||
static ikv_node_t *ikv2_parse_binary_file(const char *path)
|
||||
ikv_node_t *ikv2_parse_binary_stream(FILE *file)
|
||||
{
|
||||
FILE *file = NULL;
|
||||
uint8_t magic[4];
|
||||
uint8_t kind = 0u;
|
||||
uint32_t version = 0u;
|
||||
@@ -788,10 +787,6 @@ static ikv_node_t *ikv2_parse_binary_file(const char *path)
|
||||
long file_size_long = 0;
|
||||
size_t file_size = 0u;
|
||||
|
||||
if (!path)
|
||||
return NULL;
|
||||
|
||||
file = IKV_FOPEN(path, "rb");
|
||||
if (!file)
|
||||
return NULL;
|
||||
|
||||
@@ -919,6 +914,24 @@ static ikv_node_t *ikv2_parse_binary_file(const char *path)
|
||||
return root;
|
||||
}
|
||||
|
||||
static ikv_node_t *ikv2_parse_binary_file(const char *path)
|
||||
{
|
||||
FILE *file = NULL;
|
||||
ikv_node_t *root = NULL;
|
||||
|
||||
if (!path)
|
||||
return NULL;
|
||||
|
||||
file = IKV_FOPEN(path, "rb");
|
||||
if (!file)
|
||||
return NULL;
|
||||
|
||||
root = ikv2_parse_binary_stream(file);
|
||||
if (!root)
|
||||
IKV_FCLOSE(file);
|
||||
return root;
|
||||
}
|
||||
|
||||
static ikv_node_t *ikv2_parse_binary_memory(const void *data, size_t size)
|
||||
{
|
||||
uint8_t *buffer = NULL;
|
||||
|
||||
@@ -3,3 +3,5 @@
|
||||
#include "../internal/ikv_internal.h"
|
||||
|
||||
extern const ikv_loader_t ikv_loader_v2;
|
||||
|
||||
ikv_node_t *ikv2_parse_binary_stream(FILE *file);
|
||||
|
||||
Reference in New Issue
Block a user