my simplest kv db

最简单的kv db 

最基本的网络连接 使用STL map存储key value 作为多线程互斥的简单例子。

以后有机会逐步优化添加功能

1增加ASIO 异步通讯

2优化存储空间 传递指针 避免过多的拷贝操作

3优化代码结构

4优化全局锁 操作map时候 锁定部分区域而不是锁全局 。(思路在之前博客有提过多线程查找大量数据加锁的速度降低)

效果图:

部分代码

 1 #include "NetWork.h"
 2 #include "Handler.h"
 3 #include <thread>
 4 
 5 
 6 void DEF::NetWorkClass::work() {
 7     try {
 8         while (1) {
 9             std::shared_ptr<boost::asio::ip::tcp::socket> psocket = 
10                 std::make_shared<boost::asio::ip::tcp::socket>(*pio_service_);
11             pacceptor_->accept(*psocket);
12             std::thread t = std::thread(DEF::Handler, psocket);
13             t.detach();
14         }
15     }
16     catch (std::exception& e) {
17         std::cerr << __FUNCTION__ << " " << 
18             e.what() << std::endl;
19     }
20     return;
21 }
NetWork.cpp
#pragma once
#include "PreHead.h"
#include <boost/asio.hpp>
#include <memory>
#include <iostream>

using boost::asio::ip::tcp;


NAMESPACEBEGIN(DEF)

class NetWorkClass {
public:
    NetWorkClass(short port):port_(port),pacceptor_ (nullptr), pio_service_(nullptr){}
    bool Init() {
        bool b = false;
        pio_service_ = std::make_shared<boost::asio::io_service>();
        if (nullptr == pio_service_) {
            std::cerr << __FUNCTION__ << " make io_service() error!" << std::endl;
            return b;
        }
        pacceptor_ = std::make_shared<tcp::acceptor>(*pio_service_, 
            tcp::endpoint(tcp::v4(), port_));
        if (nullptr == pio_service_) {
            std::cerr << __FUNCTION__ << " make acceptor() error!" << std::endl;
            return b;
        }

        b = true;
        return b;
    }

    void work();

private:
    short port_;
    std::shared_ptr<tcp::acceptor> pacceptor_;
    std::shared_ptr<boost::asio::io_service> pio_service_;
};














NAMESPACEEND
NetWork.h
 1 #pragma once
 2 #include "PreHead.h"
 3 #include <memory>
 4 #include <iostream>
 5 #include <boost/asio.hpp>
 6 
 7 NAMESPACEBEGIN(DEF)
 8 
 9 bool Handler(std::shared_ptr<boost::asio::ip::tcp::socket> psocket);
10 
11 struct Item {
12     std::string command_;
13     std::string key_;
14     std::string value_;
15     std::string result_;
16 };
17 
18 class ParseRecvString {
19 public:
20     static void TestSplitBySpace();
21     static std::vector<std::string> SplitBySpace(const std::string& recvStr) {
22         std::vector<std::string> vecStr;
23         size_t begPos = recvStr.find_first_not_of(' ');
24         size_t endPos = recvStr.find_first_of(' ', begPos+1);
25         while (begPos != std::string::npos) {
26             endPos = recvStr.find_first_of(' ', begPos);
27             if (endPos != std::string::npos){
28                 vecStr.push_back(recvStr.substr(begPos, endPos - begPos));
29                 begPos = recvStr.find_first_not_of(' ', endPos + 1);
30             }
31             else {
32                 vecStr.push_back(recvStr.substr(begPos));
33                 begPos = endPos;
34             }
35         }
36 
37         return vecStr;
38     }
39 
40 private:
41 };
42 
43 class CommandHandler {
44 public:
45     CommandHandler(const std::vector<std::string>& command) :command_(command) {}
46 
47 private:
48     std::vector<std::string> command_;
49 };
50 
51 class Session {
52 public:
53     Session(std::shared_ptr<boost::asio::ip::tcp::socket> psocket): psocket_(psocket){}
54     Session(const Session& s) = delete;
55     Session operator=(const Session& s) = delete;
56     bool LoopHandle();
57 private:
58     void SetFunc(const std::vector<std::string>& vecStr, Item& item);
59     void GetFunc(const std::vector<std::string>& vecStr, Item& item);
60     void AppendFunc(const std::vector<std::string>& vecStr, Item& item);
61     void PreAppendFunc(const std::vector<std::string>& vecStr, Item& item);
62     void DeleteFunc(const std::vector<std::string>& vecStr, Item& item);
63     void DispatchCommand(const std::vector<std::string>& vecStr, Item& item);
64     bool ParseRecvData(char* recvData,size_t len,Item& item);
65     std::shared_ptr<boost::asio::ip::tcp::socket> psocket_;
66 };
67 
68 
69 
70 NAMESPACEEND
Handler.h
#include "Handler.h"
#include "DbStored.h"
#include <iostream>
#include <string>

extern DEF::DBStored g_dbStored;

bool DEF::Handler(std::shared_ptr<boost::asio::ip::tcp::socket> psocket) {
    bool b = false;
    Session s(psocket);
    b = s.LoopHandle();

    return b;
}
bool DEF::Session::ParseRecvData(char* recvData, size_t len, Item& item) {
    bool b = false;
    recvData[len] = '';
    std::string recvstr(recvData);
    std::vector<std::string> vecStr = ParseRecvString::SplitBySpace(recvstr);
    DispatchCommand(vecStr,item);

    return b;
}

