From a0cae573354acbe194b37b6fbb0fe8a4aa83726c Mon Sep 17 00:00:00 2001 From: Vivien Kraus Date: Wed, 10 May 2023 09:08:27 +0200 Subject: Remove the disfluid_db code. --- src/libdisfluid/Makefile.am | 2 - src/libdisfluid/disfluid-db.h | 1072 ---------------------------------- src/libdisfluid/disfluid-tests.h | 157 ----- src/libdisfluid/disfluid-trie-node.h | 386 ------------ 4 files changed, 1617 deletions(-) delete mode 100644 src/libdisfluid/disfluid-db.h delete mode 100644 src/libdisfluid/disfluid-trie-node.h diff --git a/src/libdisfluid/Makefile.am b/src/libdisfluid/Makefile.am index f230a3d..33000e8 100644 --- a/src/libdisfluid/Makefile.am +++ b/src/libdisfluid/Makefile.am @@ -7,11 +7,9 @@ lib_LTLIBRARIES += %D%/libdisfluid.la %D%/disfluid-cache-group.h \ %D%/disfluid-cache-entry-key.h \ %D%/disfluid-cache-entry-hash.h \ - %D%/disfluid-db.h \ %D%/disfluid-init.h \ %D%/disfluid-tests.h \ %D%/disfluid-trie.h \ - %D%/disfluid-trie-node.h \ %D%/disfluid-ui.h \ %D%/disfluid-version.h \ %D%/main.c diff --git a/src/libdisfluid/disfluid-db.h b/src/libdisfluid/disfluid-db.h deleted file mode 100644 index 3fec521..0000000 --- a/src/libdisfluid/disfluid-db.h +++ /dev/null @@ -1,1072 +0,0 @@ -#ifndef DISFLUID_DISFLUID_DB_INCLUDED -# define DISFLUID_DISFLUID_DB_INCLUDED - -# include -# include "string-desc.h" - -MAYBE_UNUSED static int -db_mark_leaf (const char *db_root, const string_desc_t * id); - -MAYBE_UNUSED static int -db_read (const char *db_root, const string_desc_t * id, string_desc_t * data); - -MAYBE_UNUSED static int -db_write (const char *db_root, string_desc_t * id, - const string_desc_t * data); - -MAYBE_UNUSED static int db_unmark (const char *db_root); - -/* WARNING: Between the call to db_unmark and db_collect, the database - must have been fully traced at least once, including the unfinished - transactions. */ -MAYBE_UNUSED static int db_collect (const char *db_root); - -MAYBE_UNUSED static int db_check (void); - -# include -# include -# include -# include -# include "safe-alloc.h" -# include -# include -# include - -# ifndef STREQ -# define STREQ(a, b) (strcmp ((a), (b)) != 0) -# endif/* not STREQ */ - -static FILE * -open_file_for_reading (const char *filename, const char *trash_filename) -{ - assert (filename != NULL); - assert (trash_filename != NULL); - FILE *f = fopen (filename, "rb"); - if (f == NULL) - { - if (rename (trash_filename, filename) == 0) - { - f = fopen (filename, "rb"); - } - } - return f; -} - -static int -db_file_name (const char *db_root, size_t id_length, const char *id, - char **dirname, char **filename, char **temp_filename, - char **trash_filename) -{ - int error = 0; - *dirname = NULL; - *filename = NULL; - *temp_filename = NULL; - *trash_filename = NULL; - gnutls_datum_t id_datum = { - .data = (char *) id, - .size = id_length - }; - gnutls_datum_t hex_id = { - .data = NULL, - .size = 0 - }; - if (gnutls_hex_encode2 (&id_datum, &hex_id) < 0) - { - error = -2; - goto cleanup; - } - assert (hex_id.size >= 2); - const size_t dirname_length = strlen (db_root) + strlen ("/") + 2; - const size_t filename_length = - dirname_length + strlen ("/") + hex_id.size - 2; - const size_t temp_filename_length = filename_length + strlen ("-XXXXXX"); - const size_t trash_filename_length = filename_length + strlen ("-trash"); - if (ALLOC_N (*filename, filename_length + 1) < 0 - || ALLOC_N (*temp_filename, temp_filename_length + 1) < 0 - || ALLOC_N (*dirname, dirname_length + 1) < 0 - || ALLOC_N (*trash_filename, trash_filename_length + 1) < 0) - { - error = -2; - goto cleanup; - } - strcpy (*dirname, db_root); - strcat (*dirname, "/"); - strncat (*dirname, hex_id.data, 2); - strcpy (*filename, *dirname); - strcat (*filename, "/"); - strncat (*filename, hex_id.data + 2, hex_id.size - 2); - strcpy (*temp_filename, *filename); - strcat (*temp_filename, "-XXXXXX"); - strcpy (*trash_filename, *filename); - strcat (*trash_filename, "-trash"); - mkdir (db_root, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); - mkdir (*dirname, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); -cleanup: - FREE (hex_id.data); - if (error != 0) - { - FREE (*dirname); - FREE (*filename); - FREE (*temp_filename); - FREE (*trash_filename); - } - else - { - assert (*dirname != NULL); - assert (*filename != NULL); - assert (*temp_filename != NULL); - assert (*trash_filename != NULL); - } - return error; -} - -static int -db_mark_leaf (const char *db_root, const string_desc_t * id) -{ - int error = 0; - char *dirname = NULL; - char *filename = NULL; - char *trash_filename = NULL; - char *temp_filename = NULL; - if (db_file_name - (db_root, id->_nbytes, id->_data, &dirname, &filename, &temp_filename, - &trash_filename) < 0) - { - error = -2; - goto cleanup; - } - FILE *f = open_file_for_reading (filename, trash_filename); -close: - if (f != NULL) - { - fclose (f); - } -cleanup: - FREE (dirname); - FREE (filename); - FREE (temp_filename); - FREE (trash_filename); - return error; -} - -static int -db_read (const char *db_root, const string_desc_t * id, string_desc_t * data) -{ - int error = 0; - assert (data->_nbytes == 0); - assert (data->_data == NULL); - char *dirname = NULL; - char *filename = NULL; - char *trash_filename = NULL; - char *temp_filename = NULL; - if (db_file_name - (db_root, id->_nbytes, id->_data, &dirname, &filename, &temp_filename, - &trash_filename) < 0) - { - error = -2; - goto cleanup; - } - FILE *f = open_file_for_reading (filename, trash_filename); - if (f == NULL) - { - error = -1; - goto close; - } - if (fseeko (f, 0, SEEK_END) != 0) - { - error = -1; - goto close; - } - const size_t length = ftello (f); - if (fseeko (f, 0, SEEK_SET) != 0) - { - error = -1; - goto close; - } - if (ALLOC_N (data->_data, length) < 0) - { - error = -2; - goto close; - } - data->_nbytes = length; - size_t n_read = fread (data->_data, 1, length, f); - if (n_read != length || ferror (f)) - { - error = -1; - goto close; - } -close: - if (f != NULL) - { - fclose (f); - } -cleanup: - FREE (dirname); - FREE (filename); - FREE (temp_filename); - FREE (trash_filename); - if (error != 0) - { - FREE (data->_data); - data->_nbytes = 0; - } - return error; -} - -static FILE * -open_file_for_writing (const char *filename, const char *dirname, - const char *db_root) -{ - assert (filename != NULL); - assert (dirname != NULL); - assert (db_root != NULL); - FILE *f = fopen (filename, "wb"); - if (f == NULL) - { - /* Try mkdir and retry. */ - int error = - mkdir (dirname, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); - if (error < 0) - { - /* Try also mkdir the root */ - error = - mkdir (db_root, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); - if (error == 0) - { - error = - mkdir (dirname, - S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); - } - if (error == 0) - { - return fopen (filename, "wb"); - } - } - return fopen (filename, "wb"); - } - return f; -} - -static int -db_write (const char *db_root, string_desc_t * id, const string_desc_t * data) -{ - assert (id->_nbytes == 0); - assert (id->_data == NULL); - uint8_t digest[32]; - const gnutls_digest_algorithm_t algo = GNUTLS_DIG_SHA256; - assert (gnutls_hash_get_len (algo) == sizeof (digest)); - int error = - gnutls_hash_fast (GNUTLS_DIG_SHA256, data->_data, data->_nbytes, digest); - char *dirname = NULL; - char *filename = NULL; - char *temp_filename = NULL; - char *trash_filename = NULL; - if (error == 0) - { - if (ALLOC_N (id->_data, sizeof (digest)) < 0) - { - error = -2; - goto cleanup; - } - id->_nbytes = sizeof (digest); - memcpy (id->_data, digest, sizeof (digest)); - } - if (db_file_name - (db_root, id->_nbytes, id->_data, &dirname, &filename, &temp_filename, - &trash_filename) < 0) - { - error = -2; - goto cleanup; - } - FILE *f = NULL; - bool temp_filename_unique = false; - while (true) - { - f = open_file_for_reading (filename, trash_filename); - if (f == NULL) - { - if (!temp_filename_unique) - { - int tmpfd = mkstemp (temp_filename); - if (tmpfd == -1) - { - error = -1; - goto cleanup; - } - close (tmpfd); - } - f = open_file_for_writing (temp_filename, dirname, db_root); - if (f == NULL) - { - error = -1; - goto close; - } - size_t n_written = fwrite (data->_data, 1, data->_nbytes, f); - if (n_written < data->_nbytes) - { - error = -1; - goto close; - } - if (fflush (f) != 0) - { - error = -1; - goto close; - } - if (rename (temp_filename, filename) < 0) - { - /* The temporary file has been garbage collected before we - could rename it :( Retry */ - continue; - } - } - else - { - break; - } - } -close: - if (error != 0) - { - remove (temp_filename); - FREE (id->_data); - id->_nbytes = 0; - } - if (f != NULL) - { - fclose (f); - /* GCC analyzer still thinks f is allocated here, but no. */ - } -cleanup: - FREE (dirname); - FREE (filename); - FREE (temp_filename); - FREE (trash_filename); - return error; -} - -static int -db_unmark_entry (const char *dirname, const char *basename) -{ - if (!STREQ (basename, ".") && !STREQ (basename, "..") - && strstr (basename, "-") == NULL) - { - /* This a real entry that we need to unmark. */ - int error = 0; - char *abs_filename = NULL; - char *trash_filename = NULL; - if (ALLOC_N - (abs_filename, - strlen (dirname) + strlen ("/") + strlen (basename) + 1) < 0) - { - error = -2; - goto cleanup; - } - strcpy (abs_filename, dirname); - strcat (abs_filename, "/"); - strcat (abs_filename, basename); - if (ALLOC_N - (trash_filename, - strlen (dirname) + strlen ("/") + strlen (basename) + - strlen ("-trash") + 1) < 0) - { - error = -2; - goto cleanup; - } - strcpy (trash_filename, abs_filename); - strcat (trash_filename, "-trash"); - error = rename (abs_filename, trash_filename); - if (error != 0) - { - error = -1; - goto cleanup; - } - cleanup: - FREE (trash_filename); - FREE (abs_filename); - return error; - } - return 0; -} - -static int -db_unmark_group_entries (const char *dirname, DIR * dir) -{ - int error = 0; - struct dirent *entry; - while ((entry = readdir (dir)) != NULL) - { - if (!STREQ (entry->d_name, ".") && !STREQ (entry->d_name, "..")) - { - int this_error = db_unmark_entry (dirname, entry->d_name); - if (this_error < 0) - { - error = -1; - } - } - } - return error; -} - -static int -db_unmark_group (const char *dirname, const char *basename) -{ - char *absolute_name = NULL; - int error = 0; - if (ALLOC_N - (absolute_name, - strlen (dirname) + strlen ("/") + strlen (basename) + 1) < 0) - { - error = -2; - goto cleanup; - } - strcpy (absolute_name, dirname); - strcat (absolute_name, "/"); - strcat (absolute_name, basename); - DIR *group = opendir (absolute_name); - if (group == NULL) - { - error = -1; - goto close; - } - error = db_unmark_group_entries (absolute_name, group); -close: - if (group != NULL) - { - closedir (group); - } -cleanup: - FREE (absolute_name); - return error; -} - -static int -db_unmark_root (const char *root_filename, DIR * root) -{ - int error = 0; - struct dirent *entry; - while ((entry = readdir (root)) != NULL) - { - if (!STREQ (entry->d_name, ".") && !STREQ (entry->d_name, "..")) - { - int this_error = db_unmark_group (root_filename, entry->d_name); - if (this_error < 0) - { - error = -1; - } - } - } - return error; -} - -static int -db_unmark (const char *db_root) -{ - /* Append the -trash suffix to all files. */ - int error = 0; - DIR *root = opendir (db_root); - if (root == NULL) - { - error = -1; - goto cleanup; - } - error = db_unmark_root (db_root, root); -cleanup: - if (root != NULL) - { - closedir (root); - } - return error; -} - -static int -db_collect_entry (const char *dirname, const char *basename) -{ - if (!STREQ (basename, ".") && !STREQ (basename, "..") - && strstr (basename, "-") != NULL) - { - /* This a real entry that we need to collect. */ - int error = 0; - char *abs_filename = NULL; - if (ALLOC_N - (abs_filename, - strlen (dirname) + strlen ("/") + strlen (basename) + 1) < 0) - { - error = -2; - goto cleanup; - } - strcpy (abs_filename, dirname); - strcat (abs_filename, "/"); - strcat (abs_filename, basename); - error = remove (abs_filename); - if (error != 0) - { - error = -1; - goto cleanup; - } - cleanup: - FREE (abs_filename); - return error; - } - return 0; -} - -static int -db_collect_group_entries (const char *dirname, DIR * dir) -{ - int error = 0; - struct dirent *entry; - while ((entry = readdir (dir)) != NULL) - { - if (!STREQ (entry->d_name, ".") && !STREQ (entry->d_name, "..")) - { - int this_error = db_collect_entry (dirname, entry->d_name); - if (this_error < 0) - { - error = -1; - } - } - } - return error; -} - -static int -db_collect_group (const char *dirname, const char *basename) -{ - char *absolute_name = NULL; - int error = 0; - if (ALLOC_N - (absolute_name, - strlen (dirname) + strlen ("/") + strlen (basename) + 1) < 0) - { - error = -2; - goto cleanup; - } - strcpy (absolute_name, dirname); - strcat (absolute_name, "/"); - strcat (absolute_name, basename); - DIR *group = opendir (absolute_name); - if (group == NULL) - { - error = -1; - goto close; - } - error = db_collect_group_entries (absolute_name, group); -close: - if (group != NULL) - { - closedir (group); - } -cleanup: - FREE (absolute_name); - return error; -} - -static int -db_collect_root (const char *root_filename, DIR * root) -{ - int error = 0; - struct dirent *entry; - while ((entry = readdir (root)) != NULL) - { - if (!STREQ (entry->d_name, ".") && !STREQ (entry->d_name, "..")) - { - int this_error = db_collect_group (root_filename, entry->d_name); - if (this_error < 0) - { - error = -1; - } - } - } - return error; -} - -static int -db_collect (const char *db_root) -{ - /* Delete all files with a dash in name. */ - int error = 0; - DIR *root = opendir (db_root); - if (root == NULL) - { - error = -1; - goto cleanup; - } - error = db_collect_root (db_root, root); -cleanup: - if (root != NULL) - { - closedir (root); - } - return error; -} - -static int -db_read_example_addressbook (const char *db_root, const string_desc_t * id, - size_t *n_people, string_desc_t ** records) -{ - /* The example addressbook is a data structure where the first 8 - bytes are the number of people, big-endian, then each person has - a record that consists of: the size of the identifier, on 4 - bytes, then the identifier. */ - string_desc_t data = { 0 }; - *n_people = 0; - *records = NULL; - int error = db_read (db_root, id, &data); - if (error != 0) - { - goto cleanup; - } - for (size_t i = 0; i < 8 && i < data._nbytes; i++) - { - *n_people *= 256; - *n_people += (uint8_t) (data._data[i]); - } - if (ALLOC_N (*records, *n_people) < 0) - { - error = -2; - goto cleanup; - } - size_t offset = 8; - for (size_t i = 0; i < *n_people; i++) - { - unsigned id_size = 0; - for (size_t j = 0; j < 4; j++, offset++) - { - id_size *= 256; - id_size += (uint8_t) (data._data[offset]); - } - (*records)[i]._nbytes = id_size; - if (ALLOC_N ((*records)[i]._data, id_size) < 0) - { - error = -2; - for (size_t clean = 0; clean < i; clean++) - { - FREE ((*records)[i]._data); - } - goto cleanup; - } - memcpy ((*records)[i]._data, data._data + offset, id_size); - offset += id_size; - } -cleanup: - FREE (data._data); - if (error != 0) - { - FREE (*records); - } - return error; -} - -static int -db_read_example_person (const char *db_root, - const string_desc_t * id, - string_desc_t * name, string_desc_t * email) -{ - /* An example person file is: 4 bytes for the name id size, the name - id, 4 bytes for the email id size, the email id. */ - name->_nbytes = 0; - name->_data = NULL; - email->_nbytes = 0; - email->_data = NULL; - string_desc_t data = { 0 }; - int error = db_read (db_root, id, &data); - if (error != 0) - { - goto cleanup; - } - unsigned name_id_size = 0; - unsigned email_id_size = 0; - for (size_t i = 0; i < 4; i++) - { - name_id_size *= 256; - name_id_size += (uint8_t) (data._data[i]); - } - if (name_id_size + 8 > data._nbytes) - { - error = -1; - goto cleanup; - } - for (size_t i = 0; i < 4; i++) - { - email_id_size *= 256; - email_id_size += (uint8_t) (data._data[4 + name_id_size + i]); - } - if (ALLOC_N (name->_data, name_id_size) < 0 - || ALLOC_N (email->_data, email_id_size) < 0) - { - error = -2; - goto cleanup; - } - memcpy (name->_data, data._data + 4, name_id_size); - memcpy (email->_data, data._data + 4 + name_id_size + 4, email_id_size); - name->_nbytes = name_id_size; - email->_nbytes = email_id_size; -cleanup: - FREE (data._data); - if (error != 0) - { - name->_nbytes = 0; - email->_nbytes = 0; - FREE (name->_data); - FREE (email->_data); - } - return error; -} - -static int -db_mark_example_person (const char *db_root, const string_desc_t * id) -{ - string_desc_t name = { 0 }, email = { 0 }; - int error = db_read_example_person (db_root, id, &name, &email); - if (error != 0) - { - goto cleanup; - } - int name_mark_error = db_mark_leaf (db_root, &name); - int email_mark_error = db_mark_leaf (db_root, &email); - error = error || name_mark_error || email_mark_error; -cleanup: - FREE (name._data); - FREE (email._data); - return error; -} - -static int -db_mark_example_addressbook (const char *db_root, const string_desc_t * id) -{ - size_t n_people = 0; - string_desc_t *people = NULL; - int error = db_read_example_addressbook (db_root, id, &n_people, &people); - if (error != 0) - { - goto cleanup; - } - for (size_t i = 0; i < n_people; i++) - { - int this_error = db_mark_example_person (db_root, &(people[i])); - error = error || this_error; - } -cleanup: - if (people != NULL) - { - for (size_t i = 0; i < n_people; i++) - { - FREE (people[i]._data); - } - } - FREE (people); - return error; -} - -static int -db_write_example_person (const char *db_root, string_desc_t * id, - const string_desc_t * name_id, - const string_desc_t * email_id) -{ - int error = 0; - char *data = NULL; - if (ALLOC_N (data, 4 + name_id->_nbytes + 4 + email_id->_nbytes) < 0) - { - error = -2; - goto cleanup; - } - size_t name_id_length = name_id->_nbytes; - size_t email_id_length = name_id->_nbytes; - for (size_t i = 4; i-- > 0;) - { - data[i] = (char) (uint8_t) (name_id_length % 256); - name_id_length /= 256; - } - memcpy (data + 4, name_id->_data, name_id->_nbytes); - for (size_t i = 4; i-- > 0;) - { - data[4 + name_id->_nbytes + i] = - (char) (uint8_t) (email_id_length % 256); - email_id_length /= 256; - } - memcpy (data + 4 + name_id->_nbytes + 4, email_id->_data, - email_id->_nbytes); - string_desc_t data_desc = {._nbytes = - 4 + name_id->_nbytes + 4 + email_id->_nbytes,._data = data - }; - error = db_write (db_root, id, &data_desc); -cleanup: - FREE (data); - return error; -} - -static int -db_write_example_addressbook (const char *db_root, string_desc_t * id, - size_t n_people, const string_desc_t ** people) -{ - int error = 0; - char *data = NULL; - size_t data_required = 8; - for (size_t i = 0; i < n_people; i++) - { - data_required += 4 + people[i]->_nbytes; - } - if (ALLOC_N (data, data_required) < 0) - { - error = -2; - goto cleanup; - } - size_t n_people_copy = n_people; - for (size_t i = 8; i-- > 0;) - { - data[i] = (char) (uint8_t) (n_people_copy % 256); - n_people_copy /= 256; - } - size_t offset = 8; - for (size_t i = 0; i < n_people; i++) - { - unsigned person_id_size = people[i]->_nbytes; - for (size_t i = 4; i-- > 0;) - { - data[offset + i] += (char) (uint8_t) (person_id_size % 256); - person_id_size /= 256; - } - offset += 4; - memcpy (data + offset, people[i]->_data, people[i]->_nbytes); - offset += people[i]->_nbytes; - } - string_desc_t data_desc = {._nbytes = data_required,._data = data }; - error = db_write (db_root, id, &data_desc); -cleanup: - FREE (data); - return error; -} - -static int -db_write_text (const char *db_root, string_desc_t * id, const char *data) -{ - string_desc_t bytes = {._nbytes = strlen (data),._data = (char *) data }; - return db_write (db_root, id, &bytes); -} - -static int -db_check (void) -{ - int error = 0; - char *dir; - string_desc_t lit_alice = {._nbytes = 0,._data = 0 }; - string_desc_t lit_bob = {._nbytes = 0,._data = 0 }; - string_desc_t lit_alice_at_example_dot_com = {._nbytes = 0,._data = 0 }; - string_desc_t lit_alice_at_example_dot_net = {._nbytes = 0,._data = 0 }; - string_desc_t lit_bob_at_example_dot_com = {._nbytes = 0,._data = 0 }; - string_desc_t alice_1_id = {._nbytes = 0,._data = 0 }; - string_desc_t alice_2_id = {._nbytes = 0,._data = 0 }; - string_desc_t bob_id = {._nbytes = 0,._data = 0 }; - string_desc_t v1_id = {._nbytes = 0,._data = 0 }; - string_desc_t v2_id = {._nbytes = 0,._data = 0 }; - string_desc_t check_alice_email_1 = {._nbytes = 0,._data = 0 }; - string_desc_t check_alice_email_2 = {._nbytes = 0,._data = 0 }; - string_desc_t recheck_alice_email_1 = {._nbytes = 0,._data = 0 }; - string_desc_t recheck_alice_email_2 = {._nbytes = 0,._data = 0 }; - if (ALLOC_N (dir, strlen ("/tmp/check-disfluid-db-XXXXXX") + 1) < 0) - { - error = -2; - goto cleanup; - } - strcpy (dir, "/tmp/check-disfluid-db-XXXXXX"); - if (mkdtemp (dir) == NULL) - { - error = -3; - goto cleanup; - } - static const char *_lit_alice = "alice"; - static const char *_lit_bob = "bob"; - static const char *_lit_alice_1 = "alice@example.com"; - static const char *_lit_alice_2 = "alice@example.net"; - static const char *_lit_bob_email = "bob@example.com"; - error = db_write_text (dir, &lit_alice, _lit_alice); - if (error != 0) - { - error = -4; - goto cleanup; - } - error = db_write_text (dir, &lit_alice_at_example_dot_com, _lit_alice_1); - if (error != 0) - { - error = -5; - goto cleanup; - } - error = db_write_example_person (dir, &alice_1_id, &lit_alice, - &lit_alice_at_example_dot_com); - if (error != 0) - { - error = -6; - goto cleanup; - } - error = db_write_text (dir, &lit_alice_at_example_dot_net, _lit_alice_2); - if (error != 0) - { - error = -7; - goto cleanup; - } - error = db_write_example_person (dir, &alice_2_id, &lit_alice, - &lit_alice_at_example_dot_net); - if (error != 0) - { - error = -8; - goto cleanup; - } - error = db_write_text (dir, &lit_bob, _lit_bob); - if (error != 0) - { - error = -9; - goto cleanup; - } - error = db_write_text (dir, &lit_bob_at_example_dot_com, _lit_bob_email); - if (error != 0) - { - error = -10; - goto cleanup; - } - error = db_write_example_person (dir, &bob_id, &lit_bob, - &lit_bob_at_example_dot_com); - if (error != 0) - { - error = -11; - goto cleanup; - } - const string_desc_t *people_v1[] = { - &alice_1_id, &bob_id - }; - const string_desc_t *people_v2[] = { - &alice_2_id, &bob_id - }; - const size_t n_v1 = sizeof (people_v1) / sizeof (people_v1[0]); - const size_t n_v2 = sizeof (people_v2) / sizeof (people_v2[0]); - error = db_write_example_addressbook (dir, &v1_id, n_v1, people_v1); - if (error != 0) - { - error = -12; - goto cleanup; - } - error = db_write_example_addressbook (dir, &v2_id, n_v2, people_v2); - if (error != 0) - { - error = -13; - goto cleanup; - } - error = db_read (dir, &lit_alice_at_example_dot_com, &check_alice_email_1); - if (error != 0) - { - error = -14; - goto cleanup; - } - error = db_read (dir, &lit_alice_at_example_dot_net, &check_alice_email_2); - if (error != 0) - { - error = -15; - goto cleanup; - } - if (check_alice_email_1._nbytes != strlen ("alice@example.com") - || memcmp (check_alice_email_1._data, "alice@example.com", - check_alice_email_1._nbytes) != 0) - { - error = -16; - goto cleanup; - } - if (check_alice_email_2._nbytes != strlen ("alice@example.net") - || memcmp (check_alice_email_2._data, "alice@example.net", - check_alice_email_2._nbytes) != 0) - { - error = -17; - goto cleanup; - } - /* Now, collect garbage. */ - error = db_unmark (dir); - if (error != 0) - { - error = -18; - goto cleanup; - } - error = db_mark_example_addressbook (dir, &v2_id); - if (error != 0) - { - error = -19; - goto cleanup; - } - error = db_collect (dir); - if (error != 0) - { - error = -20; - goto cleanup; - } - /* alice@example.net should be readable, but not alice@example.com. */ - if (db_read (dir, &lit_alice_at_example_dot_com, &recheck_alice_email_1) == - 0) - { - error = -21; - goto cleanup; - } - error = - db_read (dir, &lit_alice_at_example_dot_net, &recheck_alice_email_2); - if (error != 0) - { - error = -22; - goto cleanup; - } - if (recheck_alice_email_2._nbytes != strlen ("alice@example.net") - || memcmp (recheck_alice_email_2._data, "alice@example.net", - recheck_alice_email_2._nbytes) != 0) - { - error = -23; - goto cleanup; - } - /* Collect everything */ - error = db_unmark (dir); - if (error != 0) - { - error = -24; - goto cleanup; - } - error = db_collect (dir); - if (error != 0) - { - error = -25; - goto cleanup; - } - for (size_t i = 0; i < 256; i++) - { - char *group_name = NULL; - if (ALLOC_N (group_name, strlen (dir) + strlen ("/") + 2 + 1) < 0) - { - error = -26; - goto cleanup_group_name; - } - strcpy (group_name, dir); - strcat (group_name, "/"); - static const char *alpha[] = { - "0", "1", "2", "3", "4", "5", "6", "7", - "8", "9", "a", "b", "c", "d", "e", "f" - }; - strcat (group_name, alpha[i / 16]); - strcat (group_name, alpha[i % 16]); - rmdir (group_name); - cleanup_group_name: - FREE (group_name); - } - rmdir (dir); -cleanup: - FREE (check_alice_email_1._data); - FREE (check_alice_email_2._data); - FREE (recheck_alice_email_1._data); - FREE (recheck_alice_email_2._data); - FREE (lit_alice._data); - FREE (lit_bob._data); - FREE (lit_alice_at_example_dot_com._data); - FREE (lit_alice_at_example_dot_net._data); - FREE (lit_bob_at_example_dot_com._data); - FREE (alice_1_id._data); - FREE (alice_2_id._data); - FREE (bob_id._data); - FREE (v1_id._data); - FREE (v2_id._data); - FREE (dir); - return error; -} - -#endif /* DISFLUID_DISFLUID_DB_INCLUDED */ diff --git a/src/libdisfluid/disfluid-tests.h b/src/libdisfluid/disfluid-tests.h index 9ebbeb9..bcc50b4 100644 --- a/src/libdisfluid/disfluid-tests.h +++ b/src/libdisfluid/disfluid-tests.h @@ -12,12 +12,10 @@ static inline int test_append_count (const char *filename, size_t *n); # include -# include "disfluid-trie-node.h" # include "disfluid-init.h" # include "disfluid-version.h" # include "disfluid-cache-entry.h" # include "disfluid-cache-entry-key.h" -# include "disfluid-db.h" # include "string-desc.h" # include "disfluid-append-only-file.h" # include "disfluid-trie.h" @@ -35,47 +33,6 @@ static inline int test_append_count (const char *filename, size_t *n); # define BILLION THOUSAND MILLION -static void -prepare_database (char **filename) -{ - if (ALLOC_N (*filename, strlen ("/tmp/check-disfluid-db-XXXXXX") + 1) < 0) - { - abort (); - } - strcpy (*filename, "/tmp/check-disfluid-db-XXXXXX"); - if (mkdtemp (*filename) == NULL) - { - abort (); - } -} - -static int -cleanup_database (char **filename) -{ - int error = 0; - ck_assert_int_eq (db_unmark (*filename), 0); - ck_assert_int_eq (db_collect (*filename), 0); - for (size_t i = 0; i < 256; i++) - { - char *group_name = NULL; - ck_assert_int_ge (ALLOC_N - (group_name, - strlen (*filename) + strlen ("/") + 2 + 1), 0); - strcpy (group_name, *filename); - strcat (group_name, "/"); - static const char *alpha[] = { - "0", "1", "2", "3", "4", "5", "6", "7", - "8", "9", "a", "b", "c", "d", "e", "f" - }; - strcat (group_name, alpha[i / 16]); - strcat (group_name, alpha[i % 16]); - rmdir (group_name); - FREE (group_name); - } - rmdir (*filename); - FREE (*filename); -} - /* *INDENT-OFF* */ START_TEST (test_check_version) /* *INDENT-ON* */ @@ -876,115 +833,6 @@ START_TEST (test_cache_hash) END_TEST /* *INDENT-ON* */ -/* *INDENT-OFF* */ -START_TEST (test_db) -/* *INDENT-ON* */ - -{ - ck_assert_int_eq (db_check (), 0); -} -/* *INDENT-OFF* */ -END_TEST -/* *INDENT-ON* */ - -/* *INDENT-OFF* */ -START_TEST (test_db_trie_inner) -/* *INDENT-ON* */ - -{ - char *database; - prepare_database (&database); - static const char *hello = "hello"; - string_desc_t common_part = { - ._nbytes = 5, - ._data = (char *) hello - }; - static const char series[32] = { 1, 2, 3, 4, 5 }; - string_desc_t interesting_branch = { - ._nbytes = 32, - ._data = (char *) series - }; - ck_assert_int_eq (common_part._nbytes, strlen (hello)); - ck_assert_int_eq (interesting_branch._nbytes, sizeof (series)); - const struct trie_node node = { - .common_part = common_part, - .branches = {{0}, interesting_branch, {0}}, - .is_leaf = false - }; - string_desc_t node_id = { 0 }; - ck_assert_int_eq (db_write_trie_node (database, &node_id, &node), 0); - struct trie_node *actual_node = NULL; - ck_assert_int_eq (db_read_trie_node (database, node_id, &actual_node), 0); - ck_assert (!trie_node_is_leaf (actual_node)); - const string_desc_t actual_common_part = - trie_node_common_part (actual_node); - const string_desc_t actual_branches[2] = { - trie_node_branch (actual_node, 0), - trie_node_branch (actual_node, 1) - }; - ck_assert_int_eq (actual_common_part._nbytes, common_part._nbytes); - ck_assert_int_eq (memcmp - (actual_common_part._data, common_part._data, - common_part._nbytes), 0); - ck_assert_int_eq (actual_branches[0]._nbytes, 0); - ck_assert_ptr_null (actual_branches[0]._data); - ck_assert_int_eq (actual_branches[1]._nbytes, 32); - ck_assert_int_eq (memcmp (actual_branches[1]._data, series, 32), 0); - trie_node_free (&actual_node); - FREE (node_id._data); - cleanup_database (&database); -} -/* *INDENT-OFF* */ -END_TEST -/* *INDENT-ON* */ - -/* *INDENT-OFF* */ -START_TEST (test_db_trie_leaf) -/* *INDENT-ON* */ - -{ - char *database; - prepare_database (&database); - static const char *hello = "hello"; - const string_desc_t common_part = { - ._nbytes = 5, - ._data = (char *) hello - }; - static const char series[32] = { 1, 2, 3, 4, 5 }; - const string_desc_t leaf_id = { - ._nbytes = 32, - ._data = (char *) series - }; - ck_assert_int_eq (common_part._nbytes, strlen (hello)); - ck_assert_int_eq (leaf_id._nbytes, sizeof (series)); - const struct trie_node node = { - .common_part = common_part, - .branches = {leaf_id, {0}}, - .is_leaf = true - }; - string_desc_t node_id = { 0 }; - ck_assert_int_eq (db_write_trie_node (database, &node_id, &node), 0); - struct trie_node *actual_node = NULL; - ck_assert_int_eq (db_read_trie_node (database, node_id, &actual_node), 0); - const string_desc_t actual_common_part = - trie_node_common_part (actual_node); - ck_assert (trie_node_is_leaf (actual_node)); - const string_desc_t actual_leaf_id = trie_node_leaf_id (actual_node); - ck_assert_int_eq (actual_common_part._nbytes, common_part._nbytes); - ck_assert_int_eq (memcmp - (actual_common_part._data, common_part._data, - common_part._nbytes), 0); - ck_assert_int_eq (memcmp - (actual_leaf_id._data, leaf_id._data, leaf_id._nbytes), - 0); - trie_node_free (&actual_node); - FREE (node_id._data); - cleanup_database (&database); -} -/* *INDENT-OFF* */ -END_TEST -/* *INDENT-ON* */ - /* *INDENT-OFF* */ START_TEST (test_aof_recover) /* *INDENT-ON* */ @@ -1428,11 +1276,6 @@ run_tests (size_t *n_tests, size_t *n_errors) TCase *cache_hash = tcase_create (_("disfluid cache hash key")); tcase_add_test (cache_hash, test_cache_hash); suite_add_tcase (suite, cache_hash); - TCase *db = tcase_create (_("disfluid database")); - tcase_add_test (db, test_db); - tcase_add_test (db, test_db_trie_inner); - tcase_add_test (db, test_db_trie_leaf); - suite_add_tcase (suite, db); TCase *aof = tcase_create (_("append-only file")); tcase_add_test (aof, test_aof_recover); tcase_add_test (aof, test_aof_can_read_locked_file); diff --git a/src/libdisfluid/disfluid-trie-node.h b/src/libdisfluid/disfluid-trie-node.h deleted file mode 100644 index caa5df7..0000000 --- a/src/libdisfluid/disfluid-trie-node.h +++ /dev/null @@ -1,386 +0,0 @@ -#ifndef DISFLUID_TRIE_NODE_INCLUDED -# define DISFLUID_TRIE_NODE_INCLUDED - -# include -# include "string-desc.h" - -struct trie_node; - -MAYBE_UNUSED static int -trie_node_init_leaf (struct trie_node **node, - const string_desc_t common_part, - const string_desc_t leaf_id); - -MAYBE_UNUSED static int -trie_node_init_node (struct trie_node **node, - const string_desc_t common_part, - const string_desc_t branches[256]); - -MAYBE_UNUSED static void trie_node_free (struct trie_node **node); - -MAYBE_UNUSED static const string_desc_t -trie_node_common_part (const struct trie_node *node); - -MAYBE_UNUSED static bool trie_node_is_leaf (const struct trie_node *node); - -MAYBE_UNUSED static const string_desc_t -trie_node_leaf_id (const struct trie_node *node); - -MAYBE_UNUSED static const string_desc_t -trie_node_branch (const struct trie_node *node, char branch); - -MAYBE_UNUSED static int -db_mark_trie_node (const char *db_root, const string_desc_t id, - int (*mark_leaf) (void *, const string_desc_t), - void *context); - -MAYBE_UNUSED static int -db_read_trie_node (const char *db_root, - const string_desc_t id, struct trie_node **node); - -MAYBE_UNUSED static int -db_write_trie_node (const char *db_root, - string_desc_t * id, const struct trie_node *node); - -# include "disfluid-db.h" -# include "disfluid-init.h" -# include "safe-alloc.h" - -struct trie_node -{ - string_desc_t common_part; - string_desc_t branches[256]; - /* If a leaf, only branches[0] is set. */ - bool is_leaf; -}; - -static int -trie_node_init_full (struct trie_node **node, - const string_desc_t common_part, - bool is_leaf, const string_desc_t branches[256]) -{ - assert (*node == NULL); - ensure_init (); - int error = 0; - if (ALLOC (*node) < 0) - { - error = -2; - goto cleanup; - } - if (ALLOC_N ((*node)->common_part._data, common_part._nbytes) < 0) - { - error = -2; - goto cleanup; - } - (*node)->common_part._nbytes = common_part._nbytes; - memcpy ((*node)->common_part._data, common_part._data, common_part._nbytes); - (*node)->is_leaf = is_leaf; - for (size_t i = 0; i < 256; i++) - { - (*node)->branches[i]._nbytes = branches[i]._nbytes; - if (branches[i]._nbytes != 0) - { - if (ALLOC_N ((*node)->branches[i]._data, branches[i]._nbytes) < 0) - { - error = -2; - goto cleanup; - } - memcpy ((*node)->branches[i]._data, branches[i]._data, - branches[i]._nbytes); - } - } -cleanup: - if (error < 0) - { - trie_node_free (node); - } - return error; -} - -MAYBE_UNUSED static int -trie_node_init_leaf (struct trie_node **node, - const string_desc_t common_part, - const string_desc_t leaf_id) -{ - const string_desc_t branches[256] = { - /* Only the first one is set. */ - { - ._nbytes = leaf_id._nbytes, - ._data = (char *) (leaf_id._data)}, - {0} - }; - return trie_node_init_full (node, common_part, true, branches); -} - -MAYBE_UNUSED static int -trie_node_init_node (struct trie_node **node, - const string_desc_t common_part, - const string_desc_t branches[256]) -{ - return trie_node_init_full (node, common_part, false, branches); -} - -MAYBE_UNUSED static void -trie_node_free (struct trie_node **node) -{ - if (*node != NULL) - { - for (size_t i = 0; i < 256; i++) - { - FREE ((*node)->branches[i]._data); - } - FREE ((*node)->common_part._data); - } - FREE (*node); -} - -MAYBE_UNUSED static const string_desc_t -trie_node_common_part (const struct trie_node *node) -{ - return node->common_part; -} - -MAYBE_UNUSED static bool -trie_node_is_leaf (const struct trie_node *node) -{ - return node->is_leaf; -} - -MAYBE_UNUSED static const string_desc_t -trie_node_leaf_id (const struct trie_node *node) -{ - assert (node->is_leaf); - return node->branches[0]; -} - -MAYBE_UNUSED static const string_desc_t -trie_node_branch (const struct trie_node *node, char branch) -{ - assert (!node->is_leaf); - return node->branches[(uint8_t) branch]; -} - -static int -db_mark_trie_node (const char *db_root, - const string_desc_t id, - int (*mark_leaf) (void *, const string_desc_t), - void *context) -{ - struct trie_node *node = NULL; - int error = db_read_trie_node (db_root, id, &node); - if (error < 0) - { - goto cleanup; - } - if (trie_node_is_leaf (node)) - { - const string_desc_t leaf_id = trie_node_leaf_id (node); - error = mark_leaf (context, leaf_id); - } - else - { - for (uint8_t i = 0; i < 256; i++) - { - const string_desc_t branch = trie_node_branch (node, i); - if (branch._data != NULL) - { - int this_error = db_mark_trie_node (db_root, branch, mark_leaf, - context); - if (this_error < 0) - { - error = -1; - } - } - } - } -cleanup: - trie_node_free (&node); - return error; -} - -/* The trie node is a file composed of: */ -/* - "leaf" if this is a leaf node, "node" otherwise; */ -/* - the common part length, on 8 bytes, big endian; */ -/* - the common part bytes, padded with 0s for 251 bytes; */ -/* - if this is a leaf node: 32 bytes for the ID of the content; */ -/* - if this is a non-leaf node: 256 * 32 bytes for the ID of the - branches. If an entry has 32 zeros, then it is considered - free; */ -/* - the common part. */ - -static int -db_read_trie_node (const char *db_root, - const string_desc_t id, struct trie_node **node) -{ - string_desc_t raw_data = { 0 }; - size_t n_common = 0; - int error = db_read (db_root, &id, &raw_data); - if (error < 0) - { - goto cleanup; - } - if (raw_data._nbytes < 4 + 8 + 32) - { - error = -1; - goto cleanup; - } - n_common = 0; - for (size_t i = 0; i < 8; i++) - { - n_common *= 256; - n_common += (uint8_t) (char) raw_data._data[4 + i]; - } - if (memcmp (raw_data._data, "leaf", 4) == 0 - && raw_data._nbytes == 4 + 8 + 32 + n_common) - { - const string_desc_t common_part = { - ._nbytes = n_common, - ._data = (char *) raw_data._data + 4 + 8 + 32 - }; - const string_desc_t leaf_id = { - ._nbytes = 32, - ._data = (char *) raw_data._data + 4 + 8 - }; - error = trie_node_init_leaf (node, common_part, leaf_id); - if (error < 0) - { - goto cleanup; - } - } - else if (memcmp (raw_data._data, "node", 4) == 0 - && raw_data._nbytes == 4 + 8 + (256 * 32) + n_common) - { - string_desc_t branches[256] = { 0 }; - for (size_t i = 0; i < 256; i++) - { - branches[i]._nbytes = 32; - branches[i]._data = (char *) raw_data._data + 4 + 8 + (i * 32); - size_t n_zero = 0; - while (n_zero < branches[i]._nbytes - && branches[i]._data[n_zero] == 0) - { - n_zero++; - } - if (n_zero == branches[i]._nbytes) - { - branches[i]._nbytes = 0; - branches[i]._data = NULL; - } - } - const string_desc_t common_part = { - ._nbytes = n_common, - ._data = (char *) raw_data._data + 4 + 8 + (256 * 32) - }; - error = trie_node_init_node (node, common_part, branches); - if (error < 0) - { - goto cleanup; - } - } - else - { - error = -1; - goto cleanup; - } -cleanup: - FREE (raw_data._data); - if (error < 0) - { - trie_node_free (node); - } - return error; -} - -static int -db_write_trie_node (const char *db_root, - string_desc_t * id, const struct trie_node *node) -{ - assert (id->_data == NULL); - int error = 0; - size_t offset = 0; - const string_desc_t common_part = trie_node_common_part (node); - if (trie_node_is_leaf (node)) - { - const string_desc_t leaf_id = trie_node_leaf_id (node); - string_desc_t data = { 0 }; - if (leaf_id._nbytes != 32) - { - error = -1; - goto cleanup_as_leaf; - } - data._nbytes = 4 + 8 + 32 + common_part._nbytes; - if (ALLOC_N (data._data, data._nbytes) < 0) - { - error = -2; - goto cleanup_as_leaf; - } - memcpy (data._data, "leaf", 4); - offset += 4; - size_t nbytes = common_part._nbytes; - for (size_t i = 8; i-- > 0;) - { - data._data[offset + i] = nbytes % 256; - nbytes /= 256; - } - offset += 8; - memcpy (data._data + offset, leaf_id._data, leaf_id._nbytes); - offset += 32; - memcpy (data._data + offset, common_part._data, common_part._nbytes); - error = db_write (db_root, id, &data); - cleanup_as_leaf: - FREE (data._data); - goto cleanup; - } - else - { - string_desc_t data = { 0 }; - data._nbytes = 4 + 8 + 256 * 32 + common_part._nbytes; - if (ALLOC_N (data._data, data._nbytes) < 0) - { - error = -2; - goto cleanup_as_node; - } - memcpy (data._data, "node", 4); - offset += 4; - size_t nbytes = common_part._nbytes; - for (size_t i = 8; i-- > 0;) - { - data._data[offset + i] = nbytes % 256; - nbytes /= 256; - } - offset += 8; - for (size_t i = 0; i < 256; i++) - { - const string_desc_t branch = trie_node_branch (node, (uint8_t) i); - if (branch._data == NULL || branch._nbytes == 0) - { - /* I suppose we avoid this one. */ - assert (branch._data == NULL); - assert (branch._nbytes == 0); - } - else if (branch._nbytes != 32) - { - error = -1; - goto cleanup_as_node; - } - else - { - memcpy (data._data + offset + (i * 32), branch._data, 32); - } - } - offset += 32 * 256; - memcpy (data._data + offset, common_part._data, common_part._nbytes); - error = db_write (db_root, id, &data); - cleanup_as_node: - FREE (data._data); - goto cleanup; - } -cleanup: - if (error != 0) - { - FREE (id->_data); - } - return error; -} - -#endif /* not DISFLUID_TRIE_NODE_INCLUDED */ -- cgit v1.2.3