From b9eaeb194986c5e658cbb485dae232aa530e1706 Mon Sep 17 00:00:00 2001 From: Angelo Probst Date: Thu, 29 Aug 2024 22:43:24 -0300 Subject: [PATCH 001/130] atom db in cpp --- hyperon_das_atomdb_cpp/src/basic_types.hpp | 131 +++++ hyperon_das_atomdb_cpp/src/database.hpp | 499 ++++++++++++++++++ .../utils/expression_hasher.c | 76 +++ .../utils/expression_hasher.h | 67 +++ 4 files changed, 773 insertions(+) create mode 100644 hyperon_das_atomdb_cpp/src/basic_types.hpp create mode 100644 hyperon_das_atomdb_cpp/src/database.hpp create mode 100644 hyperon_das_atomdb_cpp/utils/expression_hasher.c create mode 100644 hyperon_das_atomdb_cpp/utils/expression_hasher.h diff --git a/hyperon_das_atomdb_cpp/src/basic_types.hpp b/hyperon_das_atomdb_cpp/src/basic_types.hpp new file mode 100644 index 00000000..43c75b46 --- /dev/null +++ b/hyperon_das_atomdb_cpp/src/basic_types.hpp @@ -0,0 +1,131 @@ +#ifndef _BASIC_TYPES_HPP +#define _BASIC_TYPES_HPP + +#include +#include +#include +#include + +enum class FieldIndexType { + BINARY_TREE, + TOKEN_INVERTED_LIST +}; + +class Atom { + public: + Atom(const std::string& id, + const std::string& handle, + const std::string& composite_type_hash, + const std::string& named_type) + : _id(id), + handle(handle), + composite_type_hash(composite_type_hash), + named_type(named_type) { + if (id.empty()) { + throw std::invalid_argument("Atom ID cannot be empty."); + } + if (handle.empty()) { + throw std::invalid_argument("Atom handle cannot be empty."); + } + if (composite_type_hash.empty()) { + throw std::invalid_argument("Composite type hash cannot be empty."); + } + if (named_type.empty()) { + throw std::invalid_argument("Named type cannot be empty."); + } + } + + virtual ~Atom() = default; + + std::string _id; + std::string handle; + std::string composite_type_hash; + std::string named_type; +}; + +class Node : public Atom { + public: + Node(const std::string& id, + const std::string& handle, + const std::string& composite_type_hash, + const std::string& named_type, + const std::string& name) + : name(name), + Atom(id, handle, composite_type_hash, named_type) { + if (name.empty()) { + throw std::invalid_argument("Node name cannot be empty."); + } + } + + std::string name; +}; + +class CompositeType { + public: + CompositeType(const std::string& single_hash) + : single_hash(single_hash) { + if (single_hash.empty()) { + throw std::invalid_argument("Single hash cannot be empty."); + } + if (!list_of_composite_types.empty()) { + throw std::invalid_argument("List of composite types must be empty."); + } + } + + CompositeType(const std::vector& list_of_composite_types) + : list_of_composite_types(list_of_composite_types) { + if (list_of_composite_types.empty()) { + throw std::invalid_argument("List of composite types cannot be empty."); + } + if (!single_hash.empty()) { + throw std::invalid_argument("Single hash must be empty."); + } + } + + std::string single_hash = ""; + std::vector list_of_composite_types = {}; +}; + +class Link : public Atom { + public: + Link(const std::string& id, + const std::string& handle, + const std::string& composite_type_hash, + const std::string& named_type, + std::vector& composite_type, + const std::string& named_type_hash, + const std::vector& targets, + bool is_top_level = true, + const std::map& keys = {}) + : composite_type(composite_type), + named_type_hash(named_type_hash), + targets(targets), + is_top_level(is_top_level), + keys(keys), + Atom(id, handle, composite_type_hash, named_type) { + if (composite_type.empty()) { + throw std::invalid_argument("Composite type cannot be empty."); + } + if (named_type_hash.empty()) { + throw std::invalid_argument("Named type hash cannot be empty."); + } + if (targets.empty()) { + throw std::invalid_argument("Link targets cannot be empty."); + } + } + + std::vector composite_type; + std::string named_type_hash; + std::vector targets; + bool is_top_level = true; + std::map keys = {}; + std::vector targets_documents = {}; +}; + +using IncomingLinks = std::vector; +using MatchedTargetsList = std::vector>>; +using HandlesList = std::vector; +using MatchedLinksResult = std::pair; +using MatchedTypesResult = std::pair; + +#endif // _BASIC_TYPES_HPP diff --git a/hyperon_das_atomdb_cpp/src/database.hpp b/hyperon_das_atomdb_cpp/src/database.hpp new file mode 100644 index 00000000..68767868 --- /dev/null +++ b/hyperon_das_atomdb_cpp/src/database.hpp @@ -0,0 +1,499 @@ +#ifndef _DATABASE_HPP +#define _DATABASE_HPP + +#include +#include +#include + +#include "basic_types.hpp" +#include "utils/expression_hasher.h" + +const std::string WILDCARD = "*"; +const std::vector UNORDERED_LINK_TYPES = {}; + +enum class OnOffParams { + NO_TARGET_FORMAT, + TARGETS_DOCUMENTS, + DEEP_REPRESENTATION, +}; + +using Flags = std::unordered_map; + +class AtomDoesNotExist : public std::exception { + public: + AtomDoesNotExist(const std::string& message, const std::string details) + : message(message), details(details) {} + + const char* what() const noexcept override { + return (message + ": " + details).c_str(); + } + + private: + std::string message; + std::string details; +}; + +class AtomDB { + public: + virtual ~AtomDB() = default; + + /** + * @brief Get the handle of the node with the specified type and name. + * @param node_type The node type. + * @param node_name The node name. + * @return The node handle. + */ + static std::string node_handle( + const std::string& node_type, const std::string& node_name) { + return terminal_hash(node_type.c_str(), node_name.c_str()); + } + + /** + * @brief Get the handle of the link with the specified type and targets. + * @param link_type The link type. + * @param target_handles A list of link target identifiers. + * @return The link handle. + */ + static std::string link_handle( + const std::string& link_type, const std::vector& target_handles) { + std::string link_type_hash = named_type_hash(link_type.c_str()); + std::vector elements; + for (const auto& target_handle : target_handles) { + elements.push_back(target_handle.c_str()); + } + return expression_hash(link_type_hash.c_str(), elements.data(), elements.size()); + } + + /** + * @brief Checks if a node with the specified type and name exists. + * + * This function checks whether a node with the given type and name exists in the database. + * + * @param node_type A string representing the type of the node. + * @param node_name A string representing the name of the node. + * @return A boolean value indicating whether the node exists (true) or not (false). + */ + bool node_exists(const std::string& node_type, const std::string& node_name) { + try { + get_node_handle(node_type, node_name); + return true; + } catch (const AtomDoesNotExist& e) { + return false; + } + } + + /** + * @brief Checks if a link with the specified type and target handles exists. + * + * This function checks whether a link with the given type and target handles exists in the database. + * + * @param link_type A string representing the type of the link. + * @param target_handles A vector of strings representing the handles of the link's targets. + * @return A boolean value indicating whether the link exists (true) or not (false). + */ + bool link_exists(const std::string& link_type, const std::vector& target_handles) { + try { + get_link_handle(link_type, target_handles); + return true; + } catch (const AtomDoesNotExist& e) { + return false; + } + } + + /** + * @brief Retrieves an atom from the database using its handle and optional flags. + * + * This function takes a handle and optional flags, and retrieves the corresponding atom from the database. + * + * @param handle A string representing the handle of the atom to be retrieved. + * @param flags An optional Flags object containing additional retrieval options. + * @return An Atom object representing the retrieved atom. + */ + const Atom& get_atom(const std::string& handle, const Flags& flags = {}) { + Atom document = _get_atom(handle); + bool no_target_format = flags.find(OnOffParams::NO_TARGET_FORMAT) != flags.end(); + no_target_format = no_target_format ? flags.at(OnOffParams::NO_TARGET_FORMAT) : false; + if (no_target_format) return document; + return reformat_document(document, flags); + } + + /** + * @brief Get the handle of the node with the specified type and name. + * @param node_type The node type. + * @param node_name The node name. + * @return The node handle. + */ + virtual std::string get_node_handle( + const std::string& node_type, const std::string& node_name) = 0; + + /** + * @brief Get the name of the node with the specified handle. + * @param node_handle The node handle. + * @return The node name. + */ + virtual std::string get_node_name(const std::string& node_handle) = 0; + + /** + * @brief Get the type of the node with the specified handle. + * @param node_handle The node handle. + * @return The node type. + */ + virtual std::string get_node_type(const std::string& node_handle) = 0; + + /** + * @brief Get the name of a node of the specified type containing the given substring. + * @param node_type The node type. + * @param substring The substring to search for in node names. + * @return List of handles of nodes whose names matched the criteria. + */ + virtual std::vector get_node_by_name( + const std::string& node_type, const std::string& substring) = 0; + + /** + * @brief Query the database by field and value. + * @param query List of dicts containing 'field' and 'value' keys. + * @return List of node IDs. + */ + virtual std::vector get_atoms_by_field( + const std::vector>& query) = 0; + + /** + * @brief Queries the database to return all atoms matching a specific index ID. + * @param index_id The ID of the index to query against. + * @param query A list of ordered dictionaries, each containing field-value pairs. + * @param cursor An optional cursor indicating the starting point within the result set. + * @param chunk_size An optional size indicating the maximum number of atom IDs to retrieve. + * @return A tuple containing the cursor position and a list of retrieved atoms. + */ + virtual std::pair> get_atoms_by_index( + const std::string& index_id, + const std::vector>& query, + int cursor = 0, + int chunk_size = 500) = 0; + + /** + * @brief Query the database by a text field. + * @param text_value Value to search for. + * @param field Field to be used to search. + * @param text_index_id TOKEN_INVERTED_LIST index id to search for. + * @return List of node IDs ordered by the closest match. + */ + virtual std::vector get_atoms_by_text_field( + const std::string& text_value, + const std::string& field = "", + const std::string& text_index_id = "") = 0; + + /** + * @brief Query the database by node name starting with 'startswith' value. + * @param node_type The node type. + * @param startswith The starting substring to search for. + * @return List of node IDs. + */ + virtual std::vector get_node_by_name_starting_with( + const std::string& node_type, const std::string& startswith) = 0; + + /** + * @brief Get all nodes of a specific type. + * @param node_type The node type. + * @param names If True, return node names instead of handles. Default is False. + * @return A list of node handles or names, depending on the value of 'names'. + */ + virtual std::vector get_all_nodes( + const std::string& node_type, bool names = false) = 0; + + /** + * @brief Get all links of a specific type. + * @param link_type The type of the link. + * @return A tuple containing a cursor and a list of link handles. + */ + virtual std::pair> get_all_links( + const std::string& link_type) = 0; + + /** + * @brief Get the handle of the link with the specified type and targets. + * @param link_type The link type. + * @param target_handles A list of link target identifiers. + * @return The link handle. + */ + virtual std::string get_link_handle( + const std::string& link_type, const std::vector& target_handles) = 0; + + /** + * @brief Get the type of the link with the specified handle. + * @param link_handle The link handle. + * @return The link type. + */ + virtual std::string get_link_type(const std::string& link_handle) = 0; + + /** + * @brief Get the target handles of a link specified by its handle. + * @param link_handle The link handle. + * @return A list of target identifiers of the link. + */ + virtual std::vector get_link_targets(const std::string& link_handle) = 0; + + /** + * @brief Check if a link specified by its handle is ordered. + * @param link_handle The link handle. + * @return True if the link is ordered, False otherwise. + */ + virtual bool is_ordered(const std::string& link_handle) = 0; + + /** + * @brief Retrieve incoming links for a specified atom handle. + * @param atom_handle The handle of the atom for which to retrieve incoming links. + * @return A tuple containing the count of incoming links and a list of incoming links. + */ + virtual std::pair get_incoming_links(const std::string& atom_handle) = 0; + + /** + * @brief Retrieve links that match a specified link type and target handles. + * @param link_type The type of the link to match. + * @param target_handles A list of target handles to match. + * @return A tuple containing a cursor and a list of matching link handles. + */ + virtual MatchedLinksResult get_matched_links( + const std::string& link_type, const std::vector& target_handles) = 0; + + /** + * @brief Retrieve links that match a specified type template. + * @param template_ A list representing the type template to match. + * @return A tuple containing a cursor and a list of matching link handles. + */ + virtual MatchedTypesResult get_matched_type_template( + const std::vector& template_) = 0; + + /** + * @brief Retrieve links that match a specified link type. + * @param link_type The type of the link to match. + * @return A tuple containing a cursor and a list of matching link handles. + */ + virtual MatchedTypesResult get_matched_type(const std::string& link_type) = 0; + + /** + * @brief Retrieve an atom by its handle. + * @param handle The handle of the atom to retrieve. + * @param flags A dictionary of flags to control the retrieval process. + * @return A dictionary representation of the atom, if found. + */ + virtual Atom get_atom(const std::string& handle, const Flags& flags = {}) = 0; + + /** + * @brief Retrieve the atom's type by its handle. + * @param handle The handle of the atom to retrieve the type for. + * @return The type of the atom. + */ + virtual std::string get_atom_type(const std::string& handle) = 0; + + /** + * @brief Get an atom as a dictionary representation. + * @param handle The atom handle. + * @param arity The arity of the atom. Defaults to 0. + * @return A dictionary representation of the atom. + */ + virtual std::unordered_map get_atom_as_dict( + const std::string& handle, int arity = 0) = 0; + + /** + * @brief Count the total number of atoms in the database. + * @return A dictionary containing the count of node atoms, link atoms, and total atoms. + */ + virtual std::unordered_map count_atoms() = 0; + + /** + * @brief Clear the entire database, removing all data. + */ + virtual void clear_database() = 0; + + /** + * @brief Adds a node to the database. + * @param node_type The node type. + * @param node_name The node name. + * @return The information about the added node, including its unique key and other details. + */ + virtual Node add_node(const std::string& node_type, const std::string& node_name) = 0; + + /** + * @brief Adds a link to the database. + * @param link_params A dictionary containing link parameters. + * @param toplevel Boolean flag to indicate toplevel links. + * @return The information about the added link, including its unique key and other details. + */ + virtual Link add_link( + const std::string& link_type, + const std::vector& targets, + bool toplevel = true) = 0; + + /** + * @brief Reindex inverted pattern index according to passed templates. + * @param pattern_index_templates Indexes are specified by atom type in a dict mapping from + * atom type to a list of field-value pairs. + */ + virtual void reindex( + const std::unordered_map< + std::string, + std::vector< + std::unordered_map>>& pattern_index_templates) = 0; // TODO: Replace void* with appropriate type + + /** + * @brief Delete an atom from the database. + * @param handle Atom handle. + */ + virtual void delete_atom(const std::string& handle) = 0; + + /** + * @brief Create an index for the specified fields in the database. + * @param atom_type The type of the atom for which the index is created. + * @param fields A list of fields to be indexed. + * @param named_type The named type of the atom. + * @param composite_type A list representing the composite type of the atom. + * @param index_type The type of the index to create. + * @return The ID of the created index. + */ + virtual std::string create_field_index( + const std::string& atom_type, + const std::vector& fields, const std::string& named_type = "", + const std::vector& composite_type = {}, + FieldIndexType index_type = FieldIndexType::BINARY_TREE) = 0; + + /** + * @brief Insert multiple documents into the database. + * @param documents A list of atoms, each representing a document to be inserted into the db. + */ + virtual void bulk_insert(const std::vector& documents) = 0; + + /** + * @brief Retrieve all atoms from the database. + * @return A list of dictionaries representing the atoms. + */ + virtual std::vector retrieve_all_atoms() = 0; + + /** + * @brief Commit the current state of the database. + */ + virtual void commit() = 0; + + protected: + AtomDB() = default; + + /** + * @brief Reformats a document based on the provided flags. + * + * This function takes a document and a set of flags, and reformats the document + * according to the specified flags. + * + * @param document A reference to the Atom object representing the document to be reformatted. + * @param flags A reference to a Flags object containing the reformatting options. + * @return A reference to the reformatted Atom object. + */ + const Atom& reformat_document(Atom& document, const Flags& flags) { + if (Link* link = dynamic_cast(&document)) { + bool targets_documents = flags.find(OnOffParams::TARGETS_DOCUMENTS) != flags.end(); + targets_documents = + targets_documents ? flags.at(OnOffParams::TARGETS_DOCUMENTS) : false; + bool deep_representation = flags.find(OnOffParams::DEEP_REPRESENTATION) != flags.end(); + deep_representation = + deep_representation ? flags.at(OnOffParams::DEEP_REPRESENTATION) : false; + if (targets_documents || deep_representation) { + std::vector targets_documents; + for (const auto& target : link->targets) { + if (deep_representation) { + targets_documents.push_back(get_atom(target, flags)); + } else { + targets_documents.push_back(get_atom(target)); + } + } + link->targets_documents = targets_documents; + } + } + return document; + } + + /** + * @brief Builds a node with the specified type and name. + * + * This function creates a node object using the provided type and name. + * + * @param node_type A string representing the type of the node. + * @param node_name A string representing the name of the node. + * @return A Node object representing the created node. + */ + Node build_node(const std::string& node_type, const std::string& node_name) { + std::string handle = AtomDB::node_handle(node_type, node_name); + return Node(handle, handle, named_type_hash(node_type.c_str()), node_type, node_name); + } + + /** + * @brief Builds a link with the specified type and targets. + * + * This function creates a link object using the provided type and targets. + * + * @param link_type A string representing the type of the link. + * @param target_handles A list of strings representing the handles of the link targets. + * @param is_top_level A boolean value indicating whether the link is top-level. + * @return A Link object representing the created link. + */ + Link build_link( + const std::string& link_type, const std::vector& targets, bool is_top_level = true) { + std::string link_type_hash = named_type_hash(link_type.c_str()); + std::vector target_handles = {}; + std::vector composite_type = {CompositeType(link_type_hash)}; + std::vector composite_type_hash = {link_type_hash}; + std::string atom_hash; + std::string atom_handle; + for (const Atom& target : targets) { + if (const Node* node = dynamic_cast(&target)) { + Node atom = this->add_node(node->named_type, node->name); + atom_handle = atom._id; + atom_hash = atom.composite_type_hash; + composite_type.push_back(atom_hash); + } else if (const Link* link = dynamic_cast(&target)) { + Link atom = this->add_link(link->named_type, link->targets, false); + atom_handle = atom._id; + atom_hash = atom.composite_type_hash; + composite_type.push_back(CompositeType(atom.composite_type)); + } + composite_type_hash.push_back(atom_hash); + target_handles.push_back(atom_handle); + } + + std::string handle = AtomDB::link_handle(link_type, target_handles); + + std::vector elements; + for (const auto& hash : composite_type_hash) { + elements.push_back(hash.c_str()); + } + + Link link = Link( + handle, // id + handle, // handle + composite_hash(elements.data(), elements.size()), // composite_type_hash + link_type, // named_type + composite_type, // composite_type + link_type_hash, // named_type_hash + target_handles, // targets + is_top_level // is_top_level + ); + + uint n = 0; + for (const auto& target_handle : target_handles) { + link.keys["key_" + std::to_string(n)] = target_handle; + n++; + } + + return link; + } + + /** + * @brief Retrieves an atom from the database using its handle. + * + * This function takes a handle and retrieves the corresponding atom from the database. + * + * @param handle A string representing the handle of the atom to be retrieved. + * @return An Atom object representing the retrieved atom. + */ + virtual const Atom& _get_atom(const std::string& handle) = 0; +}; + +#endif // _DATABASE_HPP diff --git a/hyperon_das_atomdb_cpp/utils/expression_hasher.c b/hyperon_das_atomdb_cpp/utils/expression_hasher.c new file mode 100644 index 00000000..bfc5b8cb --- /dev/null +++ b/hyperon_das_atomdb_cpp/utils/expression_hasher.c @@ -0,0 +1,76 @@ +#include "expression_hasher.h" + +#include +#include +#include +#include + +static unsigned char MD5_BUFFER[MD5_DIGEST_LENGTH]; +static char HASH[HANDLE_HASH_SIZE]; +static char HASHABLE_STRING[MAX_HASHABLE_STRING_SIZE]; + +char* compute_hash(const char* input) { + MD5_CTX ctx; + MD5_Init(&ctx); + MD5_Update(&ctx, (const unsigned char*) input, strlen(input)); + MD5_Final(MD5_BUFFER, &ctx); + for (unsigned int i = 0; i < MD5_DIGEST_LENGTH; i++) { + sprintf((char*) ((unsigned long) HASH + 2 * i), "%02x", MD5_BUFFER[i]); + } + HASH[32] = '\0'; + return strdup(HASH); +} + +char* named_type_hash(const char* name) { + return compute_hash(name); +} + +char* terminal_hash(const char* type, const char* name) { + if (strlen(type) + strlen(name) >= MAX_HASHABLE_STRING_SIZE) { + fprintf(stderr, "Invalid (too large) terminal name"); + exit(1); + } + sprintf(HASHABLE_STRING, "%s%c%s", type, JOINING_CHAR, name); + return compute_hash(HASHABLE_STRING); +} + +char* composite_hash(const char** elements, unsigned int nelements) { + unsigned int total_size = 0; + unsigned int element_size[nelements]; + + for (unsigned int i = 0; i < nelements; i++) { + unsigned int size = strlen(elements[i]); + if (size > MAX_LITERAL_OR_SYMBOL_SIZE) { + fprintf(stderr, "Invalid (too large) composite elements"); + exit(1); + } + element_size[i] = size; + total_size += size; + } + if (total_size >= MAX_HASHABLE_STRING_SIZE) { + fprintf(stderr, "Invalid (too large) composite elements"); + exit(1); + } + + unsigned long cursor = 0; + for (unsigned int i = 0; i < nelements; i++) { + if (i == (nelements - 1)) { + strcpy((char*) (HASHABLE_STRING + cursor), elements[i]); + } else { + sprintf((char*) (HASHABLE_STRING + cursor), "%s%c", elements[i], JOINING_CHAR); + cursor += 1; + } + cursor += element_size[i]; + } + + return compute_hash(HASHABLE_STRING); +} + +char* expression_hash(const char* type_hash, const char** elements, unsigned int nelements) { + char* composite[nelements + 1]; + composite[0] = type_hash; + for (unsigned int i = 0; i < nelements; i++) { + composite[i + 1] = elements[i]; + } + return composite_hash(composite, nelements + 1); +} diff --git a/hyperon_das_atomdb_cpp/utils/expression_hasher.h b/hyperon_das_atomdb_cpp/utils/expression_hasher.h new file mode 100644 index 00000000..a8cd35b8 --- /dev/null +++ b/hyperon_das_atomdb_cpp/utils/expression_hasher.h @@ -0,0 +1,67 @@ +#ifndef EXPRESSIONHASHER_H +#define EXPRESSIONHASHER_H + +#define JOINING_CHAR ((char) ' ') +#define MAX_LITERAL_OR_SYMBOL_SIZE ((size_t) 10000) +#define MAX_HASHABLE_STRING_SIZE ((size_t) 100000) +#define HANDLE_HASH_SIZE ((unsigned int) 33) + +/** + * @brief Computes the hash of the given input string. + * + * This function takes an input string, computes its hash, and returns + * the hash as a string. + * + * @param input A string representing the input to be hashed. + * @return A string representing the hash of the input. + */ +const char* compute_hash(const char* input); + +/** + * @brief Generates a hash for a named type. + * + * This function takes a name and generates a hash representing the named type. + * + * @param name A string representing the name of the type. + * @return A string representing the hash of the named type. + */ +const char* named_type_hash(const char* name); + +/** + * @brief Generates a hash for a terminal expression. + * + * This function takes a type and a name, and combines them + * to generate a hash representing the terminal expression. + * + * @param type A string representing the type of the terminal expression. + * @param name A string representing the name of the terminal expression. + * @return A string representing the hash of the terminal expression. + */ +const char* terminal_hash(const char* type, const char* name); + +/** + * @brief Generates a composite hash from an array of element hashes. + * + * This function takes an array of element hashes and combines them + * to generate a single composite hash. + * + * @param elements An array of strings, each representing the hash of an element. + * @param nelements The number of elements in the elements array. + * @return A string representing the combined composite hash. + */ +const char* composite_hash(const char** elements, unsigned int nelements); + +/** + * @brief Generates a hash for an expression. + * + * This function takes a type hash and an array of element hashes, and combines them + * to generate a single hash representing the entire expression. + * + * @param type_hash A string representing the hash of the type. + * @param elements An array of strings, each representing the hash of an element. + * @param nelements The number of elements in the elements array. + * @return A string representing the combined hash of the expression. + */ +const char* expression_hash(const char* type_hash, const char** elements, unsigned int nelements); + +#endif From 9e75256f97151548ebaa7a1aee69990ae1ca2542 Mon Sep 17 00:00:00 2001 From: Angelo Probst Date: Fri, 30 Aug 2024 18:26:39 -0300 Subject: [PATCH 002/130] atom db in cpp - wip --- .../src/adapters/ram_only.hpp | 374 ++++++++++++++++++ hyperon_das_atomdb_cpp/src/basic_types.hpp | 61 ++- hyperon_das_atomdb_cpp/src/database.hpp | 143 +++---- hyperon_das_atomdb_cpp/src/exceptions.hpp | 21 + .../utils/expression_hasher.c | 76 ---- .../utils/expression_hasher.h | 67 ---- .../utils/expression_hasher.hpp | 117 ++++++ hyperon_das_atomdb_cpp/utils/flags.hpp | 96 +++++ 8 files changed, 722 insertions(+), 233 deletions(-) create mode 100644 hyperon_das_atomdb_cpp/src/adapters/ram_only.hpp create mode 100644 hyperon_das_atomdb_cpp/src/exceptions.hpp delete mode 100644 hyperon_das_atomdb_cpp/utils/expression_hasher.c delete mode 100644 hyperon_das_atomdb_cpp/utils/expression_hasher.h create mode 100644 hyperon_das_atomdb_cpp/utils/expression_hasher.hpp create mode 100644 hyperon_das_atomdb_cpp/utils/flags.hpp diff --git a/hyperon_das_atomdb_cpp/src/adapters/ram_only.hpp b/hyperon_das_atomdb_cpp/src/adapters/ram_only.hpp new file mode 100644 index 00000000..66efa82a --- /dev/null +++ b/hyperon_das_atomdb_cpp/src/adapters/ram_only.hpp @@ -0,0 +1,374 @@ +#ifndef _RAM_ONLY +#define _RAM_ONLY + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../basic_types.hpp" +#include "../database.hpp" +#include "../utils/expression_hasher.hpp" + +class Database { + public: + /** + * @brief Class representing the structure of the in-memory database. + */ + + using Pattern = std::tuple; + using PatternsSet = std::unordered_set; + using Template = std::tuple; + using TemplatesSet = std::unordered_set