zoukankan      html  css  js  c++  java
  • 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驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    python基础-枚举定义错误码
    凸包-Graham扫描法
    [USACO04OPEN]MooFest
    [USACO16OPEN]262144
    [ASPNETCORE] 抛砖引玉,EFCORE 软删除和自动添加审计的实现
    java 文件读取汇总
    java 各类型转换 convert
    java 各类型初始化汇总
    java 常用类型占用字节数
    Maven 常用命令
  • 原文地址:https://www.cnblogs.com/itdef/p/8470783.html
Copyright © 2011-2022 走看看