refactor: don't compile trie as separate library
ci/woodpecker/push/woodpecker Pipeline was successful
Details
ci/woodpecker/push/woodpecker Pipeline was successful
Details
parent
55474b485f
commit
cc8cfaeace
|
@ -1,16 +1,15 @@
|
|||
cmake_minimum_required(VERSION 3.20)
|
||||
project(lander C CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
include_directories(crow/include tries/include)
|
||||
include_directories(crow/include include)
|
||||
|
||||
add_subdirectory(crow)
|
||||
add_subdirectory(tries)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL Release)
|
||||
add_compile_options(-O3 -flto)
|
||||
endif()
|
||||
|
||||
add_executable(lander src/main.cpp)
|
||||
target_link_libraries(lander Crow ternarytrie)
|
||||
add_executable(lander src/main.cpp src/tries/ternarytrie.c)
|
||||
|
|
3
Makefile
3
Makefile
|
@ -1,10 +1,11 @@
|
|||
# =====CONFIG=====
|
||||
BUILD_DIR := ./build
|
||||
SRC_DIR := ./src
|
||||
INCLUDE_DIR := ./include
|
||||
TEST_DIR := test
|
||||
CORES != nproc
|
||||
|
||||
SRCS := $(shell find '$(SRC_DIR)' -iname '*.cpp')
|
||||
SRCS := $(shell find '$(SRC_DIR)' '$(INCLUDE_DIR)' \( -iname '*.cpp' -or -iname '*.c' -or -iname '*.h' \))
|
||||
|
||||
|
||||
# =====RECIPES=====
|
||||
|
|
|
@ -1,16 +1,23 @@
|
|||
#ifndef AD3_TERNARYTRIE
|
||||
#define AD3_TERNARYTRIE
|
||||
|
||||
#define ALPHABET_SIZE 256
|
||||
#define DELIMITER '\0'
|
||||
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
|
||||
|
||||
/**
|
||||
* The implementation of a Ternary Trie.
|
||||
*
|
||||
* Each node should be represented by a binary tree in order to reduce the memory usage.
|
||||
* Each node should be represented by a binary tree in order to reduce the
|
||||
* memory usage.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
static const char charset[] =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
static const size_t charset_len = sizeof(charset) - 1;
|
||||
|
||||
// Length of randomly generated keys
|
||||
|
@ -24,11 +31,7 @@ static const size_t charset_len = sizeof(charset) - 1;
|
|||
*/
|
||||
typedef struct ttrie TernaryTrie;
|
||||
|
||||
typedef enum entry_type {
|
||||
Redirect,
|
||||
Paste,
|
||||
Unknown
|
||||
} EntryType;
|
||||
typedef enum entry_type { Redirect, Paste, Unknown } EntryType;
|
||||
|
||||
typedef struct entry {
|
||||
EntryType type;
|
||||
|
@ -42,7 +45,7 @@ Entry *entry_new(EntryType type, const char *string);
|
|||
*
|
||||
* @return a pointer to an empty Trie struct
|
||||
*/
|
||||
TernaryTrie* ternarytrie_init();
|
||||
TernaryTrie *ternarytrie_init();
|
||||
|
||||
/**
|
||||
* Populate trie with entries stored in the given file.
|
||||
|
@ -51,14 +54,14 @@ TernaryTrie* ternarytrie_init();
|
|||
* @param file_path path to file containing entries
|
||||
* @return amount of entries added; -1 if an error occured
|
||||
*/
|
||||
int ternarytrie_populate(TernaryTrie* trie, const char* file_path);
|
||||
int ternarytrie_populate(TernaryTrie *trie, const char *file_path);
|
||||
|
||||
/**
|
||||
* De-allocate a trie by freeing the memory occupied by this trie.
|
||||
*
|
||||
* @param trie which should be freed
|
||||
*/
|
||||
void ternarytrie_free(TernaryTrie* trie);
|
||||
void ternarytrie_free(TernaryTrie *trie);
|
||||
|
||||
/**
|
||||
* Search for an entry in the trie.
|
||||
|
@ -67,7 +70,7 @@ void ternarytrie_free(TernaryTrie* trie);
|
|||
* @param key key representing the entry
|
||||
* @return pointer to entry; NULL if not found
|
||||
*/
|
||||
Entry *ternarytrie_search(TernaryTrie* trie, const char* key);
|
||||
Entry *ternarytrie_search(TernaryTrie *trie, const char *key);
|
||||
|
||||
/**
|
||||
* Add a string to this trie.
|
||||
|
@ -75,9 +78,10 @@ Entry *ternarytrie_search(TernaryTrie* trie, const char* key);
|
|||
* @param trie
|
||||
* @param key key to represent entry with
|
||||
* @param entry entry to add
|
||||
* @return true if the trie was changed by this operation, false if it was already present
|
||||
* @return true if the trie was changed by this operation, false if it was
|
||||
* already present
|
||||
*/
|
||||
bool ternarytrie_add(TernaryTrie* trie, const char* key, Entry *entry);
|
||||
bool ternarytrie_add(TernaryTrie *trie, const char *key, Entry *entry);
|
||||
|
||||
/**
|
||||
* Add an entry by generating a random string as the key.
|
||||
|
@ -94,9 +98,10 @@ char *ternarytrie_add_random(TernaryTrie *trie, Entry *entry, bool secure);
|
|||
*
|
||||
* @param trie
|
||||
* @param key key representing entry
|
||||
* @return true if the entry was present and has been removed, false if it was not present
|
||||
* @return true if the entry was present and has been removed, false if it was
|
||||
* not present
|
||||
*/
|
||||
bool ternarytrie_remove(TernaryTrie* trie, const char *key);
|
||||
bool ternarytrie_remove(TernaryTrie *trie, const char *key);
|
||||
|
||||
/**
|
||||
* Returns the number of entries in this trie.
|
||||
|
@ -104,6 +109,6 @@ bool ternarytrie_remove(TernaryTrie* trie, const char *key);
|
|||
* @param trie
|
||||
* @return the number of entries in this trie
|
||||
*/
|
||||
size_t ternarytrie_size(TernaryTrie* trie);
|
||||
size_t ternarytrie_size(TernaryTrie *trie);
|
||||
|
||||
#endif //AD3_TERNARYTRIE
|
||||
#endif // AD3_TERNARYTRIE
|
|
@ -1,8 +1,8 @@
|
|||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "ternarytrie.h"
|
||||
#include "ternarytrie_node.c"
|
||||
|
@ -10,7 +10,7 @@
|
|||
typedef struct ttrie {
|
||||
TernaryTrieNode *root;
|
||||
size_t size;
|
||||
char* file_path;
|
||||
char *file_path;
|
||||
pthread_rwlock_t lock;
|
||||
} TernaryTrie;
|
||||
|
||||
|
@ -20,7 +20,7 @@ typedef struct ttrie {
|
|||
* @return pointer to the empty TernaryTrie
|
||||
*/
|
||||
TernaryTrie *ternarytrie_init() {
|
||||
TernaryTrie *trie = calloc(1, sizeof(TernaryTrie));
|
||||
TernaryTrie *trie = (TernaryTrie *)calloc(1, sizeof(TernaryTrie));
|
||||
trie->root = ttnode_init();
|
||||
pthread_rwlock_init(&trie->lock, NULL);
|
||||
|
||||
|
@ -40,28 +40,33 @@ void ternarytrie_free(TernaryTrie *trie) {
|
|||
bool ternarytrie_add_internal(TernaryTrie *trie, const char *key, Entry *entry);
|
||||
|
||||
EntryType entry_type_from_char(char c) {
|
||||
switch(c) {
|
||||
case '0': return Redirect;
|
||||
case '1': return Paste;
|
||||
default: return Unknown;
|
||||
switch (c) {
|
||||
case '0':
|
||||
return Redirect;
|
||||
case '1':
|
||||
return Paste;
|
||||
default:
|
||||
return Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
char entry_type_to_char(EntryType et) {
|
||||
switch (et) {
|
||||
case Redirect: return '0';
|
||||
case Paste: return '1';
|
||||
default: return '\0';
|
||||
case Redirect:
|
||||
return '0';
|
||||
case Paste:
|
||||
return '1';
|
||||
default:
|
||||
return '\0';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Entry *entry_new(EntryType type, const char *string) {
|
||||
Entry *entry = malloc(sizeof(Entry));
|
||||
Entry *entry = (Entry *)malloc(sizeof(Entry));
|
||||
entry->type = type;
|
||||
|
||||
if (string != NULL) {
|
||||
entry->string = my_strdup(string);
|
||||
entry->string = strdup(string);
|
||||
} else {
|
||||
entry->string = NULL;
|
||||
}
|
||||
|
@ -70,9 +75,9 @@ Entry *entry_new(EntryType type, const char *string) {
|
|||
}
|
||||
|
||||
int ternarytrie_populate(TernaryTrie *trie, const char *file_path) {
|
||||
trie->file_path = my_strdup(file_path);
|
||||
trie->file_path = strdup(file_path);
|
||||
|
||||
FILE* fp = fopen(file_path, "r");
|
||||
FILE *fp = fopen(file_path, "r");
|
||||
|
||||
// TODO properly handle this
|
||||
if (fp == NULL) {
|
||||
|
@ -161,8 +166,7 @@ SearchResult ternarytrie_search_node(TernaryTrie *trie, const char *key) {
|
|||
} while (1);
|
||||
|
||||
if ((*child_ptr)->type == 2) {
|
||||
if (key[i] != DELIMITER &&
|
||||
strcmp(key + i, (*child_ptr)->ptr.string) == 0) {
|
||||
if (key[i] != DELIMITER && strcmp(key + i, (*child_ptr)->ptr.string) == 0) {
|
||||
out.child = *child_ptr;
|
||||
out.parent = *node_ptr;
|
||||
}
|
||||
|
@ -208,7 +212,8 @@ Entry *ternarytrie_search(TernaryTrie *trie, const char *key) {
|
|||
* @return true if the string wasn't present in the trie and thus added, false
|
||||
* otherwise
|
||||
*/
|
||||
bool ternarytrie_add_internal(TernaryTrie *trie, const char *string, Entry *entry) {
|
||||
bool ternarytrie_add_internal(TernaryTrie *trie, const char *string,
|
||||
Entry *entry) {
|
||||
// Edge case for empty string
|
||||
if (string[0] == DELIMITER) {
|
||||
if (trie->root->type == 0) {
|
||||
|
@ -291,7 +296,8 @@ bool ternarytrie_add_internal(TernaryTrie *trie, const char *string, Entry *entr
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ternarytrie_add_persistent(TernaryTrie *trie, const char *key, Entry *entry) {
|
||||
bool ternarytrie_add_persistent(TernaryTrie *trie, const char *key,
|
||||
Entry *entry) {
|
||||
bool return_value = false;
|
||||
|
||||
if (trie->file_path != NULL) {
|
||||
|
@ -333,13 +339,13 @@ bool ternarytrie_add(TernaryTrie *trie, const char *key, Entry *entry) {
|
|||
return return_value;
|
||||
}
|
||||
|
||||
char* ternarytrie_add_random(TernaryTrie *trie, Entry *entry, bool secure) {
|
||||
char *ternarytrie_add_random(TernaryTrie *trie, Entry *entry, bool secure) {
|
||||
pthread_rwlock_wrlock(&trie->lock);
|
||||
|
||||
// Generate random key
|
||||
bool ok = false;
|
||||
int key_length = secure ? RANDOM_KEY_LENGTH_LONG : RANDOM_KEY_LENGTH_SHORT;
|
||||
char *key = malloc(key_length + 1);
|
||||
char *key = (char *)malloc(key_length + 1);
|
||||
key[key_length] = '\0';
|
||||
|
||||
// We naively generate new keys until we find a key that isn't in the trie
|
||||
|
@ -368,7 +374,6 @@ char* ternarytrie_add_random(TernaryTrie *trie, Entry *entry, bool secure) {
|
|||
return return_value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove the given string from a TernaryTrie.
|
||||
*
|
|
@ -3,7 +3,6 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "ternarytrie.h"
|
||||
#include "common.c"
|
||||
|
||||
/**
|
||||
* Represents a node of the binary tree contained within each non-leaf
|
||||
|
@ -55,7 +54,8 @@ void ttnode_free(TernaryTrieNode *node);
|
|||
* @return pointer to newly allocated struct
|
||||
*/
|
||||
TernaryTrieInnerNode *ttinode_init(char c) {
|
||||
TernaryTrieInnerNode *node = calloc(1, sizeof(TernaryTrieInnerNode));
|
||||
TernaryTrieInnerNode *node =
|
||||
(TernaryTrieInnerNode *)calloc(1, sizeof(TernaryTrieInnerNode));
|
||||
node->key = c;
|
||||
|
||||
return node;
|
||||
|
@ -66,7 +66,9 @@ TernaryTrieInnerNode *ttinode_init(char c) {
|
|||
*
|
||||
* @return pointer to newly allocated struct
|
||||
*/
|
||||
TernaryTrieNode *ttnode_init() { return calloc(1, sizeof(TernaryTrieNode)); }
|
||||
TernaryTrieNode *ttnode_init() {
|
||||
return (TernaryTrieNode *)calloc(1, sizeof(TernaryTrieNode));
|
||||
}
|
||||
|
||||
/**
|
||||
* Free a TernaryTrieInnerNode and its underlying tree structure. This should
|
||||
|
@ -120,7 +122,7 @@ void ttnode_free(TernaryTrieNode *node) {
|
|||
void ttnode_set_string(TernaryTrieNode *node, const char *string) {
|
||||
node->type = 2;
|
||||
node->size = strlen(string);
|
||||
node->ptr.string = my_strdup(string);
|
||||
node->ptr.string = strdup(string);
|
||||
}
|
||||
|
||||
/**
|
|
@ -1,12 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.20)
|
||||
project(ternarytrie C)
|
||||
|
||||
set(CMAKE_C_STANDARD 17)
|
||||
|
||||
add_library(ternarytrie STATIC src/ternarytrie.c)
|
||||
|
||||
target_include_directories(
|
||||
ternarytrie PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
)
|
||||
target_compile_options(ternarytrie PRIVATE -O3 -flto)
|
|
@ -1,42 +0,0 @@
|
|||
#define ALPHABET_SIZE 256
|
||||
#define DELIMITER '\0'
|
||||
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Own implementation of strdup, heavily inspired by the glibc source code.
|
||||
*
|
||||
* This is neccessary because subGIT does not seem to have a strdup
|
||||
* implementation available for use.
|
||||
*
|
||||
* @param s string to duplicate
|
||||
* @return pointer to the newly allocated string
|
||||
*/
|
||||
char *my_strdup(const char *s) {
|
||||
size_t len = strlen(s);
|
||||
char *new = malloc(len + 1);
|
||||
new[len] = DELIMITER;
|
||||
|
||||
return (char *)memcpy(new, s, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Own implementation of strndup, heavily inspired by the glibc source code.
|
||||
*
|
||||
* This is neccessary because subGIT does not seem to have a strndup
|
||||
* implementation available for use.
|
||||
*
|
||||
* @param s string to duplicate
|
||||
* @return pointer to the newly allocated string
|
||||
*/
|
||||
char *my_strndup(const char *s, size_t n) {
|
||||
size_t string_len = strlen(s);
|
||||
size_t len = MAX(string_len, n);
|
||||
char *new = (char *)malloc(len + 1);
|
||||
|
||||
new[len] = DELIMITER;
|
||||
|
||||
return (char *)memcpy(new, s, len);
|
||||
}
|
Loading…
Reference in New Issue