Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: setup build env for kvssd and add skeleton code for kvssd-hashmap interface #3

Merged
merged 2 commits into from
Dec 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ endif()

option(BIND_ROCKSDB "build with rocksdb" OFF)
option(BIND_LMDB "build with lmdb" OFF)
option(BIND_KVSSD "build with kvssd" OFF)
option(BIND_LEVELDB "build with leveldb" OFF)
option(BIND_WIREDTIGER "build with wiredtiger" OFF)

Expand Down Expand Up @@ -84,6 +85,26 @@ else()
message(STATUS "BIND_LMDB - OFF")
endif()

if (BIND_KVSSD)
message(STATUS "BIND_KVSSD - ON")
file(GLOB_RECURSE YCSB_KVSSD_SRC "kvssd/*.cc")
target_sources(ycsb PRIVATE ${YCSB_KVSSD_SRC})

find_package(kvssd CONFIG)
if(kvssd_FOUND)
target_link_libraries(ycsb PRIVATE kvssd)
else()
message(STATUS "Try to find kvssd library using find_library")
find_library(KVSSD_LIB kvssd REQUIRED)
find_path(KVSSD_INCLUDE_DIR "kvssd.h" REQUIRED)
target_link_libraries(ycsb PRIVATE ${KVSSD_LIB})
target_include_directories(ycsb PRIVATE ${KVSSD_INCLUDE_DIR})
endif()
message(STATUS "Found KVSSD library")
else()
message(STATUS "BIND_KVSSD - OFF")
endif()

if (BIND_LEVELDB)
message(STATUS "BIND_LEVELDB - ON")
file(GLOB_RECURSE YCSB_LEVELDB_SRC "leveldb/*.cc")
Expand Down
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ BIND_LEVELDB ?= 0
BIND_ROCKSDB ?= 0
BIND_LMDB ?= 0
BIND_SQLITE ?= 0
BIND_KVSSD ?= 0

