188 lines
6.0 KiB
C++
188 lines
6.0 KiB
C++
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <sys/mman.h>
|
|
#include <iostream>
|
|
#include <cstring>
|
|
#include <thread>
|
|
#include <chrono>
|
|
#include <sys/stat.h>
|
|
|
|
#include "core/SharedCommandQueue.h"
|
|
#include "utils/hash/Hash128.h"
|
|
|
|
// int main()
|
|
// {
|
|
// constexpr const char* shm_name = "/shm_rates1";
|
|
// constexpr size_t shm_size = sizeof(usub::core::SharedCommandQueue);
|
|
//
|
|
// int shm_fd = shm_open(shm_name, O_RDWR, 0600);
|
|
// if (shm_fd == -1)
|
|
// {
|
|
// perror("shm_open failed");
|
|
// return 1;
|
|
// }
|
|
//
|
|
// void* ptr = mmap(nullptr, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
|
|
// if (ptr == MAP_FAILED)
|
|
// {
|
|
// perror("mmap failed");
|
|
// close(shm_fd);
|
|
// return 1;
|
|
// }
|
|
//
|
|
// auto* queue = static_cast<usub::core::SharedCommandQueue*>(ptr);
|
|
// std::cout << "[CLIENT] Connected to shared memory.\n";
|
|
//
|
|
// size_t head = queue->head().load(std::memory_order_relaxed);
|
|
// size_t next_head = (head + 1) % queue->capacity();
|
|
// while (next_head == queue->tail().load(std::memory_order_acquire))
|
|
// {
|
|
// std::this_thread::sleep_for(std::chrono::milliseconds(1)); // wait
|
|
// }
|
|
//
|
|
// usub::core::Command* slot = &queue->raw_buffer()[head];
|
|
//
|
|
// // заполняем slot
|
|
// slot->op = usub::core::OperationType::PUT;
|
|
// slot->key = usub::utils::compute_hash128("test_key", 9);
|
|
// const char* put_value = "test_value";
|
|
// slot->value_size = std::strlen(put_value);
|
|
// std::memcpy(slot->value, put_value, slot->value_size);
|
|
// slot->response_size = 0;
|
|
// slot->response_ready.store(0, std::memory_order_relaxed);
|
|
//
|
|
// slot->ready.store(1, std::memory_order_release);
|
|
//
|
|
// // обновляем head
|
|
// queue->head().store(next_head, std::memory_order_release);
|
|
//
|
|
// std::cout << "[CLIENT] PUT command sent.\n";
|
|
//
|
|
// // Ожидание, можно реализовать FIND аналогично.
|
|
//
|
|
// munmap(ptr, shm_size);
|
|
// close(shm_fd);
|
|
//
|
|
// return 0;
|
|
// }
|
|
|
|
int main()
|
|
{
|
|
constexpr const char* shm_name = "/shm_rates1";
|
|
constexpr size_t capacity = 1024; // или то, что реально
|
|
size_t shm_size = usub::core::SharedCommandQueue::calculate_shm_size(capacity);
|
|
|
|
int shm_fd = shm_open(shm_name, O_RDWR, 0600);
|
|
if (shm_fd == -1)
|
|
{
|
|
perror("shm_open failed");
|
|
return 1;
|
|
}
|
|
|
|
// struct stat statbuf;
|
|
// if (fstat(shm_fd, &statbuf) == -1)
|
|
// {
|
|
// perror("fstat failed");
|
|
// close(shm_fd);
|
|
// return 1;
|
|
// }
|
|
|
|
// void* ptr = mmap(nullptr, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
|
|
void* ptr = mmap(nullptr, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
|
|
if (ptr == MAP_FAILED)
|
|
{
|
|
perror("mmap failed");
|
|
close(shm_fd);
|
|
return 1;
|
|
}
|
|
|
|
auto* queue = static_cast<usub::core::SharedCommandQueue*>(ptr);
|
|
std::cout << "[CLIENT] Connected to shared memory.\n";
|
|
|
|
// -------------------
|
|
// PUT Command
|
|
// -------------------
|
|
{
|
|
std::cout << "1\n";
|
|
auto head = queue->head().load(std::memory_order_relaxed);
|
|
size_t next_head = (head + 1) % queue->capacity();
|
|
while (next_head == queue->tail().load(std::memory_order_acquire))
|
|
{
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
}
|
|
std::cout << "2\n";
|
|
|
|
usub::core::Command* slot = &queue->raw_buffer()[head];
|
|
|
|
std::cout << "queue = " << queue << '\n';
|
|
std::cout << "queue->capacity() = " << queue->capacity() << '\n';
|
|
std::cout << "head = " << head << '\n';
|
|
std::cout << "ptr to raw_buffer = " << static_cast<void*>(queue->raw_buffer()) << '\n';
|
|
std::cout << "ptr to slot = " << static_cast<void*>(&queue->raw_buffer()[head]) << '\n';
|
|
std::cout.flush();
|
|
|
|
slot->op = usub::core::OperationType::PUT;
|
|
slot->key = usub::utils::compute_hash128("test_key", 8); // исправил длину "test_key" = 8 символов
|
|
const char* put_value = "test_value";
|
|
slot->value_size = std::strlen(put_value);
|
|
std::cout << "3\n";
|
|
std::memcpy(slot->value, put_value, slot->value_size);
|
|
std::cout << "4\n";
|
|
slot->response_size = 0;
|
|
slot->response_ready.store(0, std::memory_order_relaxed);
|
|
|
|
slot->ready.store(1, std::memory_order_release);
|
|
queue->head().store(next_head, std::memory_order_release);
|
|
|
|
std::cout << "[CLIENT] PUT command sent.\n";
|
|
}
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(50)); // дать серверу время
|
|
|
|
// -------------------
|
|
// FIND Command
|
|
// -------------------
|
|
{
|
|
size_t head = queue->head().load(std::memory_order_relaxed);
|
|
size_t next_head = (head + 1) % queue->capacity();
|
|
while (next_head == queue->tail().load(std::memory_order_acquire))
|
|
{
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
}
|
|
|
|
usub::core::Command* slot = &queue->raw_buffer()[head];
|
|
|
|
slot->op = usub::core::OperationType::FIND;
|
|
slot->key = usub::utils::compute_hash128("test_key", 8);
|
|
slot->value_size = 0;
|
|
slot->response_size = 0;
|
|
slot->response_ready.store(0, std::memory_order_relaxed);
|
|
|
|
slot->ready.store(1, std::memory_order_release);
|
|
queue->head().store(next_head, std::memory_order_release);
|
|
|
|
std::cout << "[CLIENT] FIND command sent.\n";
|
|
|
|
// Ожидание ответа
|
|
while (slot->response_ready.load(std::memory_order_acquire) == 0)
|
|
{
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
}
|
|
|
|
if (slot->response_size > 0)
|
|
{
|
|
std::string result(reinterpret_cast<char*>(slot->response), slot->response_size);
|
|
std::cout << "[CLIENT] FIND result: " << result << "\n";
|
|
}
|
|
else
|
|
{
|
|
std::cout << "[CLIENT] FIND result: not found\n";
|
|
}
|
|
}
|
|
|
|
munmap(ptr, shm_size);
|
|
close(shm_fd);
|
|
|
|
return 0;
|
|
}
|