diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | src/client/client.cpp | 134 | ||||
| -rw-r--r-- | src/client/client.h | 32 | ||||
| -rw-r--r-- | src/client/main.cpp | 112 | ||||
| -rw-r--r-- | src/server/main.cpp | 2 |
5 files changed, 171 insertions, 111 deletions
diff --git a/Makefile b/Makefile index b526fed..7c250ef 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ CXXFLAGS := -std=c++23 -Wall -Wextra -Wpedantic -O3 -Isrc/common all: server client server: src/server/main.cpp ${CXX} ${CXXFLAGS} $^ -o $@ -client: src/client/main.cpp +client: src/client/main.cpp src/client/client.cpp ${CXX} ${CXXFLAGS} $^ -o $@ .PHONY: clean diff --git a/src/client/client.cpp b/src/client/client.cpp new file mode 100644 index 0000000..d88df5f --- /dev/null +++ b/src/client/client.cpp @@ -0,0 +1,134 @@ +#include "client.h" +#include "shared_memory.h" +#include <optional> + +Client::Client() +{ + shm_fd = shm_open(SHM_NAME, O_RDWR, 0666); + if (shm_fd == -1) { + std::cout << "Server not running" << '\n'; + return; + } + + shared_memory = + (SharedMemory*)mmap(0, sizeof(SharedMemory), PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); +} + +Client::~Client() +{ + munmap(shared_memory, sizeof(SharedMemory)); + close(shm_fd); +} + +void Client::start_client() +{ + while (true) { + char operation; + int k, v; + std::cout << "Choose the operation (i: Insert, g: Get, r: Remove, p: Print, e: Exit)" + << '\n'; + std::cin >> operation; + switch (operation) { + case 'e': + return; + case 'i': + std::cout << "Insert: Enter the k-v pair(<int> <int>):" << '\n'; + if (!(std::cin >> k >> v)) { + std::cout << "Invalid input" << '\n'; + std::cin.clear(); + std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); + break; + }; + send_request( + shared_memory, INSERT, std::optional(serialize(k)), std::optional(serialize(v))); + break; + case 'g': { + std::cout << "Get: Enter the key(<int>):" << '\n'; + if (!(std::cin >> k)) { + std::cout << "Invalid input" << '\n'; + std::cin.clear(); + std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); + break; + }; + int index = send_request(shared_memory, GET, std::optional(serialize(k)), std::nullopt); + std::string response = process_result(shared_memory, index); + std::cout << "Got: " << response << '\n'; + break; + } + case 'r': + std::cout << "Remove: Enter key(<int>):" << '\n'; + if (!(std::cin >> k)) { + std::cout << "Invalid input" << '\n'; + std::cin.clear(); + std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); + break; + }; + send_request(shared_memory, DELETE, std::optional(serialize(k)), std::nullopt); + break; + case 'p': + send_request(shared_memory, PRINT, std::nullopt, std::nullopt); + break; + default: + break; + } + std::cout << '\n'; + } +} + +bool Client::request_processed(SharedMemory* shared_memory, int index) +{ + if (shared_memory->full) { + return false; + } + if (shared_memory->tail == shared_memory->head && !shared_memory->full) { + return true; + } + + for (int i = shared_memory->head - 1; i != shared_memory->tail; i = (i - 1) % QUEUE_SIZE) { + if (i == index) { + return false; + } + } + + return shared_memory->tail != index; +} + +int Client::send_request( + SharedMemory* shared_memory, + Operations type, + std::optional<const std::string> k, + std::optional<const std::string> v) +{ + int index; + + pthread_mutex_lock(&shared_memory->mutex); + + while (shared_memory->full) { + pthread_cond_wait(&shared_memory->cond_var, &shared_memory->mutex); + } + + index = shared_memory->head; + Request* request = &shared_memory->request[index]; + request->type = type; + strncpy(request->key, k.value_or("null").c_str(), MAX_KEY_SIZE); + strncpy(request->value, v.value_or("null").c_str(), MAX_VALUE_SIZE); + shared_memory->head = (1 + shared_memory->head) % QUEUE_SIZE; + shared_memory->full = shared_memory->head == shared_memory->tail; + pthread_cond_signal(&shared_memory->cond_var); + + pthread_mutex_unlock(&shared_memory->mutex); + + return index; +} + +std::string Client::process_result(SharedMemory* shared_memory, int index) +{ + pthread_mutex_lock(&shared_memory->mutex); + + while (!request_processed(shared_memory, index)) { + pthread_cond_wait(&shared_memory->cond_var, &shared_memory->mutex); + } + std::string result(shared_memory->request[index].response); + pthread_mutex_unlock(&shared_memory->mutex); + return result; +} diff --git a/src/client/client.h b/src/client/client.h new file mode 100644 index 0000000..9ff5b47 --- /dev/null +++ b/src/client/client.h @@ -0,0 +1,32 @@ +#pragma once + +#include <cstring> +#include <fcntl.h> +#include <iostream> +#include <optional> +#include <pthread.h> +#include <string> +#include <sys/mman.h> +#include <unistd.h> +#include <utility> + +#include "shared_memory.h" +class Client { +public: + Client(); + ~Client(); + + void start_client(); + +private: + SharedMemory* shared_memory; + int shm_fd; + + int send_request( + SharedMemory* shared_memory, + Operations type, + std::optional<const std::string> k, + std::optional<const std::string> v); + bool request_processed(SharedMemory* shared_memory, int index); + std::string process_result(SharedMemory* shared_memory, int index); +}; diff --git a/src/client/main.cpp b/src/client/main.cpp index 6dfd48f..ca2f4a3 100644 --- a/src/client/main.cpp +++ b/src/client/main.cpp @@ -1,115 +1,9 @@ -#include "shared_memory.h" -#include <cstring> -#include <fcntl.h> -#include <iostream> -#include <pthread.h> -#include <sys/mman.h> -#include <unistd.h> -#include <utility> +#include "client.h" -bool request_processed(SharedMemory* shared_memory, int index) -{ - if (shared_memory->full) { - return false; - } - if (shared_memory->tail == shared_memory->head && !shared_memory->full) { - return true; - } - - for (int i = shared_memory->head - 1; i != shared_memory->tail; i = (i - 1) % QUEUE_SIZE) { - if (i == index) { - return false; - } - } - - return shared_memory->tail != index; -} - -void send_request( - SharedMemory* shared_memory, - Operations type, - std::pair<const std::string&, const std::string&> arguments) -{ - int index; - - pthread_mutex_lock(&shared_memory->mutex); - - if (shared_memory->full) { - std::cout << "Queue is full" << '\n'; - pthread_cond_wait(&shared_memory->cond_var, &shared_memory->mutex); - return; - } - - index = shared_memory->head; - Request* request = &shared_memory->request[index]; - request->type = type; - strncpy(request->key, serialize(arguments.first).c_str(), MAX_KEY_SIZE); - strncpy(request->value, serialize(arguments.second).c_str(), MAX_VALUE_SIZE); - shared_memory->head = (1 + shared_memory->head) % QUEUE_SIZE; - shared_memory->full = shared_memory->head == shared_memory->tail; - pthread_cond_signal(&shared_memory->cond_var); - - pthread_mutex_unlock(&shared_memory->mutex); - - std::cout << "Command sent" << '\n'; - - if (type == Operations::GET) { - pthread_mutex_lock(&shared_memory->mutex); - - while (!request_processed(shared_memory, index)) { - pthread_cond_wait(&shared_memory->cond_var, &shared_memory->mutex); - } - std::string result(shared_memory->request[index].response); - pthread_mutex_unlock(&shared_memory->mutex); - std::cout << "Result: " << result << std::endl; - } -} int main() { - int shm_fd = shm_open(SHM_NAME, O_RDWR, 0666); - if (shm_fd == -1) { - std::cout << "Server not running" << '\n'; - return -1; - } - - SharedMemory* shared_memory = - (SharedMemory*)mmap(0, sizeof(SharedMemory), PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); - - std::cout << "Start inserting.." << '\n'; - send_request(shared_memory, INSERT, std::pair(serialize(3), serialize(3))); - - std::cout << "Start inserting.." << '\n'; - send_request(shared_memory, INSERT, std::pair(serialize(4), serialize(5))); - - std::cout << "Start inserting.." << '\n'; - send_request(shared_memory, INSERT, std::pair(serialize(6), serialize(6))); - - std::cout << "Start inserting.." << '\n'; - send_request(shared_memory, INSERT, std::pair(serialize(7), serialize(3))); - - std::cout << "Start inserting.." << '\n'; - send_request(shared_memory, INSERT, std::pair(serialize(8), serialize(3))); - - std::cout << "Start inserting.." << '\n'; - send_request(shared_memory, INSERT, std::pair(serialize(9), serialize(3))); - - std::cout << "Start inserting.." << '\n'; - send_request(shared_memory, INSERT, std::pair(serialize(10), serialize(3))); - - std::cout << "Start inserting.." << '\n'; - send_request(shared_memory, INSERT, std::pair(serialize(11), serialize(3))); - - std::cout << "Start inserting.." << '\n'; - send_request(shared_memory, INSERT, std::pair(serialize(12), serialize(3))); - - std::cout << "Start inserting.." << '\n'; - send_request(shared_memory, INSERT, std::pair(serialize(13), serialize(4))); - - std::cout << "Start PRINTING.." << '\n'; - send_request(shared_memory, PRINT, std::pair(serialize(0), serialize(0))); + Client client; - munmap(shared_memory, sizeof(SharedMemory)); - close(shm_fd); - return 0; + client.start_client(); } diff --git a/src/server/main.cpp b/src/server/main.cpp index 424326f..d4890aa 100644 --- a/src/server/main.cpp +++ b/src/server/main.cpp @@ -20,7 +20,7 @@ int main(int argc, char* argv[]) return 1; } - SharedMemoryServer<int, std::string> shm(size); + SharedMemoryServer<int, int> shm(size); shm.process_requests(); |