void DEF::Session::SetFunc(const std::vector<std::string>& vecStr, Item& item) {
    assert(vecStr.size() >= 3);
    bool b = g_dbStored.InsertDBWithLock(vecStr[1], vecStr[2]);
    item.key_ = vecStr[1];
    item.value_ = vecStr[2];
    if (b) {
        item.result_ = "STORED";
    }
    else {
        item.result_ = "STORED_FAILED";
    }
    return ;
}

void DEF::Session::GetFunc(const std::vector<std::string>& vecStr, Item& item) {
    assert(vecStr.size() >= 2);
    std::string getVal;
    bool b = g_dbStored.GetFromDbWithLock(vecStr[1], getVal);
    item.key_ = vecStr[1];
    item.value_ = getVal;
    if (b) {
        item.result_ = getVal;
    }
    else {
        item.result_ = "GET_FAILED";
    }
    return ;
}

void DEF::Session::AppendFunc(const std::vector<std::string>& vecStr, Item& item) {
    assert(0);


    return ;
}

void DEF::Session::PreAppendFunc(const std::vector<std::string>& vecStr, Item& item) {
    assert(0);


    return ;
}

void DEF::Session::DeleteFunc(const std::vector<std::string>& vecStr, Item& item) {



    return ;
}


void DEF::Session::DispatchCommand(const std::vector<std::string>& vecStr, Item& item)
{
    std::string s = vecStr[0];
    std::string result;
    transform(s.begin(), s.end(), s.begin(), tolower);
    //可使用MAP 进行命令分发
    if (s == "set") {
        item.command_ = "set";
        SetFunc(vecStr, item);
    }
    else if (s == "get") {
        item.command_ = "get";
        GetFunc(vecStr, item);
    }
    else if (s == "append") {
        item.command_ = "append";
        AppendFunc(vecStr, item);
    }
    else if (s == "preappend") {
        item.command_ = "preappend";
        PreAppendFunc(vecStr, item);
    }
    else if (s == "del") {
        item.command_ = "del";
        DeleteFunc(vecStr, item);
    }
    else {
        item.result_ = "ERROR_COMMAND";
    }

    return;
}

void DEF::ParseRecvString::TestSplitBySpace()
{
    std::string s1 = " set   ";
    std::string s2 = " set";
    std::string s3 = "set";
    std::string s4 = "set ";
    std::string s5 = " set   mykey myvalue";
    std::string s6 = " set   mykey myvalue ";
    std::string s7 = " set   mykey   myvalue ";
    std::string s8 = "set mykey myvalue";

    std::vector<std::string> vs;

    vs = DEF::ParseRecvString::SplitBySpace(s1);
    assert(vs.size() == 1 && vs[0] == "set");
    vs.clear();
    vs = DEF::ParseRecvString::SplitBySpace(s2);
    assert(vs.size() == 1 && vs[0] == "set");
    vs.clear();
    vs = DEF::ParseRecvString::SplitBySpace(s3);
    assert(vs.size() == 1 && vs[0] == "set");
    vs.clear();
    vs = DEF::ParseRecvString::SplitBySpace(s4);
    assert(vs.size() == 1 && vs[0] == "set");
    vs.clear();
    vs = DEF::ParseRecvString::SplitBySpace(s5);
    assert(vs.size() == 3 && vs[0] == "set" && vs[1] == "mykey" && vs[2] == "myvalue");
    vs.clear();
    vs = DEF::ParseRecvString::SplitBySpace(s6);
    assert(vs.size() == 3 && vs[0] == "set" && vs[1] == "mykey" && vs[2] == "myvalue");
    vs.clear();
    vs = DEF::ParseRecvString::SplitBySpace(s7);
    assert(vs.size() == 3 && vs[0] == "set" && vs[1] == "mykey" && vs[2] == "myvalue");
    vs.clear();
    vs = DEF::ParseRecvString::SplitBySpace(s8);
    assert(vs.size() == 3 && vs[0] == "set" && vs[1] == "mykey" && vs[2] == "myvalue");
    vs.clear();
}

bool DEF::Session::LoopHandle() {
    bool b = false;
    if (psocket_ == nullptr)
        return b;
    char recvData[1024];
    try {
        while (1) {
            boost::system::error_code error;
            size_t len = psocket_->read_some(boost::asio::buffer(recvData,1024), error);
            if (error == boost::asio::error::eof) {
                return (b = true);
            }
            else if (error) {
                throw boost::system::system_error(error);
            }
            Item item;
            b = ParseRecvData(recvData, len,item);
            len = psocket_->write_some(boost::asio::buffer(item.result_.c_str(),item.result_.size()), 
                error);
            if (error) {
                throw boost::system::system_error(error);
            }
        }
    }
    catch (std::exception& e) {
        std::cerr << e.what() << std::endl;
    }
    return b;
}
Handler.cpp
作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
B站算法视频题解
https://space.bilibili.com/18508846
qq 151435887
gitee https://gitee.com/def/
欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
如果觉得不错,欢迎点赞,你的鼓励就是我的动力
阿里打赏 微信打赏
原文地址:https://www.cnblogs.com/itdef/p/8470783.html