# Extra options
DEBUG_BUILD ?=
Expand Down Expand Up @@ -61,6 +62,11 @@ ifeq ($(BIND_SQLITE), 1)
SOURCES += $(wildcard sqlite/*.cc)
endif

ifeq ($(BIND_KVSSD), 1)
LDFLAGS += -lkvssd
SOURCES += $(wildcard kvssd/*.cc)
endif

CXXFLAGS += -std=c++17 -Wall -pthread $(EXTRA_CXXFLAGS) -I./
LDFLAGS += $(EXTRA_LDFLAGS) -lpthread
SOURCES += $(wildcard core/*.cc)
Expand Down
7 changes: 7 additions & 0 deletions kvssd/kvssd.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
kvssd.dbpath=/tmp/ycsb-kvssd
kvssd.mapsize=1073741824
kvssd.nosync=true
kvssd.nometasync=false
kvssd.noreadahead=false
kvssd.writemap=false
kvssd.mapasync=false
90 changes: 90 additions & 0 deletions kvssd/kvssd_hashmap_db.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#include <string>
#include <mutex>
#include "kvssd_hashmap_db.h"

#include <kvssd.h>

const char *kvstrerror[] = {
"Successful", // KVS_SUCCESS
"Buffer space is not enough", // KVS_ERR_BUFFER_SMALL
"Device does not have enough space", // KVS_ERR_DEV_CAPAPCITY
"No device with the dev_hd exists", // KVS_ERR_DEV_NOT_EXIST
"Key space does not have enough space", // KVS_ERR_KS_CAPACITY
"Key space is already created", // KVS_ERR_KS_EXIST
"Index is not valid", // KVS_ERR_KS_INDEX
"Key space name is not valid", // KVS_ERR_KS_NAME
"Key space does not exist", // KVS_ERR_KS_NOT_EXIST
"Key space does not open", // KVS_ERR_KS_NOT_OPEN
"Key space is already opened", // KVS_ERR_KS_OPEN
"Iterator filter is not valid", // KVS_ERR_ITERATOR_FILTER_INVALID
"Maximum number of iterators opened", // KVS_ERR_ITERATOR_MAX
"Iterator Key Group does not exist", // KVS_ERR_ITERATOR_NOT_EXIST
"Iterator is already opened", // KVS_ERR_ITERATOR_OPEN
"Key is not valid", // KVS_ERR_KEY_LENGTH_INVALID
"Key does not exist", // KVS_ERR_KEY_NOT_EXIST
"Option is not supported", // KVS_ERR_OPTION_INVALID
"Null input parameter", // KVS_ERR_PARAM_INVALID
"I/O error occurs", // KVS_ERR_SYS_IO
"Value length is out of range", // KVS_ERR_VALUE_LENGTH_INVALID
"Value offset is out of range", // KVS_ERR_VALUE_OFFSET_INVALID
"Value offset is misaligned", // KVS_ERR_VALUE_OFFSET_MISALIGNED
"Value update is not allowed", // KVS_ERR_VALUE_UPDATE_NOT_ALLOWED
"Device was not opened yet" // KVS_ERR_DEV_NOT_OPENED
};

Hashmap_KVSSD::Hashmap_KVSSD()
{
// initialize
}
Hashmap_KVSSD::~Hashmap_KVSSD()
{
// cleanup
}

/** @todo
* @brief Read API ํ•จ์ˆ˜
* @param[in] key ์ฐพ์„ row์˜ key
* @param[out] value_out ์ฐพ์€ row์˜ value
* @return kvs_result
*/
kvs_result Hashmap_KVSSD::Read(const kvs_key &key, kvs_value &value_out)
{
return KVS_SUCCESS;
}

/** @todo
* @brief Insert API ํ•จ์ˆ˜
* @param[in] key ์ถ”๊ฐ€ํ•  row์˜ key
* @param[in] value ์ถ”๊ฐ€ํ•  row์˜ value
* @return kvs_result
*/
kvs_result Hashmap_KVSSD::Insert(const kvs_key &key, const kvs_value &value)
{
return KVS_SUCCESS;
}

/** @todo
* @brief Update API ํ•จ์ˆ˜
* @param[in] key ๊ฒ€์ƒ‰ ๋ฐ ๋ณ€๊ฒฝํ•  row์˜ key
* @param[in] value ๊ฒ€์ƒ‰ ๋ฐ ๋ณ€๊ฒฝํ•  row์˜ value
* @return kvs_result
*/
kvs_result Hashmap_KVSSD::Update(const kvs_key &key, const kvs_value &value)
{
return KVS_SUCCESS;
}

/** @todo
* @brief Delete API ํ•จ์ˆ˜
* @param[in] key ์‚ญ์ œํ•  row์˜ key
* @return kvs_result
*/
kvs_result Hashmap_KVSSD::Delete(const kvs_key &key)
{
return KVS_SUCCESS;
}

KVSSD *NewKvssdDB()
{
return new Hashmap_KVSSD;
}
153 changes: 153 additions & 0 deletions kvssd/kvssd_hashmap_db.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
#ifndef YCSB_C_KVSSD_HASHMAP_DB_H_
#define YCSB_C_KVSSD_HASHMAP_DB_H_

#include <unordered_map>
#include <cstring>

#include <kvssd.h>

/**
* @brief kvssd API ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ์ž๋ฃŒํ˜•
*/
typedef enum
{
KVS_SUCCESS = 0, // Successful
KVS_ERR_BUFFER_SMALL = 0x001, // buffer space is not enough
KVS_ERR_DEV_CAPAPCITY = 0x002, // device does not have enough space. Key Space size is too big
KVS_ERR_DEV_NOT_EXIST = 0x003, // no device with the dev_hd exists
KVS_ERR_KS_CAPACITY = 0x004, // key space does not have enough space
KVS_ERR_KS_EXIST = 0x005, // key space is already created with the same name
KVS_ERR_KS_INDEX = 0x006, // index is not valid
KVS_ERR_KS_NAME = 0x007, // key space name is not valid
KVS_ERR_KS_NOT_EXIST = 0x008, // key space does not exist
KVS_ERR_KS_NOT_OPEN = 0x009, // key space does not open
KVS_ERR_KS_OPEN = 0x00A, // key space is already opened
KVS_ERR_ITERATOR_FILTER_INVALID = 0x00B, // iterator filter(match bitmask and pattern) is not valid
KVS_ERR_ITERATOR_MAX = 0x00C, // the maximum number of iterators that a device supports is opened
KVS_ERR_ITERATOR_NOT_EXIST = 0x00D, // the iterator Key Group does not exist
KVS_ERR_ITERATOR_OPEN = 0x00E, // iterator is already opened
KVS_ERR_KEY_LENGTH_INVALID = 0x00F, // key is not valid (e.g., key length is not supported)
KVS_ERR_KEY_NOT_EXIST = 0x010, // key does not exist
KVS_ERR_OPTION_INVALID = 0x011, // an option is not supported in this implementation
KVS_ERR_PARAM_INVALID = 0x012, // null input parameter
KVS_ERR_SYS_IO = 0x013, // I/O error occurs
KVS_ERR_VALUE_LENGTH_INVALID = 0x014, // value length is out of range
KVS_ERR_VALUE_OFFSET_INVALID = 0x015, // value offset is out of range
KVS_ERR_VALUE_OFFSET_MISALIGNED = 0x016, // offset of value is required to be aligned to KVS_ALIGNMENT_UNIT
KVS_ERR_VALUE_UPDATE_NOT_ALLOWED = 0x017, // key exists but value update is not allowed
KVS_ERR_DEV_NOT_OPENED = 0x018, // device was not opened yet
} kvs_result;

/**
* @brief kvs_result์„ Index, ๋Œ€์‘๋˜๋Š” ์—๋Ÿฌ๋ฌธ์„ Value๋กœ ๊ฐ–๋Š” ๋ฐฐ์—ด
*/
extern const char *kvstrerror[];

/**
* @brief DB row์˜ Value vector์˜ ์›์†Œ ํƒ€์ž…
*/
struct Field
{
std::string name;
std::string value;
};

/**
* @brief DB row์˜ key struct type
*/
struct kvs_key
{
void *key;
uint16_t length;

~kvs_key()
{
delete[] static_cast<char *>(key);
}

bool operator==(const kvs_key &other) const
{
return length == other.length &&
std::memcmp(key, other.key, length) == 0;
}
};

template <>
struct std::hash<kvs_key>
{
std::size_t operator()(const kvs_key &k) const
{
const uint8_t *data = static_cast<const uint8_t *>(k.key); // ๋ฐ”์ดํŠธ ๋‹จ์œ„๋กœ ์ ‘๊ทผ
uint16_t length = k.length;

std::size_t hash = 0xcbf29ce484222325; // FNV-1a ์ดˆ๊ธฐ๊ฐ’ (64๋น„ํŠธ)
const std::size_t fnv_prime = 0x100000001b3;

for (uint16_t i = 0; i < length; ++i)
{
hash ^= data[i]; // ๋ฐ”์ดํŠธ๋ฅผ XOR ์—ฐ์‚ฐ
hash *= fnv_prime; // FNV-1a ํ•ด์‹œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์ฃผ์š” ๊ณฑ์…ˆ ๋‹จ๊ณ„
}

return hash;
}
};

/**
* @brief DB row์˜ value struct type
*/
struct kvs_value
{
void *value; // value byte stream ๋ฒ„ํผ์˜ ์‹œ์ž‘ ์ฃผ์†Œ
uint32_t length; // value byte stream ๋ฒ„ํผ์˜ ํฌ๊ธฐ (๋‹จ์œ„: byte)
uint32_t actual_value_size; // device์— ์ €์žฅ๋œ value์˜ ์‹ค์ œ ํฌ๊ธฐ (๋‹จ์œ„: byte)
uint32_t offset; // [optional] device์— ์ €์žฅ๋œ value์˜ offset (๋‹จ์œ„: byte)

~kvs_value()
{
delete[] static_cast<char *>(value);
}
};

/**
* @brief KVSSD Interface
*/
class KVSSD
{
public:
KVSSD() = default;
virtual ~KVSSD() = default;

virtual kvs_result Read(const kvs_key &, kvs_value &) = 0;
virtual kvs_result Insert(const kvs_key &, const kvs_value &) = 0;
virtual kvs_result Update(const kvs_key &, const kvs_value &) = 0;
virtual kvs_result Delete(const kvs_key &) = 0;
};

/**
* @brief Hashmap_KVSSD Class
*
* KVSSD Interface์˜ ๊ตฌํ˜„์ฒด
*/
class Hashmap_KVSSD : public KVSSD
{
public:
Hashmap_KVSSD();
~Hashmap_KVSSD();

kvs_result Read(const kvs_key &, kvs_value &);
kvs_result Insert(const kvs_key &, const kvs_value &);
kvs_result Update(const kvs_key &, const kvs_value &);
kvs_result Delete(const kvs_key &);

private:
std::unordered_map<kvs_key, kvs_value> db;
};

/**
* @brief Hashmap_KVSSD ๊ฐ์ฒด ์ƒ์„ฑ ํ•จ์ˆ˜
* @return KVSSD ํƒ€์ž…์˜ Hashmap_KVSSD ๊ฐ์ฒด
*/
KVSSD *NewKvssdDB();

#endif // YCSB_C_KVSSD_HASHMAP_DB_H_
Loading