database_flatfile: single-file storage with sparse index
Some checks failed
CI Code / Check spelling (pull_request) Successful in 20s
CI Code / Check coding style (pull_request) Failing after 33s
CI Code / Code Coverage (pull_request) Successful in 4m50s
CI Code / Linux (debian) (pull_request) Successful in 6m14s
CI Code / Linux (ubuntu) (pull_request) Successful in 6m23s
CI Code / Linux (arch) (pull_request) Successful in 6m29s
Some checks failed
CI Code / Check spelling (pull_request) Successful in 20s
CI Code / Check coding style (pull_request) Failing after 33s
CI Code / Code Coverage (pull_request) Successful in 4m50s
CI Code / Linux (debian) (pull_request) Successful in 6m14s
CI Code / Linux (ubuntu) (pull_request) Successful in 6m23s
CI Code / Linux (arch) (pull_request) Successful in 6m29s
Replace per-contact directory structure with a single flat file per contact. Each file uses pipe-delimited records with a sparse byte-offset index that is rebuilt on demand and cached in memory. - Rewrite _ff_write_record / _ff_read_records for single-file format - Add sparse index (every Nth record) for O(log N) seek on history read - Cursor-based pagination: _ff_get_previous_chat uses saved byte offset - LMC corrections applied in-place during read (_ff_apply_lmc) - Newline escaping (\n) in message bodies for line-based storage - Simplify verify: parse + timestamp order + LMC reference check - Update parser helpers for new field layout
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "database.h"
|
||||
#include "xmpp/xmpp.h"
|
||||
@@ -60,8 +61,44 @@ typedef struct
|
||||
char* from_jid;
|
||||
char* from_resource;
|
||||
char* message;
|
||||
off_t file_offset;
|
||||
} ff_parsed_line_t;
|
||||
|
||||
// --- Sparse index for single-file lookup ---
|
||||
|
||||
#define FF_INDEX_STEP 500
|
||||
|
||||
typedef struct
|
||||
{
|
||||
off_t byte_offset;
|
||||
gint64 timestamp_epoch;
|
||||
} ff_index_entry_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
time_t mtime;
|
||||
off_t size;
|
||||
ino_t inode;
|
||||
} ff_file_stamp_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char* filepath;
|
||||
ff_index_entry_t* entries;
|
||||
size_t n_entries;
|
||||
size_t cap_entries;
|
||||
size_t total_lines;
|
||||
ff_file_stamp_t stamp;
|
||||
off_t cursor_offset;
|
||||
int bom_len;
|
||||
} ff_contact_state_t;
|
||||
|
||||
// State management
|
||||
ff_contact_state_t* ff_state_new(const char* filepath);
|
||||
void ff_state_free(ff_contact_state_t* state);
|
||||
gboolean ff_state_ensure_fresh(ff_contact_state_t* state);
|
||||
off_t ff_state_offset_for_time(ff_contact_state_t* state, const char* iso_time);
|
||||
|
||||
// --- Type conversion helpers ---
|
||||
|
||||
const char* ff_get_message_type_str(prof_msg_type_t type);
|
||||
@@ -73,7 +110,7 @@ prof_enc_t ff_get_message_enc_type(const char* const encstr);
|
||||
|
||||
char* ff_jid_to_dir(const char* jid);
|
||||
char* ff_get_contact_dir(const char* contact_barejid);
|
||||
char* ff_get_log_path(const char* contact_barejid, GDateTime* dt);
|
||||
char* ff_get_log_path(const char* contact_barejid);
|
||||
gboolean ff_ensure_dir(const char* path);
|
||||
|
||||
// --- Escape / unescape ---
|
||||
|
||||
Reference in New Issue
Block a user