diff options
| author | Christian Krinitsin <mail@krinitsin.com> | 2025-03-21 22:13:38 +0100 |
|---|---|---|
| committer | Christian Krinitsin <mail@krinitsin.com> | 2025-03-21 22:13:38 +0100 |
| commit | 7212db13b9013aa15673ae65da65eeaf97ee0d12 (patch) | |
| tree | 9346b38f25ab5880af3f40e49ba1e64c4f7e0ca2 | |
| parent | b67a507e2ef0db4970f04df5c5a52d9b9e9dd74d (diff) | |
| download | BT-Programming-Assignment-7212db13b9013aa15673ae65da65eeaf97ee0d12.tar.gz BT-Programming-Assignment-7212db13b9013aa15673ae65da65eeaf97ee0d12.zip | |
add doxygen-comments for each member
Diffstat (limited to '')
| -rw-r--r-- | src/client/client.h | 51 | ||||
| -rw-r--r-- | src/common/shared_memory.h | 19 | ||||
| -rw-r--r-- | src/server/hashtable.h | 65 | ||||
| -rw-r--r-- | src/server/shared_memory_server.h | 30 |
4 files changed, 164 insertions, 1 deletions
diff --git a/src/client/client.h b/src/client/client.h index 852ade3..bc2d702 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -11,22 +11,73 @@ #include <utility> #include "shared_memory.h" + +/** + * @class Client + * @brief Represents the client, which performs actions on the hashtable of the server. + */ class Client { public: + /** + * @brief Constructs a new client and opens the shared memory. + */ Client(); + + /** + * @brief Unmaps the shared memory. + */ ~Client(); + /** + * @brief Main client program. + * + * @details The user can choose the operation and the arguments, which will be sent to the + * server. + */ void start_client(); private: + /** + * @brief Memory which is shared with the server. + */ SharedMemory* shared_memory; + + /** + * @brief File descriptor for the shared memory, used to unmap and close the memory at the end. + */ int shm_fd; + /** + * @brief Sends a request to the server. + * + * @param shared_memory The memory to use. + * @param type The type of the operation the server has to process. + * @param k First potential argument of the request, represents the key. + * @param v Second potential argument of the request, represent the value. + * @return int The index of the request in the circular-buffer, so we can access it again for + * processing the respond. + */ int send_request( SharedMemory* shared_memory, Operations type, std::optional<const std::string> k, std::optional<const std::string> v); + + /** + * @brief Determines if the request was processed by the server. + * + * @param shared_memory The memory to use. + * @param index The index of the request in the circular-buffer. + * @return bool The request was processed by the server. + */ bool request_processed(SharedMemory* shared_memory, int index); + + /** + * @brief Processes the respond of the server. + * + * @param shared_memory The memory to use. + * @param index The index of the request in the circular-buffer. + * @return std::string The response of the server as a string. + */ std::string process_respond(SharedMemory* shared_memory, int index); }; diff --git a/src/common/shared_memory.h b/src/common/shared_memory.h index 70554e4..fe101ea 100644 --- a/src/common/shared_memory.h +++ b/src/common/shared_memory.h @@ -9,8 +9,14 @@ #define MAX_KEY_SIZE 64 #define MAX_VALUE_SIZE 128 +/** + * @brief Possible operations on the hashtable. + */ enum Operations { INSERT, DELETE, GET, PRINT }; +/** + * @brief One request constists out of the operation, the arguments and the response. + */ struct Request { Operations type; char key[MAX_KEY_SIZE]; @@ -18,6 +24,13 @@ struct Request { char response[MAX_VALUE_SIZE]; }; +/** + * @brief The shared memory between client and server. + * + * @details The shared memory consists out of: + * - A circular-buffer, to de- and enqueue multiple request at once. + * - A mutex with a conditional variable, to ensure concurrency of the buffer. + */ struct SharedMemory { Request request[QUEUE_SIZE]; pthread_mutex_t mutex; @@ -28,6 +41,9 @@ struct SharedMemory { bool full; }; +/** + * @brief Converts a generic type to a stringstream, so that it can be saved in the shared memory. + */ template <typename T> std::string serialize(const T& data) { @@ -36,6 +52,9 @@ std::string serialize(const T& data) return oss.str(); } +/** + * @brief Converts a stringstream to a generic type, so that value in the shared memory can be read. + */ template <typename T> T deserialize(const std::string& str) { diff --git a/src/server/hashtable.h b/src/server/hashtable.h index 2538e76..e09fcd4 100644 --- a/src/server/hashtable.h +++ b/src/server/hashtable.h @@ -9,9 +9,18 @@ #include <sstream> #include <vector> +/** + * @class HashTable + * @brief Represents a generic hashtable with simple operations. + */ template <typename K, typename V> class HashTable { public: + /** + * @brief Constructs a new Hashtable. + * + * @param size The number of buckets of the table. + */ HashTable(size_t size) : size { size } , table(size) @@ -19,6 +28,13 @@ public: { } + /** + * @brief Insert a kv-pair into the hashtable. + * + * @param key The key to determine the bucket. + * @param value The value to insert. + * @return bool Successful insert of the pair. + */ bool insert(K key, V value) { size_t index = get_bucket_index(key); @@ -35,6 +51,12 @@ public: return true; } + /** + * @brief Gets the value which corresponds to the key. + * + * @param key The key to look for. + * @return std::optional The value, if the key could be found. + */ std::optional<V> get(K key) { size_t index = get_bucket_index(key); @@ -50,6 +72,12 @@ public: return std::optional<V>(); } + /** + * @brief Removes the kv-pair which corresponds to the key. + * + * @param key The key to look for. + * @return bool The pair could be removed successfully. + */ bool remove(K key) { size_t index = get_bucket_index(key); @@ -66,6 +94,11 @@ public: return false; } + /** + * @brief Constructs a string representation of the hashtable. + * + * @return std::string The string of the hashtable. + */ std::string string() { std::ostringstream output; @@ -85,14 +118,33 @@ public: } private: + /** + * @brief The number of buckets. + */ size_t size; + /** + * @brief The hashtable. + */ std::vector<std::list<std::pair<K, V>>> table; + /** + * @brief A mutex for every button. + */ std::vector<std::shared_mutex> bucket_mutexes; + /** + * @brief The hashfunction to use for the bucket determination. + */ std::hash<K> hash_function; + /** + * @brief Finds the kv-pair inside a bucket. + * + * @param list The bucket. + * @param key The key to look for. + * @return auto The iterator element, which points to the kv-pair or list.end(). + */ auto bucket_find_key(std::list<std::pair<K, V>>& list, K key) { return std::find_if(list.begin(), list.end(), [&key](const std::pair<K, V>& pair) { @@ -100,10 +152,23 @@ private: }); } + /** + * @brief Checks if the bucket contains the key. + * + * @param list The bucket. + * @param key The key to look for. + * @return bool The bucket contains the key. + */ bool bucket_contains_key(std::list<std::pair<K, V>>& list, K key) { return list.begin() != list.end() && bucket_find_key(list, key) != list.end(); } + /** + * @brief Uses the hashfunction and the key to determine, which bucket to use. + * + * @param key The key. + * @return size_t The index of the bucket. + */ size_t get_bucket_index(K key) { return hash_function(key) % size; } }; diff --git a/src/server/shared_memory_server.h b/src/server/shared_memory_server.h index aa0e261..4580d1a 100644 --- a/src/server/shared_memory_server.h +++ b/src/server/shared_memory_server.h @@ -8,9 +8,19 @@ #include <sys/mman.h> #include <unistd.h> +/** + * @class Server + * @brief Represents the server, which performs operations on the hashtable based on the requests of + * the client. + */ template <typename K, typename V> class Server { public: + /** + * @brief Constructs a new hashtable and initializes a shared memory buffer. + * + * @param size The number of buckets in the hashtable. + */ Server(size_t size) : hash_table(size) { @@ -34,6 +44,9 @@ public: pthread_cond_init(&shared_memory->cond_var, &cond_attr); } + /** + * @brief Unmaps and unlinks the shared memory. + */ ~Server() { munmap(shared_memory, sizeof(SharedMemory)); @@ -41,6 +54,11 @@ public: shm_unlink(SHM_NAME); } + /** + * @brief The main loop of the server. + * + * @details The server checks the shared memory for new requests and executes them. + */ void process_requests() { while (true) { @@ -121,8 +139,18 @@ public: } private: + /** + * @brief The hashtable. + */ HashTable<K, V> hash_table; - int shm_fd; + /** + * @brief Memory which is shared with the client. + */ SharedMemory* shared_memory; + + /** + * @brief File descriptor for the shared memory, used to unmap and close the memory at the end. + */ + int shm_fd; }; |