2022-11-15 16:21:27 +01:00
|
|
|
#ifndef AD3_TERNARYTRIE
|
|
|
|
#define AD3_TERNARYTRIE
|
|
|
|
|
2022-11-27 20:20:09 +01:00
|
|
|
#define DELIMITER '\0'
|
2022-12-03 13:27:34 +01:00
|
|
|
|
2022-12-07 23:20:39 +01:00
|
|
|
// The compiler aligns structs to be multiple of 8 bytes. Therefore, we have a
|
|
|
|
// few "free" bytes that are allocated whether we use them or not, so we might
|
|
|
|
// as, hence the seemingly weird number. This is the largest number we can use
|
|
|
|
// where the size of TernaryTrieNode is still 32 bytes.
|
|
|
|
//
|
|
|
|
// NOTE: Should not be higher than 254 or stuff will break.
|
|
|
|
#define TRIE_MAX_SKIP_SIZE 13
|
2022-11-27 20:20:09 +01:00
|
|
|
|
2022-11-15 16:21:27 +01:00
|
|
|
/**
|
|
|
|
* The implementation of a Ternary Trie.
|
|
|
|
*
|
2022-11-27 20:20:09 +01:00
|
|
|
* Each node should be represented by a binary tree in order to reduce the
|
|
|
|
* memory usage.
|
2022-11-15 16:21:27 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stddef.h>
|
2022-12-07 23:20:39 +01:00
|
|
|
#include <stdint.h>
|
2022-11-27 20:20:09 +01:00
|
|
|
#include <string.h>
|
2022-11-15 16:21:27 +01:00
|
|
|
|
2022-11-27 20:20:09 +01:00
|
|
|
static const char charset[] =
|
|
|
|
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
2022-11-21 12:03:16 +01:00
|
|
|
static const size_t charset_len = sizeof(charset) - 1;
|
|
|
|
|
|
|
|
// Length of randomly generated keys
|
2022-11-21 21:02:33 +01:00
|
|
|
#define RANDOM_KEY_LENGTH_SHORT 4
|
|
|
|
#define RANDOM_KEY_LENGTH_LONG 16
|
2022-11-21 12:03:16 +01:00
|
|
|
|
2022-11-15 16:21:27 +01:00
|
|
|
/**
|
|
|
|
* Type definition for the struct representing the current Trie.
|
|
|
|
*
|
|
|
|
* You can (and should) redefine this in your c-file with the concrete fields.
|
|
|
|
*/
|
2022-11-29 11:27:28 +01:00
|
|
|
typedef struct ttrie Trie;
|
2022-11-15 16:21:27 +01:00
|
|
|
|
2022-12-07 12:29:37 +01:00
|
|
|
typedef enum trie_exit_code {
|
|
|
|
Ok = 0,
|
|
|
|
NotFound,
|
|
|
|
AlreadyPresent,
|
|
|
|
FileError
|
|
|
|
} TrieExitCode;
|
2022-11-21 15:28:02 +01:00
|
|
|
|
2022-11-21 14:46:53 +01:00
|
|
|
/**
|
2022-12-07 12:29:37 +01:00
|
|
|
* Allocate & initialize a new trie, and populate it with the data from the
|
|
|
|
* given data file.
|
2022-11-21 14:46:53 +01:00
|
|
|
*
|
2022-12-07 12:29:37 +01:00
|
|
|
* @return 0 if everything was successful, non-zero otherwise
|
2022-11-21 14:46:53 +01:00
|
|
|
*/
|
2022-12-07 12:29:37 +01:00
|
|
|
TrieExitCode trie_init(Trie **trie_ptr, const char *file_path);
|
2022-11-15 22:49:36 +01:00
|
|
|
|
2022-11-15 16:21:27 +01:00
|
|
|
/**
|
|
|
|
* De-allocate a trie by freeing the memory occupied by this trie.
|
|
|
|
*
|
|
|
|
* @param trie which should be freed
|
|
|
|
*/
|
2022-11-29 11:27:28 +01:00
|
|
|
void trie_free(Trie *trie);
|
2022-11-15 16:21:27 +01:00
|
|
|
|
|
|
|
/**
|
2022-11-21 15:28:02 +01:00
|
|
|
* Search for an entry in the trie.
|
2022-11-15 16:21:27 +01:00
|
|
|
*
|
|
|
|
* @param trie
|
2022-12-07 12:29:37 +01:00
|
|
|
* @param entry_ptr pointer to Entry will be stored here, if found
|
2022-11-21 15:28:02 +01:00
|
|
|
* @param key key representing the entry
|
2022-12-07 12:29:37 +01:00
|
|
|
* @return 0 if the search was successful, 1 if not found
|
2022-11-15 16:21:27 +01:00
|
|
|
*/
|
2022-12-07 23:20:39 +01:00
|
|
|
TrieExitCode trie_search(Trie *trie, void **data_ptr, const char *key);
|
2022-11-15 16:21:27 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Add a string to this trie.
|
|
|
|
*
|
|
|
|
* @param trie
|
2022-11-21 15:28:02 +01:00
|
|
|
* @param key key to represent entry with
|
2022-11-27 20:20:09 +01:00
|
|
|
* @param entry entry to add
|
2022-12-07 12:29:37 +01:00
|
|
|
* @return 0 if added, 1 if already in trie, something else if other errors
|
2022-11-15 16:21:27 +01:00
|
|
|
*/
|
2022-12-07 23:55:46 +01:00
|
|
|
TrieExitCode trie_add(Trie *trie, const char *key, void *data,
|
|
|
|
uint64_t data_len);
|
2022-11-29 20:59:28 +01:00
|
|
|
|
2022-12-08 12:12:29 +01:00
|
|
|
/**
|
|
|
|
* Same as trie_add, but copy the data instead of taking over ownership of the
|
|
|
|
* pointer.
|
|
|
|
*
|
|
|
|
* @param trie
|
|
|
|
* @param key key to represent entry with
|
|
|
|
* @param entry entry to add
|
|
|
|
* @return 0 if added, 1 if already in trie, something else if other errors
|
|
|
|
*/
|
|
|
|
TrieExitCode trie_add_copy(Trie *trie, const char *key, void *data,
|
|
|
|
uint64_t data_len);
|
|
|
|
|
2022-11-21 12:03:16 +01:00
|
|
|
/**
|
2022-11-21 15:28:02 +01:00
|
|
|
* Add an entry by generating a random string as the key.
|
2022-11-21 12:03:16 +01:00
|
|
|
*
|
|
|
|
* @param trie
|
2022-11-21 15:28:02 +01:00
|
|
|
* @param entry entry to add
|
2022-11-21 21:02:33 +01:00
|
|
|
* @param secure whether to generate a longer, more secure random key
|
2022-12-07 11:28:20 +01:00
|
|
|
* @return pointer to the generated key. This pointer is safe to use after
|
|
|
|
* unlocking the trie, and should be freed manually.
|
2022-11-21 12:03:16 +01:00
|
|
|
*/
|
2022-12-07 23:20:39 +01:00
|
|
|
TrieExitCode trie_add_random(Trie *trie, char **key_ptr, void *data,
|
2022-12-07 23:55:46 +01:00
|
|
|
uint64_t data_len, bool secure);
|
2022-11-21 12:03:16 +01:00
|
|
|
|
2022-11-15 16:21:27 +01:00
|
|
|
/**
|
2022-11-21 15:28:02 +01:00
|
|
|
* Remove an entry from this trie given its key.
|
2022-11-15 16:21:27 +01:00
|
|
|
*
|
|
|
|
* @param trie
|
2022-11-21 15:28:02 +01:00
|
|
|
* @param key key representing entry
|
2022-11-27 20:20:09 +01:00
|
|
|
* @return true if the entry was present and has been removed, false if it was
|
|
|
|
* not present
|
2022-11-15 16:21:27 +01:00
|
|
|
*/
|
2022-11-29 11:27:28 +01:00
|
|
|
bool trie_remove(Trie *trie, const char *key);
|
2022-11-15 16:21:27 +01:00
|
|
|
|
|
|
|
/**
|
2022-11-21 15:28:02 +01:00
|
|
|
* Returns the number of entries in this trie.
|
2022-11-15 16:21:27 +01:00
|
|
|
*
|
|
|
|
* @param trie
|
2022-11-21 15:28:02 +01:00
|
|
|
* @return the number of entries in this trie
|
2022-11-15 16:21:27 +01:00
|
|
|
*/
|
2022-12-07 23:20:39 +01:00
|
|
|
uint64_t trie_size(Trie *trie);
|
2022-11-15 16:21:27 +01:00
|
|
|
|
2022-12-07 11:28:20 +01:00
|
|
|
/*
|
|
|
|
* Acquire a read lock on the trie.
|
|
|
|
*
|
|
|
|
* @return 0 if successful, non-zero otherwise (return value of
|
|
|
|
* pthread_rwlock_rdlock)
|
|
|
|
*/
|
|
|
|
int trie_rlock(Trie *trie);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Acquire a write lock on the trie.
|
|
|
|
*
|
|
|
|
* @return 0 if successful, non-zero otherwise (return value of
|
|
|
|
* pthread_rwlock_wrlock)
|
|
|
|
*/
|
|
|
|
int trie_wlock(Trie *trie);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Release the lock on a trie after having acquired it beforehand.
|
|
|
|
*
|
|
|
|
* @return 0 if successful, non-zero otherwise (return value of
|
|
|
|
* pthread_rwlock_unlock)
|
|
|
|
*/
|
|
|
|
int trie_unlock(Trie *trie);
|
|
|
|
|
2022-11-27 20:20:09 +01:00
|
|
|
#endif // AD3_TERNARYTRIE
|