Full Code of loveyacper/Qedis for AI

master a68b8261737b cached
217 files
1.1 MB
329.5k tokens
1981 symbols
1 requests
Download .txt
Showing preview only (1,208K chars total). Download the full file or copy to clipboard to get everything.
Repository: loveyacper/Qedis
Branch: master
Commit: a68b8261737b
Files: 217
Total size: 1.1 MB

Directory structure:
gitextract_0j0gzhnc/

├── .gitignore
├── .travis.yml
├── CMakeCommon
├── CMakeLists.txt
├── LICENSE
├── Makefile
├── Modules/
│   ├── CMakeLists.txt
│   ├── QHashModule.cc
│   ├── QHashModule.h
│   ├── QListModule.cc
│   ├── QListModule.h
│   ├── QModuleInit.cc
│   ├── QModuleInit.h
│   ├── QSetModule.cc
│   └── QSetModule.h
├── QBase/
│   ├── AsyncBuffer.cc
│   ├── AsyncBuffer.h
│   ├── Buffer.h
│   ├── CMakeLists.txt
│   ├── ClientSocket.cc
│   ├── ClientSocket.h
│   ├── ConfigParser.cc
│   ├── ConfigParser.h
│   ├── Delegate.h
│   ├── EPoller.cc
│   ├── EPoller.h
│   ├── Kqueue.cc
│   ├── Kqueue.h
│   ├── ListenSocket.cc
│   ├── ListenSocket.h
│   ├── Log/
│   │   ├── Logger.cc
│   │   ├── Logger.h
│   │   ├── MemoryFile.cc
│   │   └── MemoryFile.h
│   ├── NetThreadPool.cc
│   ├── NetThreadPool.h
│   ├── Poller.h
│   ├── README.md
│   ├── Server.cc
│   ├── Server.h
│   ├── Socket.cc
│   ├── Socket.h
│   ├── StreamSocket.cc
│   ├── StreamSocket.h
│   ├── TaskManager.cc
│   ├── TaskManager.h
│   ├── Threads/
│   │   ├── ThreadPool.cc
│   │   └── ThreadPool.h
│   ├── Timer.cc
│   ├── Timer.h
│   ├── UnboundedBuffer.cc
│   ├── UnboundedBuffer.h
│   └── lzf/
│       ├── lzf.h
│       ├── lzfP.h
│       ├── lzf_c.c
│       └── lzf_d.c
├── QSentinel/
│   ├── CMakeLists.txt
│   ├── QClusterClient.cc
│   ├── QClusterClient.h
│   ├── QClusterInterface.h
│   ├── README.md
│   └── zookeeper/
│       ├── ZookeeperConn.cc
│       ├── ZookeeperConn.h
│       ├── proto.h
│       ├── recordio.c
│       ├── recordio.h
│       ├── zookeeper.jute.c
│       ├── zookeeper.jute.h
│       └── zookeeper_version.h
├── Qedis.xcodeproj/
│   └── project.pbxproj
├── QedisCore/
│   ├── CMakeLists.txt
│   ├── QAOF.cc
│   ├── QAOF.h
│   ├── QClient.cc
│   ├── QClient.h
│   ├── QCommand.cc
│   ├── QCommand.h
│   ├── QCommon.cc
│   ├── QCommon.h
│   ├── QConfig.cc
│   ├── QConfig.h
│   ├── QDB.cc
│   ├── QDB.h
│   ├── QDumpInterface.h
│   ├── QGlobRegex.cc
│   ├── QGlobRegex.h
│   ├── QHash.cc
│   ├── QHash.h
│   ├── QHelper.cc
│   ├── QHelper.h
│   ├── QKeyCommand.cc
│   ├── QLeveldb.cc
│   ├── QLeveldb.h
│   ├── QList.cc
│   ├── QList.h
│   ├── QMigration.cc
│   ├── QMigration.h
│   ├── QModule.cc
│   ├── QModule.h
│   ├── QMulti.cc
│   ├── QMulti.h
│   ├── QProtoParser.cc
│   ├── QProtoParser.h
│   ├── QPubsub.cc
│   ├── QPubsub.h
│   ├── QReplication.cc
│   ├── QReplication.h
│   ├── QServerCommand.cc
│   ├── QSet.cc
│   ├── QSet.h
│   ├── QSlaveClient.cc
│   ├── QSlaveClient.h
│   ├── QSlowLog.cc
│   ├── QSlowLog.h
│   ├── QSortedSet.cc
│   ├── QSortedSet.h
│   ├── QStore.cc
│   ├── QStore.h
│   ├── QString.cc
│   ├── QString.h
│   ├── crc64.c
│   ├── redisIntset.c
│   ├── redisIntset.h
│   ├── redisZipList.c
│   └── redisZipList.h
├── QedisSvr/
│   ├── CMakeLists.txt
│   ├── Qedis.cc
│   ├── Qedis.h
│   └── QedisLogo.h
├── README.md
├── README.zh.md
├── UnitTest/
│   ├── CMakeLists.txt
│   ├── QGlobRegex_unittest.cc
│   ├── UnitTest.cc
│   └── UnitTest.h
├── cluster/
│   ├── .gitignore
│   ├── CMakeCommon
│   ├── CMakeLists.txt
│   ├── Makefile
│   ├── README.md
│   ├── ananas/
│   │   ├── CMakeLists.txt
│   │   ├── future/
│   │   │   ├── Future.h
│   │   │   ├── Helper.h
│   │   │   └── Try.h
│   │   ├── net/
│   │   │   ├── Acceptor.cc
│   │   │   ├── Acceptor.h
│   │   │   ├── AnanasDebug.cc
│   │   │   ├── AnanasDebug.h
│   │   │   ├── AnanasLogo.h
│   │   │   ├── Buffer.cc
│   │   │   ├── Buffer.h
│   │   │   ├── CMakeLists.txt
│   │   │   ├── Connection.cc
│   │   │   ├── Connection.h
│   │   │   ├── Connector.cc
│   │   │   ├── Connector.h
│   │   │   ├── DatagramSocket.cc
│   │   │   ├── DatagramSocket.h
│   │   │   ├── Epoller.cc
│   │   │   ├── Epoller.h
│   │   │   ├── EventLoop.cc
│   │   │   ├── EventLoop.h
│   │   │   ├── Kqueue.cc
│   │   │   ├── Kqueue.h
│   │   │   ├── Poller.h
│   │   │   ├── Socket.cc
│   │   │   ├── Socket.h
│   │   │   ├── ThreadPool.cc
│   │   │   ├── ThreadPool.h
│   │   │   ├── TimeUtil.cc
│   │   │   ├── TimeUtil.h
│   │   │   ├── Timer.cc
│   │   │   ├── Timer.h
│   │   │   ├── Typedefs.h
│   │   │   └── log/
│   │   │       ├── Logger.cc
│   │   │       ├── Logger.h
│   │   │       ├── MmapFile.cc
│   │   │       ├── MmapFile.h
│   │   │       └── README.md
│   │   └── util/
│   │       ├── Delegate.h
│   │       ├── Scheduler.h
│   │       └── Util.h
│   ├── cluster_conn/
│   │   ├── CMakeLists.txt
│   │   ├── ClusterConn.h
│   │   └── zookeeper/
│   │       ├── CMakeLists.txt
│   │       ├── ZkResponse.h
│   │       ├── ZookeeperContext.cc
│   │       ├── ZookeeperContext.h
│   │       ├── proto.h
│   │       ├── recordio.c
│   │       ├── recordio.h
│   │       ├── zookeeper.jute.c
│   │       └── zookeeper.jute.h
│   └── qedis_proxy/
│       ├── CMakeLists.txt
│       ├── ClientConn.cc
│       ├── ClientConn.h
│       ├── ClientManager.cc
│       ├── ClientManager.h
│       ├── ClusterManager.cc
│       ├── ClusterManager.h
│       ├── Command.cc
│       ├── Command.h
│       ├── ConfigParser.cc
│       ├── ConfigParser.h
│       ├── Protocol.cc
│       ├── Protocol.h
│       ├── ProxyConfig.cc
│       ├── ProxyConfig.h
│       ├── ProxyLog.h
│       ├── QedisConn.cc
│       ├── QedisConn.h
│       ├── QedisManager.cc
│       ├── QedisManager.h
│       ├── ZookeeperConn.cc
│       ├── ZookeeperConn.h
│       └── main.cc
└── qedis.conf

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# MAC OS
.DS_Store

#
build/
bin/


================================================
FILE: .travis.yml
================================================
sudo: false
language: cpp
compiler:
  - clang
script: make
branches:
  only:
    - master
notifications:
  recipients:
    - bertyoung666@gmail.com
  email:
    on_success: change
    on_failure: always
os:
  - osx


================================================
FILE: CMakeCommon
================================================
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)

IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
    SET(CMAKE_CXX_FLAGS_DEBUG  "-g -Wall -std=c++0x")
    SET(CMAKE_CXX_FLAGS_RELEASE "-O2 -g -Wall -std=c++0x")
ELSEIF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
    SET(CMAKE_CXX_FLAGS_DEBUG  "-g -Wall -std=c++1y -stdlib=libc++ -Wc++11-extensions")
    SET(CMAKE_CXX_FLAGS_RELEASE "-O2 -g -Wall -std=c++1y -stdlib=libc++ -Wc++11-extensions")
ELSE()
    message(FATAL_ERROR "Only support linux or OS X, support for windows is in plan")
ENDIF()

OPTION(DEBUG "Debug or release" OFF)

IF(DEBUG)
    SET(CMAKE_BUILD_TYPE "Debug")
ELSE()
    SET(CMAKE_BUILD_TYPE "Release")
ENDIF()



================================================
FILE: CMakeLists.txt
================================================
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)

PROJECT(QEDIS)

SUBDIRS(QBase)
SUBDIRS(QedisCore)
SUBDIRS(QedisSvr)
SUBDIRS(Modules)
SUBDIRS(UnitTest)


SET(QEDIS_CLUSTER 0)
SET(USE_ZOOKEEPER 0)

ADD_DEFINITIONS(-DQEDIS_CLUSTER=${QEDIS_CLUSTER})
ADD_DEFINITIONS(-DUSE_ZOOKEEPER=${USE_ZOOKEEPER})
if(${QEDIS_CLUSTER} EQUAL 1)
    SUBDIRS(QSentinel)
endif()


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2017 Bert Young

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: Makefile
================================================
all:
	@if [ ! -d "leveldb" ]; then echo "leveldb not present. Fetching leveldb-1.18 from internet..."; curl -s -L -O https://github.com/google/leveldb/archive/v1.18.tar.gz; tar xzvf v1.18.tar.gz; rm -f v1.18.tar.gz; mv leveldb-1.18 leveldb; fi
	cd leveldb && make && cd -
	mkdir -p bin && ln -s -f ../leveldb/libleveldb.so.1.18 bin/libleveldb.so.1
	mkdir -p build && cd build && cmake .. && make 

clean:
	@if [ -d "build" ]; then cd build && make clean && cd -; fi
cleanall:clean
	@if [ -d "leveldb" ]; then cd leveldb && make clean && cd -; rm -rf leveldb; fi


================================================
FILE: Modules/CMakeLists.txt
================================================
INCLUDE(${PROJECT_SOURCE_DIR}/CMakeCommon)

AUX_SOURCE_DIRECTORY(. QEDIS_MODULE_SRC)

LINK_DIRECTORIES(../../leveldb)

SET(LIBRARY_OUTPUT_PATH ../../bin)
SET(QEDIS_MODULE qedismodule)

ADD_LIBRARY(${QEDIS_MODULE} SHARED ${QEDIS_MODULE_SRC})

INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/QedisCore)
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/QBase)

ADD_DEPENDENCIES(${QEDIS_MODULE} qediscore leveldb)
# clang needs below, not necessary for gcc
TARGET_LINK_LIBRARIES(${QEDIS_MODULE} qbaselib; qediscore; leveldb)

SET_TARGET_PROPERTIES(${QEDIS_MODULE} PROPERTIES LINKER_LANGUAGE CXX)


================================================
FILE: Modules/QHashModule.cc
================================================
#include "QHashModule.h"
#include "QHash.h"
#include "QStore.h"
#include "QGlobRegex.h"

using namespace qedis;

QError hgets(const std::vector<QString>& params, UnboundedBuffer* reply)
{
    QObject* value;
    QError err = QSTORE.GetValueByType(params[1], value, QType_hash);
    if (err != QError_ok) 
    {  
        ReplyError(err, reply);
        return err;
    }
    
    const PHASH& hash= value->CastHash();
    std::vector<const QString* > res;
    for (const auto& kv : *hash)
    {
        if (glob_match(params[2], kv.first))
        {
            res.push_back(&kv.first);
            res.push_back(&kv.second);
        }
    }

    PreFormatMultiBulk(res.size(), reply);
    for (auto v : res)
    {
        FormatBulk(*v, reply);
    }

    return   QError_ok;
}



================================================
FILE: Modules/QHashModule.h
================================================
#ifndef BERT_QHASHMODULE_H
#define BERT_QHASHMODULE_H

#include <vector>
#include "QString.h"
#include "QCommon.h"

namespace qedis
{
class UnboundedBuffer;
}


// hgets  hash_key  filter_pattern
// for example, `hgets profile c*y` may return ["city":"shanghai", "country":"china"]
// because c*y matches "city" and "country"
//
extern "C"
qedis::QError hgets(const std::vector<qedis::QString>& params, qedis::UnboundedBuffer* reply);

#endif



================================================
FILE: Modules/QListModule.cc
================================================
#include "QListModule.h"
#include "QList.h"
#include "QStore.h"
#include <algorithm>

using namespace qedis;


QError ldel(const std::vector<QString>& params, UnboundedBuffer* reply)
{
    QObject* value;

    QError err = QSTORE.GetValueByType(params[1], value, QType_list);
    if (err != QError_ok)
    {
        Format0(reply);
        return err;
    }
        
    long idx;
    if (!Strtol(params[2].c_str(), params[2].size(), &idx))
    {
        ReplyError(QError_nan, reply);
        return QError_nan;
    }
        
    const PLIST& list = value->CastList();
    const int size = static_cast<int>(list->size());
    if (idx < 0)
        idx += size;
    
    if (idx < 0 || idx >= size)
    {
        Format0(reply);
        return QError_nop;
    }
    
    if (2 * idx < size)
    {
        auto it = list->begin();
        std::advance(it, idx);
        list->erase(it);
    }
    else
    {
        auto it = list->rbegin();
        idx = size - 1 - idx;
        std::advance(it, idx);
        list->erase((++it).base());
    }

    if (list->empty())
        QSTORE.DeleteKey(params[1]);
    
    Format1(reply);
    return QError_ok;
}



================================================
FILE: Modules/QListModule.h
================================================
#ifndef BERT_QLISTMODULE_H
#define BERT_QLISTMODULE_H

#include <vector>
#include "QString.h"
#include "QCommon.h"

namespace qedis
{
class UnboundedBuffer;
}


// ldel  list_key  item_index
// For delete list item by index
//
extern "C"
qedis::QError ldel(const std::vector<qedis::QString>& params, qedis::UnboundedBuffer* reply);

#endif



================================================
FILE: Modules/QModuleInit.cc
================================================
#include "QModuleInit.h"
#include "QCommand.h"
#include <algorithm>

extern "C"
qedis::QError ldel(const std::vector<qedis::QString>& params, qedis::UnboundedBuffer* reply);

extern "C"
qedis::QError hgets(const std::vector<qedis::QString>& params, qedis::UnboundedBuffer* reply);

extern "C"
qedis::QError skeys(const std::vector<qedis::QString>& params, qedis::UnboundedBuffer* reply);

bool QedisModule_OnLoad()
{
    printf("enter %s\n", __FUNCTION__);
    using namespace qedis;

    // register list ldel command
    static QCommandInfo ldelinfo;
    ldelinfo.cmd = "ldel";
    ldelinfo.attr = QAttr_write;
    ldelinfo.params = 3;
    ldelinfo.handler = &ldel;

    if (!QCommandTable::AddCommand("ldel", &ldelinfo))
        return false;

    // register hash hgets command
    static QCommandInfo hgetsinfo;
    hgetsinfo.cmd = "hgets";
    hgetsinfo.attr = QAttr_read;
    hgetsinfo.params = 3;
    hgetsinfo.handler = &hgets;

    if (!QCommandTable::AddCommand("hgets", &hgetsinfo))
    {
        QCommandTable::DelCommand("ldel");
        return false;
    }

    // register set skeys command
    static QCommandInfo skeysinfo;
    skeysinfo.cmd = "skeys";
    skeysinfo.attr = QAttr_read;
    skeysinfo.params = 3;
    skeysinfo.handler = &skeys;

    if (!QCommandTable::AddCommand("skeys", &skeysinfo))
    {
        QCommandTable::DelCommand("hgets");
        QCommandTable::DelCommand("ldel");
        return false;
    }
    
    printf("exit %s\n", __FUNCTION__);
    return true;
}


void QedisModule_OnUnLoad()
{
    printf("enter %s\n", __FUNCTION__);
    qedis::QCommandTable::DelCommand("skeys");
    qedis::QCommandTable::DelCommand("hgets");
    qedis::QCommandTable::DelCommand("ldel");
    printf("exit %s\n", __FUNCTION__);
}


================================================
FILE: Modules/QModuleInit.h
================================================
#ifndef BERT_QMODULEINIT_H
#define BERT_QMODULEINIT_H

extern "C"
bool QedisModule_OnLoad();

extern "C"
void QedisModule_OnUnLoad();
#endif



================================================
FILE: Modules/QSetModule.cc
================================================
#include "QSetModule.h"
#include "QSet.h"
#include "QStore.h"
#include "QGlobRegex.h"

using namespace qedis;

QError skeys(const std::vector<QString>& params, UnboundedBuffer* reply)
{
    QObject* value;
    QError err = QSTORE.GetValueByType(params[1], value, QType_set);
    if (err != QError_ok) 
    {  
        if (err == QError_notExist)
            FormatNull(reply);
        else
            ReplyError(err, reply);

        return err;
    }

    std::vector<const QString* > res;
    const PSET& set = value->CastSet();
    for (const auto& k : *set)
    {
        if (glob_match(params[2], k))
        {
            res.push_back(&k);
        }
    }

    PreFormatMultiBulk(res.size(), reply);
    for (auto v : res)
    {
        FormatBulk(*v, reply);
    }

    return   QError_ok;
}




================================================
FILE: Modules/QSetModule.h
================================================
#ifndef BERT_QSETMODULE_H
#define BERT_QSETMODULE_H

#include <vector>
#include "QString.h"
#include "QCommon.h"

namespace qedis
{
class UnboundedBuffer;
}


// skeys set_key  filter_pattern
// for example, `skeys cities sh*` may return ["shanghai", "shenzhen"]
//
extern "C"
qedis::QError skeys(const std::vector<qedis::QString>& params, qedis::UnboundedBuffer* reply);

#endif



================================================
FILE: QBase/AsyncBuffer.cc
================================================
#include <assert.h>

#if defined(__APPLE__)
#include <unistd.h>
#endif

#include "AsyncBuffer.h"

using std::size_t;

AsyncBuffer::AsyncBuffer(size_t size) : buffer_(size),
                                          backBytes_(0)
{
}

AsyncBuffer::~AsyncBuffer()
{
  //  assert (buffer_.IsEmpty());
   // assert (backBytes_ == 0);
}


void   AsyncBuffer::Write(const void* data, size_t len)
{
    BufferSequence  bf;
    bf.buffers[0].iov_base = const_cast<void* >(data);
    bf.buffers[0].iov_len  = len;
    bf.count = 1;
    
    this->Write(bf);
}

void   AsyncBuffer::Write(const BufferSequence& data)
{
    auto len = data.TotalBytes();

    if (backBytes_ > 0 || buffer_.WritableSize() < len)
    {
        std::lock_guard<std::mutex>  guard(backBufLock_);

        if (backBytes_ > 0 || buffer_.WritableSize() < len)
        {
            for (size_t i = 0; i < data.count; ++ i)
            {
                backBuf_.PushData(data.buffers[i].iov_base,
                                   data.buffers[i].iov_len);
            }
        
            backBytes_ += len;
            assert (backBytes_ == backBuf_.ReadableSize());

            return;
        }
    }
    
    assert(backBytes_ == 0 && buffer_.WritableSize() >= len);

    for (size_t i = 0; i < data.count; ++ i)
    {
        buffer_.PushData(data.buffers[i].iov_base, data.buffers[i].iov_len);
    }
}

void  AsyncBuffer::ProcessBuffer(BufferSequence& data)
{
    data.count = 0;
    
    // Here be dragons! see below...
    if (!tmpBuf_.IsEmpty())
    {
        data.count = 1;
        data.buffers[0].iov_base = tmpBuf_.ReadAddr();
        data.buffers[0].iov_len  = tmpBuf_.ReadableSize();
    }
    else if (!buffer_.IsEmpty())
    {
        auto nLen = buffer_.ReadableSize();

        buffer_.GetDatum(data, nLen);
        assert (nLen == data.TotalBytes());
    }
    else
    {
        if (backBytes_ > 0 && backBufLock_.try_lock())
        {
            // tmpBuf_ is used for process backBuf_ without held mutex!
            backBytes_ = 0;
            tmpBuf_.Swap(backBuf_);
            backBufLock_.unlock();
            
            data.count = 1;
            data.buffers[0].iov_base = tmpBuf_.ReadAddr();
            data.buffers[0].iov_len  = tmpBuf_.ReadableSize();
        }
    }
}

void  AsyncBuffer::Skip(size_t  size)
{
    if (!tmpBuf_.IsEmpty())
    {
        assert(size <= tmpBuf_.ReadableSize());
        tmpBuf_.AdjustReadPtr(size);
    }
    else
    {
        assert(buffer_.ReadableSize() >= size);
        buffer_.AdjustReadPtr(size);
    }
}



================================================
FILE: QBase/AsyncBuffer.h
================================================
#ifndef BERT_ASYNCBUFFER_H
#define BERT_ASYNCBUFFER_H

#include <mutex>
#include <atomic>

#include "Buffer.h"
#include "UnboundedBuffer.h"

class AsyncBuffer
{
public:
    explicit
    AsyncBuffer(std::size_t  size = 128 * 1024);
   ~AsyncBuffer();

    void        Write(const void* data, std::size_t len);
    void        Write(const BufferSequence& data);

    void        ProcessBuffer(BufferSequence& data);
    void        Skip(std::size_t  size);

private:
    // for async write
    Buffer          buffer_;
    
    // double buffer
    qedis::UnboundedBuffer tmpBuf_;
    
    std::mutex      backBufLock_;
    std::atomic<std::size_t>    backBytes_;
    qedis::UnboundedBuffer backBuf_;
};

#endif



================================================
FILE: QBase/Buffer.h
================================================

#ifndef BERT_BUFFER_H
#define BERT_BUFFER_H

#include <cassert>
#include <cstring>
#include <vector>
#include <string>
#include <sys/uio.h>
#include <atomic>


struct BufferSequence
{
    static const std::size_t kMaxIovec = 16;

    iovec       buffers[kMaxIovec];
    std::size_t count;

    std::size_t TotalBytes() const
    {
        assert (count <= kMaxIovec);
        std::size_t nBytes = 0;
        for (std::size_t i = 0; i < count; ++ i)
            nBytes += buffers[i].iov_len;

        return nBytes;
    }
};


//static const std::size_t  DEFAULT_BUFFER_SIZE = 4 * 1024;

inline std::size_t RoundUp2Power(std::size_t size)
{
    if (0 == size)  return 0;

    std::size_t roundSize = 1;
    while (roundSize < size)
        roundSize <<= 1;

    return roundSize;
}


template <typename BUFFER>
class  CircularBuffer
{
public:
    // Constructor  to be specialized
    explicit CircularBuffer(std::size_t size = 0) : maxSize_(size),
    readPos_(0),
    writePos_(0)
    {
    }
    CircularBuffer(const BufferSequence& bf);
    CircularBuffer(char* , std::size_t );
   ~CircularBuffer() { }

    bool IsEmpty() const { return writePos_ == readPos_; }
    bool IsFull()  const { return ((writePos_ + 1) & (maxSize_ - 1)) == readPos_; }

    // For gather write
    void GetDatum(BufferSequence& buffer, std::size_t maxSize, std::size_t offset = 0);

    // For scatter read
    void GetSpace(BufferSequence& buffer, std::size_t offset = 0);

    // Put data into internal buffer_
    bool PushData(const void* pData, std::size_t nSize);
    bool PushDataAt(const void* pData, std::size_t nSize, std::size_t offset = 0);

    // Get data from internal buffer_, adjust read ptr
    bool PeekData(void* pBuf, std::size_t nSize);
    bool PeekDataAt(void* pBuf, std::size_t nSize, std::size_t offset = 0);

    char* ReadAddr() { return &buffer_[readPos_]; }
    char* WriteAddr() { return &buffer_[writePos_]; }

    void AdjustWritePtr(std::size_t size);
    void AdjustReadPtr(std::size_t size);

    std::size_t ReadableSize()  const {  return (writePos_ - readPos_) & (maxSize_ - 1);  }
    std::size_t WritableSize()  const {  return maxSize_ - ReadableSize() - 1;  }

    std::size_t Capacity() const { return maxSize_; }
    void InitCapacity(std::size_t size);

    template <typename T>
    CircularBuffer& operator<< (const T& data);
    template <typename T>
    CircularBuffer& operator>> (T& data);

    template <typename T>
    CircularBuffer & operator<< (const std::vector<T>& );
    template <typename T>
    CircularBuffer & operator>> (std::vector<T>& );

    CircularBuffer & operator<< (const std::string& str);
    CircularBuffer & operator>> (std::string& str);

protected:
    // The max capacity of buffer_
    std::size_t maxSize_;

private:
    // The starting address can be read
    std::atomic<std::size_t> readPos_;

    // The starting address can be write
    std::atomic<std::size_t> writePos_;

    // The real internal buffer
    BUFFER buffer_;

    bool   owned_ = false;
};

template <typename BUFFER>
void CircularBuffer<BUFFER>::GetDatum(BufferSequence& buffer, std::size_t maxSize, std::size_t offset)
{
    if (maxSize == 0 ||
        offset >= ReadableSize()
       )
    {
        buffer.count = 0;
        return;
    }

    assert(readPos_  < maxSize_);
    assert(writePos_ < maxSize_);

    std::size_t   bufferIndex  = 0;
    const std::size_t readPos  = (readPos_ + offset) & (maxSize_ - 1);
    const std::size_t writePos = writePos_;
    assert (readPos != writePos);

    buffer.buffers[bufferIndex].iov_base = &buffer_[readPos];
    if (readPos < writePos)
    {            
        if (maxSize < writePos - readPos)
            buffer.buffers[bufferIndex].iov_len = maxSize;
        else
            buffer.buffers[bufferIndex].iov_len = writePos - readPos;
    }
    else
    {
        std::size_t nLeft = maxSize;
        if (nLeft > (maxSize_ - readPos))
            nLeft = (maxSize_ - readPos);
        buffer.buffers[bufferIndex].iov_len = nLeft;
        nLeft = maxSize - nLeft;
 
        if (nLeft > 0 && writePos > 0)
        {
            if (nLeft > writePos)
                nLeft = writePos;

            ++ bufferIndex;
            buffer.buffers[bufferIndex].iov_base = &buffer_[0];
            buffer.buffers[bufferIndex].iov_len = nLeft;
        }
    }

    buffer.count = bufferIndex + 1;
}

template <typename BUFFER>
void CircularBuffer<BUFFER>::GetSpace(BufferSequence& buffer, std::size_t offset)
{
    assert(readPos_ >= 0 && readPos_ < maxSize_);
    assert(writePos_ >= 0 && writePos_ < maxSize_);

    if (WritableSize() <= offset + 1)
    {
        buffer.count = 0;
        return;
    }

    std::size_t bufferIndex = 0;
    const std::size_t readPos  = readPos_;
    const std::size_t writePos = (writePos_ + offset) & (maxSize_ - 1);

    buffer.buffers[bufferIndex].iov_base = &buffer_[writePos];

    if (readPos > writePos)
    {
        buffer.buffers[bufferIndex].iov_len = readPos - writePos - 1;
        assert (buffer.buffers[bufferIndex].iov_len > 0);
    }
    else
    {
        buffer.buffers[bufferIndex].iov_len = maxSize_ - writePos;
        if (0 == readPos)
        {
            buffer.buffers[bufferIndex].iov_len -= 1;
        }
        else if (readPos > 1)
        {
            ++ bufferIndex;
            buffer.buffers[bufferIndex].iov_base = &buffer_[0];
            buffer.buffers[bufferIndex].iov_len = readPos - 1;
        }
    }

    buffer.count = bufferIndex + 1;
}

template <typename BUFFER>
bool CircularBuffer<BUFFER>::PushDataAt(const void* pData, std::size_t nSize, std::size_t offset)
{
    if (!pData || 0 == nSize)
        return true;

    if (offset + nSize > WritableSize())
        return false;

    const std::size_t readPos = readPos_;
    const std::size_t writePos = (writePos_ + offset) & (maxSize_ - 1);
    if (readPos > writePos)
    {
        assert(readPos - writePos > nSize);
        ::memcpy(&buffer_[writePos], pData, nSize);
    }
    else
    {
        std::size_t availBytes1 = maxSize_ - writePos;
        std::size_t availBytes2 = readPos - 0;
        assert (availBytes1 + availBytes2 >= 1 + nSize);

        if (availBytes1 >= nSize + 1)
        {
            ::memcpy(&buffer_[writePos], pData, nSize);
        }
        else
        {
            ::memcpy(&buffer_[writePos], pData, availBytes1);
            int bytesLeft = static_cast<int>(nSize - availBytes1);
            if (bytesLeft > 0)
                ::memcpy(&buffer_[0], static_cast<const char*>(pData) + availBytes1, bytesLeft);
        }
    }

    return  true;
}

template <typename BUFFER>
bool CircularBuffer<BUFFER>::PushData(const void* pData, std::size_t nSize)
{
    if (!PushDataAt(pData, nSize))
        return false;

    AdjustWritePtr(nSize);
    return true;
}

template <typename BUFFER>
bool CircularBuffer<BUFFER>::PeekDataAt(void* pBuf, std::size_t nSize, std::size_t offset)
{
    if (!pBuf || 0 == nSize)
        return true;

    if (nSize + offset > ReadableSize())
        return false;

    const std::size_t writePos = writePos_;
    const std::size_t readPos  = (readPos_ + offset) & (maxSize_ - 1);
    if (readPos < writePos)
    {
        assert(writePos - readPos >= nSize);
        ::memcpy(pBuf, &buffer_[readPos], nSize);
    }
    else
    {
        assert(readPos > writePos);
        std::size_t availBytes1 = maxSize_ - readPos;
        std::size_t availBytes2 = writePos - 0;
        assert(availBytes1 + availBytes2 >= nSize);

        if (availBytes1 >= nSize)
        {
            ::memcpy(pBuf, &buffer_[readPos], nSize);            
        }
        else
        {
            ::memcpy(pBuf, &buffer_[readPos], availBytes1);
            assert(nSize - availBytes1 > 0);
            ::memcpy(static_cast<char*>(pBuf) + availBytes1, &buffer_[0], nSize - availBytes1);
        }
    }

    return true;
}

template <typename BUFFER>
bool CircularBuffer<BUFFER>::PeekData(void* pBuf, std::size_t nSize)
{
    if (PeekDataAt(pBuf, nSize))
        AdjustReadPtr(nSize);
    else 
        return false;

    return true;
}


template <typename BUFFER>
inline void CircularBuffer<BUFFER>::AdjustWritePtr(std::size_t size)
{
    std::size_t writePos = writePos_;
    writePos += size;
    writePos &= maxSize_ - 1;
    
    writePos_ = writePos;
}

template <typename BUFFER>
inline void CircularBuffer<BUFFER>::AdjustReadPtr(std::size_t size)
{
    std::size_t readPos = readPos_;
    readPos += size;
    readPos &= maxSize_ - 1;
    
    readPos_ = readPos;
}

template <typename BUFFER>
inline void CircularBuffer<BUFFER>::InitCapacity(std::size_t size)
{
    assert (size > 0 && size <= 1 * 1024 * 1024 * 1024);

    maxSize_ = RoundUp2Power(size);
    buffer_.resize(maxSize_);
    std::vector<char>(buffer_).swap(buffer_);
}

template <typename BUFFER>
template <typename T>
inline CircularBuffer<BUFFER>& CircularBuffer<BUFFER>::operator<< (const T& data )
{
    if (!PushData(&data, sizeof(data)))
        assert (!!!"Please modify the DEFAULT_BUFFER_SIZE");

    return *this;
}

template <typename BUFFER>
template <typename T>
inline CircularBuffer<BUFFER> & CircularBuffer<BUFFER>::operator>> (T& data )
{
    if (!PeekData(&data, sizeof(data)))
        assert(!!!"Not enough data in buffer_");

    return *this;
}

template <typename BUFFER>
template <typename T>
inline CircularBuffer<BUFFER> & CircularBuffer<BUFFER>::operator<< (const std::vector<T>& v)
{
    if (!v.empty())
    {
        (*this) << static_cast<unsigned short>(v.size());
        for ( typename std::vector<T>::const_iterator it = v.begin(); it != v.end(); ++it )
        {
            (*this) << *it;
        } 
    }
    return *this;
}

template <typename BUFFER>
template <typename T>
inline CircularBuffer<BUFFER> & CircularBuffer<BUFFER>::operator>> (std::vector<T>& v)
{
    v.clear();
    unsigned short size;
    *this >> size;
    v.reserve(size);

    while (size--)
    {
        T t;
        *this >> t;
        v.push_back(t);
    }
    return *this;
}

template <typename BUFFER>
inline CircularBuffer<BUFFER>& CircularBuffer<BUFFER>::operator<< (const std::string& str)
{
    *this << static_cast<unsigned short>(str.size());
    if (!PushData(str.data(), str.size()))
    {
        AdjustWritePtr(static_cast<int>(0 - sizeof(unsigned short)));
        assert(!!!"2Please modify the DEFAULT_BUFFER_SIZE");
    }
    return *this;
}

template <typename BUFFER>
inline CircularBuffer<BUFFER>& CircularBuffer<BUFFER>::operator>> (std::string& str)
{
    unsigned short size = 0;
    *this >> size;
    str.clear();
    str.reserve(size);

    char ch;
    while ( size-- )
    {
        *this >> ch;
        str += ch;
    }
    return *this;
}

///////////////////////////////////////////////////////////////
typedef CircularBuffer< ::std::vector<char> >  Buffer;

template <>
inline Buffer::CircularBuffer(std::size_t maxSize) : maxSize_(RoundUp2Power(maxSize)), readPos_(0), writePos_(0), buffer_(maxSize_)
{
    assert (0 == (maxSize_ & (maxSize_ - 1)) && "maxSize_ MUST BE power of 2");
}


template <int N>
class StackBuffer : public CircularBuffer<char [N]>
{
    using CircularBuffer<char [N]>::maxSize_;
public:
    StackBuffer()
    {
        maxSize_ = N;
        if (maxSize_ < 0)
            maxSize_ = 1;

        if (0 != (maxSize_ & (maxSize_ - 1)))
            maxSize_ = RoundUp2Power(maxSize_);

        assert (0 == (maxSize_ & (maxSize_ - 1)) && "maxSize_ MUST BE power of 2");
    }
};

typedef CircularBuffer<char* > AttachedBuffer;

template <>
inline AttachedBuffer::CircularBuffer(char* pBuf, std::size_t len) :
    maxSize_(RoundUp2Power(len + 1)),
    readPos_(0),
    writePos_(len)
{
    buffer_ = pBuf;
    owned_  = false;
}

template <>
inline AttachedBuffer::CircularBuffer(const BufferSequence& bf) :
readPos_(0),
writePos_(0)
{
    owned_ = false;

    if (0 == bf.count)
    {
        buffer_ = 0;
    }
    else if (1 == bf.count)
    {
        buffer_   = (char*)bf.buffers[0].iov_base;
        writePos_ = static_cast<int>(bf.buffers[0].iov_len);
    }
    else if (bf.count > 1)
    {
        owned_  = true;
        buffer_ = new char[bf.TotalBytes()];

        std::size_t off = 0;
        for (std::size_t i = 0; i < bf.count; ++ i)
        {
            memcpy(buffer_ + off, bf.buffers[i].iov_base, bf.buffers[i].iov_len);
            off += bf.buffers[i].iov_len;
        }

        writePos_ = bf.TotalBytes();
    }

    maxSize_ = RoundUp2Power(writePos_ - readPos_ + 1);
}

template <>
inline AttachedBuffer::~CircularBuffer()
{
    if (owned_)
        delete [] buffer_;
}

template <typename T>
inline void OverwriteAt(void* addr, T data)
{
	memcpy(addr, &data, sizeof(data));
}

#endif



================================================
FILE: QBase/CMakeLists.txt
================================================
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)

INCLUDE(${PROJECT_SOURCE_DIR}/CMakeCommon)

AUX_SOURCE_DIRECTORY(. SDK_SRC)
AUX_SOURCE_DIRECTORY(./Log     SDK_SRC)
AUX_SOURCE_DIRECTORY(./Threads SDK_SRC)
AUX_SOURCE_DIRECTORY(./SmartPtr SDK_SRC)
AUX_SOURCE_DIRECTORY(./lzf SDK_SRC)
SET(LIBRARY_OUTPUT_PATH ../../bin)
ADD_LIBRARY(qbaselib SHARED ${SDK_SRC})

TARGET_LINK_LIBRARIES(qbaselib; pthread)

SET_TARGET_PROPERTIES(qbaselib PROPERTIES LINKER_LANGUAGE CXX)


================================================
FILE: QBase/ClientSocket.cc
================================================

#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include "Server.h"
#include "ClientSocket.h"
#include "Log/Logger.h"
#include "NetThreadPool.h"


ClientSocket::ClientSocket(int tag) : tag_(tag)
{
}

ClientSocket::~ClientSocket()
{
    if (localSock_ != INVALID_SOCKET)
        WRN << "Destruct ClientSocket " << localSock_;
}

bool ClientSocket::Connect(const SocketAddr& dst)
{
    if (dst.Empty())
        return false;

    if (INVALID_SOCKET != localSock_)
        return false;

    peerAddr_ = dst;

    localSock_ = CreateTCPSocket();
    SetNonBlock(localSock_);
    SetNodelay(localSock_);
    SetRcvBuf(localSock_);
    SetSndBuf(localSock_);

    int  result = ::connect(localSock_, (sockaddr*)&peerAddr_.GetAddr(), sizeof(sockaddr_in));

    if (0 == result)
    {
        INF << "ClientSocket immediately connected to ["
            << peerAddr_.GetIP()
            << ":"
            << peerAddr_.GetPort()
            << "]";
       
        Server::Instance()->NewConnection(localSock_, tag_, onConnectFail_);
        localSock_ = INVALID_SOCKET;
        return  true;
    }
    else
    {
        if (EINPROGRESS == errno)
        {
            
            INF << "EINPROGRESS: ClientSocket connected to ("
                << peerAddr_.GetIP()
                << ":"
                << peerAddr_.GetPort()
                << ")";
            
            Internal::NetThreadPool::Instance().AddSocket(shared_from_this(), EventTypeWrite);
            epollOut_ = true;
            return true;
        }

        ERR << "Failed: ClientSocket connected to ("
            << peerAddr_.GetIP()
            << ":"
            << peerAddr_.GetPort()
            << ")";

        if (onConnectFail_)
            onConnectFail_();

        return false;
    }
    
    return true;
}


bool ClientSocket::OnWritable()
{
    epollOut_ = false;
    int         error  = 0;
    socklen_t   len    = sizeof error;

    bool bSucc = (::getsockopt(localSock_, SOL_SOCKET, SO_ERROR, (char*)&error, &len) >= 0 && 0 == error);
    if (!bSucc)    
    {
        errno = error;
        ERR << "Failed: ClientSocket connected to ("
            << peerAddr_.GetIP()
            << ":"
            << peerAddr_.GetPort()
            << "), error:" << error;

        return false;
    }

    INF << "Success: ClientSocket connected to ("
        << peerAddr_.GetIP()
        << ":"
        << peerAddr_.GetPort() << ")";

    Server::Instance()->NewConnection(localSock_, tag_, onConnectFail_);
    localSock_ = INVALID_SOCKET; 

    return true;
}

bool ClientSocket::OnError()
{
    if (Socket::OnError())
    {
        ERR << __FUNCTION__ << " connected to ("
            << peerAddr_.GetIP()
            << ":"
            << peerAddr_.GetPort() << ")";
        
        if (onConnectFail_)
            onConnectFail_();

        return  true;
    }
        
    return  false;
}



================================================
FILE: QBase/ClientSocket.h
================================================

#ifndef BERT_CLIENTSOCKET_H
#define BERT_CLIENTSOCKET_H

#include <functional>
#include "Socket.h"

// Abstraction for a TCP client socket
class ClientSocket : public Socket
{
public:
    explicit
    ClientSocket(int tag);
    ~ClientSocket();
    bool    Connect(const SocketAddr& addr);
    bool    OnWritable();
    bool    OnError();
    SocketType GetSockType() const { return SocketType_Client; }

    void SetFailCallback(const std::function<void ()>& cb) { onConnectFail_ = cb; }

private:
    const int tag_;
    SocketAddr peerAddr_;
    std::function<void ()> onConnectFail_;
};

#endif



================================================
FILE: QBase/ConfigParser.cc
================================================
#include <vector>
#include "ConfigParser.h"
#include "Log/MemoryFile.h"

static const int  SPACE     = ' ';
static const int  TAB       = '\t';
static const int  NEWLINE   = '\n';
static const int  COMMENT   = '#';


static size_t  SkipBlank(const char* data, size_t len, size_t off)
{
    while (++ off < len)
    {
        if (SPACE != data[off] && TAB != data[off])
        {
            -- off;
            break;
        }
    }

    return off;
}

bool ConfigParser::Load(const char* FileName)
{
    InputMemoryFile  file;
    if (!file.Open(FileName))
        return false; // no such file

    data_.clear();

    size_t      maxLen = size_t(-1);
    const char* data = file.Read(maxLen);

    bool  bReadKey = true;
    std::string  key, value;
    key.reserve(64);
    value.reserve(64);

    size_t  off = 0;
    while (off < maxLen)
    {
        switch (data[off])
        {
            case COMMENT:
                while (++ off < maxLen)
                {
                    if (NEWLINE == data[off])
                    {
                        -- off;
                        break;
                    }
                }
                break;

            case NEWLINE:
                bReadKey = true;

                if (!key.empty())
                {
                    data_[key].push_back(value);
                    
                    key.clear();
                    value.clear();
                }
                
                off = SkipBlank(data, maxLen, off);
                break;
            
            case SPACE:
            case TAB:
                // 支持value中有空格
                if (bReadKey)
                {
                    bReadKey = false;
                    off = SkipBlank(data, maxLen, off); // 跳过所有分界空格
                }
                else
                {
                    value += data[off];
                }
                break;
            
            case '\r':
                break;
            
            default:
                if (bReadKey)
                    key += data[off];
                else
                    value += data[off];

                break;
        }

        ++ off;
    }
    
    file.Close();
    return true;
}

const std::vector<std::string>& ConfigParser::GetDataVector(const char* key) const
{
    auto it = data_.find(key);
    if (it == data_.end())
    {
        static const std::vector<std::string> kEmpty;
        return kEmpty;
    }
    
    return it->second;
}

#ifdef CONFIG_DEBUG
int main()
{
    ConfigParser   csv;
    csv.Load("config");
    csv.Print();
	
    std::cout << "=====================" << std::endl;
}
#endif



================================================
FILE: QBase/ConfigParser.h
================================================
#ifndef BERT_CONFIGPARSER_H
#define BERT_CONFIGPARSER_H

#include <map>
#include <string>
#include <sstream>

#ifdef CONFIG_DEBUG
#include <iostream>
#endif

class ConfigParser
{
public:
    bool Load(const char* FileName);

    template <typename T>
    T   GetData(const char* key, const T& default_ = T()) const;

    const std::vector<std::string>& GetDataVector(const char* key) const;
    

#ifdef CONFIG_DEBUG
    void Print()
    {
        std::cout << "//////////////////"<< std::endl;
        std::map<std::string, std::string>::const_iterator it = data_.begin();
        while (it != data_.end())
        {
            std::cout << it->first << ":" << it->second << "\n";
            ++ it;
        }
    }
#endif

private:
    typedef std::map<std::string, std::vector<std::string> > Data;
    
    Data data_;

    template <typename T>
    T  _ToType(const std::string& data) const;
};


template <typename T>
inline  T  ConfigParser::_ToType(const std::string& data) const
{
    T        t;
    std::istringstream  os(data);
    os >> t;
    return  t;
}

template <>
inline  const char*  ConfigParser::_ToType<const char* >(const std::string& data) const
{
    return  data.c_str();
}

template <>
inline  std::string  ConfigParser::_ToType<std::string >(const std::string& data) const
{
    return  data;
}


template <typename T>
inline  T  ConfigParser::GetData(const char* key, const T& default_) const
{
    auto it = data_.find(key);
    if (it == data_.end())
        return default_;

    return  _ToType<T>(it->second[0]); // only return first value
}

#endif



================================================
FILE: QBase/Delegate.h
================================================
#include <functional>
#include <list>


template <typename T>
class Delegate;

template <typename... Args>
class Delegate<void (Args...)>
{
public:
    typedef Delegate<void (Args...)> Self;

    Delegate() = default;

    Delegate(const Self& ) = delete;
    Self& operator= (const Self& ) = delete;

    template <typename F>
    Delegate(F&& f)
    {
        connect(std::forward<F>(f));
    }

    Delegate(Self&& other) : funcs_(std::move(other.funcs_))
    {
    }
    
    template <typename F>
    Self& operator+=(F&& f)
    {
        connect(std::forward<F>(f));
        return *this;
    }
    
    template <typename F>
    Self& operator-=(F&& f)
    {
        disconnect(std::forward<F>(f));
        return *this;
    }
    
    void operator()(Args&&... args)
    {
        call(std::forward<Args>(args)...);
    }
    
private:
    std::list<std::function<void (Args ...)> > funcs_;
    
    template <typename F>
    void connect(F&& f)
    {
        funcs_.emplace_back(std::forward<F>(f));
    }

    template <typename F>
    void disconnect(F&& f)
    {
        //std::cerr << "&f = " << typeid(&f).name() << ", and target = " << typeid(decltype(std::addressof(f))).name() << std::endl;
        for (auto it(funcs_.begin()); it != funcs_.end(); ++ it)
        {
            const auto& target = it->template target<decltype(std::addressof(f))>();
            if (target)
            {
                if(*target == &f)
                {
                    funcs_.erase(it);
                    return;
                }
            }
            else
            {
                const auto& target2 = it->template target<typename std::remove_reference<decltype(f)>::type>();

                // the function object must implement operator ==
                if (target2 && *target2 == f)
                {
                    funcs_.erase(it);
                    return;
                }
            }
        }
    }

    void call(Args&&... args)
    {
        // But what if rvalue args? FIXME
        for (const auto& f : funcs_)
            f(std::forward<Args>(args)...);
    }
};



================================================
FILE: QBase/EPoller.cc
================================================

#if defined(__gnu_linux__)

#include "EPoller.h"
#include "Log/Logger.h"

#include <errno.h>
#include <unistd.h>

namespace Epoll
{
    bool ModSocket(int epfd, int socket, uint32_t events, void* ptr);

    bool AddSocket(int epfd, int socket, uint32_t events, void* ptr)
    {
        if (socket < 0)
            return false;

        epoll_event  ev;
        ev.data.ptr= ptr;

        ev.events  = 0;
        if (events & EventTypeRead)
            ev.events |= EPOLLIN;
        if (events & EventTypeWrite)
            ev.events |= EPOLLOUT;

        return 0 == epoll_ctl(epfd, EPOLL_CTL_ADD, socket, &ev);
    }

    bool DelSocket(int epfd, int socket)
    {
        if (socket < 0)
            return false;

        epoll_event dummy;

        return 0 == epoll_ctl(epfd, EPOLL_CTL_DEL, socket, &dummy) ;
    }

    bool ModSocket(int epfd, int socket, uint32_t events, void* ptr)
    {
        if (socket < 0)
            return false;

        epoll_event  ev;
        ev.data.ptr= ptr;

        ev.events  = 0;
        if (events & EventTypeRead)
            ev.events |= EPOLLIN;
        if (events & EventTypeWrite)
            ev.events |= EPOLLOUT;

        return 0 == epoll_ctl(epfd, EPOLL_CTL_MOD, socket, &ev);
    }
}


Epoller::Epoller()
{
    multiplexer_ = ::epoll_create(512);
    INF << "create epoll:  " << multiplexer_;
}

Epoller::~Epoller()
{
    INF << "close epoll:  " << multiplexer_;
    if (multiplexer_ != -1)  
        ::close(multiplexer_);
}

bool Epoller::AddSocket(int sock, int events, void* userPtr)
{
    if (Epoll::AddSocket(multiplexer_, sock, events, userPtr))
        return  true;

    return (errno == EEXIST) && ModSocket(sock, events, userPtr);
}
    
bool Epoller::DelSocket(int sock, int events)
{
    return Epoll::DelSocket(multiplexer_, sock);
}

   
bool Epoller::ModSocket(int sock, int events, void* userPtr)
{
    if (events == 0)
        return DelSocket(sock, 0);

    if (Epoll::ModSocket(multiplexer_, sock, events, userPtr))
        return  true;

    return  errno == ENOENT && AddSocket(sock, events, userPtr);
}


int Epoller::Poll(std::vector<FiredEvent>& events, size_t  maxEvent, int timeoutMs)
{
    if (maxEvent == 0)
        return 0;

    while (events_.size() < maxEvent)
        events_.resize(2 * events_.size() + 1);

    int nFired = TEMP_FAILURE_RETRY(::epoll_wait(multiplexer_, &events_[0], maxEvent, timeoutMs));
    if (nFired == -1 && errno != EINTR && errno != EWOULDBLOCK)
        return -1;

    if (nFired > 0 && static_cast<size_t>(nFired) > events.size())
        events.resize(nFired);

    for (int i = 0; i < nFired; ++ i)
    {
        FiredEvent& fired = events[i];
        fired.events   = 0;
        fired.userdata = events_[i].data.ptr;

        if (events_[i].events & EPOLLIN)
            fired.events  |= EventTypeRead;

        if (events_[i].events & EPOLLOUT)
            fired.events  |= EventTypeWrite;

        if (events_[i].events & (EPOLLERR | EPOLLHUP))
            fired.events  |= EventTypeError;
    }

    return nFired;
}

#endif



================================================
FILE: QBase/EPoller.h
================================================
#ifndef BERT_EPOLLER_H
#define BERT_EPOLLER_H

#if defined(__gnu_linux__)

#include <sys/epoll.h>
#include <vector>
#include "Poller.h"

class Epoller : public Poller
{
public:
    Epoller();
   ~Epoller();

    bool AddSocket(int sock, int events, void* userPtr);
    bool ModSocket(int sock, int events, void* userPtr);
    bool DelSocket(int sock, int events);

    int Poll(std::vector<FiredEvent>& events, std::size_t maxEvent, int timeoutMs);

private:
    std::vector<epoll_event> events_;    
};

#endif

#endif



================================================
FILE: QBase/Kqueue.cc
================================================
#if defined(__APPLE__)

#include "Kqueue.h"
#include "Log/Logger.h"

#include <sys/event.h>
#include <errno.h>
#include <unistd.h>


Kqueue::Kqueue()
{
    multiplexer_ = ::kqueue();
    INF << "create kqueue:  " << multiplexer_;
}

Kqueue::~Kqueue()
{
    INF << "close kqueue: " << multiplexer_;
    if (multiplexer_ != -1)  
        ::close(multiplexer_);
}

bool Kqueue::AddSocket(int sock, int events, void* userPtr)
{
     struct kevent change[2];
         
     int  cnt = 0;
     
     if (events & EventTypeRead)
     {
         EV_SET(change + cnt, sock, EVFILT_READ, EV_ADD, 0, 0, userPtr);
         ++ cnt;
     }
                 
     if (events & EventTypeWrite)
     {
         EV_SET(change + cnt, sock, EVFILT_WRITE, EV_ADD, 0, 0, userPtr);
         ++ cnt;
     }
                     
     return kevent(multiplexer_, change, cnt, NULL, 0, NULL) != -1;
}
    
bool Kqueue::DelSocket(int sock, int events)
{
    struct kevent change[2];
    int cnt = 0;

    if (events & EventTypeRead)
    {
        EV_SET(change + cnt, sock, EVFILT_READ, EV_DELETE, 0, 0, NULL);
        ++ cnt;
    }

    if (events & EventTypeWrite)
    {
        EV_SET(change + cnt, sock, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
        ++ cnt;
    }
                    
    if (cnt == 0)
        return false;
                        
    return -1 != kevent(multiplexer_, change, cnt, NULL, 0, NULL);
}

   
bool Kqueue::ModSocket(int sock, int events, void* userPtr)
{
    bool ret = DelSocket(sock, EventTypeRead | EventTypeWrite);
    if (events == 0)
        return ret;

    return AddSocket(sock, events, userPtr);
}


int Kqueue::Poll(std::vector<FiredEvent>& events, std::size_t maxEvent, int timeoutMs)
{
    if (maxEvent == 0)
        return 0;

    while (events_.size() < maxEvent)
        events_.resize(2 * events_.size() + 1);

    struct timespec* pTimeout = NULL;  
    struct timespec  timeout;
    if (timeoutMs >= 0)
    {
        pTimeout = &timeout;
        timeout.tv_sec  = timeoutMs / 1000;
        timeout.tv_nsec = timeoutMs % 1000 * 1000000;
    }

    int nFired = ::kevent(multiplexer_, NULL, 0, &events_[0], static_cast<int>(maxEvent), pTimeout);
    if (nFired == -1)
        return -1;

    if (nFired > 0 && static_cast<size_t>(nFired) > events.size())
        events.resize(nFired);

    for (int i = 0; i < nFired; ++ i)
    {
        FiredEvent& fired = events[i];
        fired.events   = 0;
        fired.userdata = events_[i].udata;

        if (events_[i].filter == EVFILT_READ)
            fired.events  |= EventTypeRead;

        if (events_[i].filter == EVFILT_WRITE)
            fired.events  |= EventTypeWrite;

        if (events_[i].flags & EV_ERROR)
            fired.events  |= EventTypeError;
    }

    return nFired;
}

#endif



================================================
FILE: QBase/Kqueue.h
================================================
#ifndef BERT_KQUEUE_H
#define BERT_KQUEUE_H

#if defined(__APPLE__)

#include "Poller.h"
#include <vector>

class Kqueue : public Poller
{
public:
    Kqueue();
   ~Kqueue();

    bool AddSocket(int sock, int events, void* userPtr);
    bool ModSocket(int sock, int events, void* userPtr);
    bool DelSocket(int sock, int events);

    int Poll(std::vector<FiredEvent>& events, std::size_t maxEvent, int timeoutMs);

private:
    std::vector<struct kevent> events_;    
};

#endif

#endif



================================================
FILE: QBase/ListenSocket.cc
================================================

#include <errno.h>
#include <sys/socket.h>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include "Server.h"
#include "NetThreadPool.h"
#include "ListenSocket.h"
#include "Log/Logger.h"

namespace Internal
{

const int ListenSocket::LISTENQ = 1024;

ListenSocket::ListenSocket(int tag) :
    localPort_(INVALID_PORT),
    tag_(tag)
{
}

ListenSocket::~ListenSocket()
{
    Server::Instance()->DelListenSock(localSock_);
    USR << "Close ListenSocket " << localSock_;
}

bool ListenSocket::Bind(const SocketAddr& addr)
{
    if (addr.Empty())
        return  false;

    if (localSock_ != INVALID_SOCKET)
        return false;

    localPort_ = addr.GetPort();

    localSock_ = CreateTCPSocket();
    SetNonBlock(localSock_);
    SetNodelay(localSock_);
    SetReuseAddr(localSock_);
    SetRcvBuf(localSock_);
    SetSndBuf(localSock_);

    struct sockaddr_in serv = addr.GetAddr();

    int ret = ::bind(localSock_, (struct sockaddr*)&serv, sizeof serv);
    if (SOCKET_ERROR == ret)
    {
        CloseSocket(localSock_);
        ERR << "Cannot bind port " << addr.GetPort();
        return false;
    }
    ret = ::listen(localSock_, ListenSocket::LISTENQ);
    if (SOCKET_ERROR == ret)
    {
        CloseSocket(localSock_);
        ERR << "Cannot listen on port " << addr.GetPort();
        return false;
    }

    if (!NetThreadPool::Instance().AddSocket(shared_from_this(), EventTypeRead))
        return false;

    USR << "Success: listen on ("
        << addr.GetIP()
        << ":"
        << addr.GetPort()
        << ")";
    
    return true;
}

int ListenSocket::_Accept()
{
    socklen_t   addrLength = sizeof addrClient_;
    return ::accept(localSock_, (struct sockaddr *)&addrClient_, &addrLength);
}

bool ListenSocket::OnReadable()
{
    while (true)
    {
        int connfd = _Accept();
        if (connfd >= 0)
        {
            Server::Instance()->NewConnection(connfd, tag_);
        }
        else
        {
            bool result = false;
            switch (errno)
            {
            case EWOULDBLOCK:
            case ECONNABORTED:
            case EINTR:
                result = true;
                break;

            case EMFILE:
            case ENFILE:
                ERR << "Not enough file descriptor available!!!";
                result = true;
                break;

            case ENOBUFS:
                ERR << "Not enough memory";          
                result = true;

            default:
                ERR << "When accept, unknown error happened : " << errno;          
                break;
            }

            return result;
        }
    }
    
    return true;
}

bool ListenSocket::OnWritable()
{
    return false;
}

bool ListenSocket::OnError()
{
    if (Socket::OnError())
    {
        Server::Instance()->DelListenSock(localSock_);
        return  true;
    }

    return false;
}

}



================================================
FILE: QBase/ListenSocket.h
================================================

#ifndef BERT_LISTENSOCKET_H
#define BERT_LISTENSOCKET_H

#include "Socket.h"

namespace Internal
{

class ListenSocket : public Socket
{
    static const int LISTENQ;
public:
    explicit
    ListenSocket(int tag);
    ~ListenSocket();
    
    SocketType GetSocketType() const { return SocketType_Listen; }

    bool Bind(const SocketAddr& addr);
    bool OnReadable();
    bool OnWritable();
    bool OnError();

private:
    int _Accept();
    sockaddr_in     addrClient_;
    unsigned short  localPort_;
    const int       tag_;
};

}

#endif


================================================
FILE: QBase/Log/Logger.cc
================================================

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cstdarg>
#include <errno.h>
#include <sys/stat.h>


enum LogColor
{
    RED_COLOR    = 1,
    GREEN_COLOR     ,
    YELLOW_COLOR    ,
    NORMAL_COLOR    ,
    BLUE_COLOR      ,
    PURPLE_COLOR    ,
    WHITE_COLOR     ,
    COLOR_MAX       ,
} ;

#include "Logger.h"
#include "../Timer.h"


static const size_t DEFAULT_LOGFILESIZE = 32 * 1024 * 1024;
static const size_t PREFIX_LEVEL_LEN    = 6;
static const size_t PREFIX_TIME_LEN     = 24;

unsigned int ConvertLogLevel(const std::string& level)
{
    unsigned int l = logALL;
    
    if (level == "debug")
    {
        ;
    }
    else if (level == "verbose")
    {
        l &= ~logDEBUG;
    }
    else if (level == "notice")
    {
        l &= ~logDEBUG;
        l &= ~logINFO;
    }
    else if (level == "warning")
    {
        l &= ~logDEBUG;
        l &= ~logINFO;
        l &= ~logWARN; // redis warning is my error
    }
    else if (level == "none")
    {
        l = 0;
    }
    
    return l;
}

static bool MakeDir(const char* pDir)
{
    if (mkdir(pDir, 0755) != 0)
    {
        if (EEXIST != errno)
            return false;
    }
    
    return true;
}

__thread Logger*  g_log = nullptr;
__thread unsigned g_logLevel;
__thread unsigned g_logDest;

Logger::Logger() : level_(0),
                   dest_(0)
{
    lastLogMSecond_ = lastLogSecond_ = -1;
    _Reset();
}

Logger::~Logger()
{
    _CloseLogFile();
}

bool Logger::Init(unsigned int level, unsigned int dest, const char* pDir)
{
    level_      = level;
    dest_       = dest;
    directory_  = pDir ? pDir : ".";

    if (0 == level_)
    {
        return  true;
    }
  
    if (dest_ & logFILE)
    {
        if (directory_ == "." ||
            MakeDir(directory_.c_str()))
        {
            _OpenLogFile(_MakeFileName().c_str());
            return true;
        }
        
        return false;
    }

    if (!(dest_ & logConsole))
    {
        std::cerr << "log has no output, but loglevel is " << level << std::endl;
        return false;
    }
            
    return true;
}

bool Logger::_CheckChangeFile()
{
    if (!file_.IsOpen())
        return true;
    
    return file_.Offset() + MAXLINE_LOG > DEFAULT_LOGFILESIZE;
}

const std::string& Logger::_MakeFileName()
{
    char   name[32];
    Time   now;
    size_t len = now.FormatTime(name);
    name[len] = '\0';

    fileName_  = directory_ + "/" + name;
    fileName_ += ".log";

    return fileName_;
}

bool Logger::_OpenLogFile(const char* name)
{ 
    return  file_.Open(name, true);
}

void Logger::_CloseLogFile()
{
    return file_.Close();
}


void Logger::Flush(enum LogLevel level)
{
    if (IsLevelForbid(curLevel_) ||
        !(level & curLevel_) ||
         (pos_ <= PREFIX_TIME_LEN + PREFIX_LEVEL_LEN)) 
    {
        _Reset();
        return;
    }
    
    time_.Now();
#if 0
    time_.FormatTime(tmpBuffer_);
#else
    auto seconds = time_.MilliSeconds() / 1000;
    if (seconds != lastLogSecond_)
    {
        time_.FormatTime(tmpBuffer_);
        lastLogSecond_ = seconds;
    }
    else
    {
        auto msec = time_.MilliSeconds() % 1000;
        if (msec != lastLogMSecond_)
        {
            snprintf(tmpBuffer_ + 20, 4, "%03d", static_cast<int>(msec));
            tmpBuffer_[23] = ']';
            lastLogMSecond_ = msec;
        }
    }
#endif

    switch(level)
    {
    case logINFO:
        memcpy(tmpBuffer_ + PREFIX_TIME_LEN, "[INF]:", PREFIX_LEVEL_LEN);
        break;

    case logDEBUG:
        memcpy(tmpBuffer_ + PREFIX_TIME_LEN, "[DBG]:", PREFIX_LEVEL_LEN);
        break;

    case logWARN:
        memcpy(tmpBuffer_ + PREFIX_TIME_LEN, "[WRN]:", PREFIX_LEVEL_LEN);
        break;

    case logERROR:
        memcpy(tmpBuffer_ + PREFIX_TIME_LEN, "[ERR]:", PREFIX_LEVEL_LEN);
        break;

    case logUSR:
        memcpy(tmpBuffer_ + PREFIX_TIME_LEN, "[USR]:", PREFIX_LEVEL_LEN);
        break;

    default:    
        memcpy(tmpBuffer_ + PREFIX_TIME_LEN, "[???]:", PREFIX_LEVEL_LEN);
        break;
    }

    tmpBuffer_[pos_ ++] = '\n';
    tmpBuffer_[pos_] = '\0';
    
    if (LogManager::Instance().IsShutdown())
    {
        std::cout << tmpBuffer_;
    }
    else
    {
        // Format: level info, length info, log msg
        int logLevel = level;

        BufferSequence  contents;
        contents.count = 3;

        contents.buffers[0].iov_base = &logLevel;
        contents.buffers[0].iov_len  = sizeof logLevel;
        contents.buffers[1].iov_base = &pos_;
        contents.buffers[1].iov_len  = sizeof pos_;
        contents.buffers[2].iov_base = tmpBuffer_;
        contents.buffers[2].iov_len  = pos_;

        buffer_.Write(contents);
    }

    _Reset();
}

void Logger::_Color(unsigned int color)
{
#if defined(__gnu_linux__)
    const char* colorstrings[COLOR_MAX] = {
        "",
        "\033[1;31;40m",
        "\033[1;32;40m",
        "\033[1;33;40m",
        "\033[0m",
        "\033[1;34;40m",
        "\033[1;35;40m",
        "\033[1;37;40m",
    };

    fprintf(stdout, "%s", colorstrings[color]);
#endif
}

Logger&  Logger::operator<< (const char* msg)
{
    if (IsLevelForbid(curLevel_))
    {
        return *this;
    }

    const auto len = strlen(msg);
    if (pos_ + len >= MAXLINE_LOG)  
    {
        return *this;
    }

    memcpy(tmpBuffer_ + pos_, msg, len);
    pos_ += len;

    return  *this;
}

Logger&  Logger::operator<< (const unsigned char* msg)
{
    return operator<<(reinterpret_cast<const char*>(msg));
}

Logger&  Logger::operator<< (const std::string& msg)
{
    return operator<<(msg.c_str());
}

Logger&  Logger::operator<< (void* ptr)
{
    if (IsLevelForbid(curLevel_))
    {
        return *this;
    }
    
    if (pos_ + 18 < MAXLINE_LOG)
    {  
        unsigned long ptrValue = (unsigned long)ptr;
        auto nbytes = snprintf(tmpBuffer_ + pos_, MAXLINE_LOG - pos_, "%#018lx", ptrValue);
        if (nbytes > 0) pos_ += nbytes;
    }

    return  *this;
}


Logger&  Logger::operator<< (unsigned char a)
{
    if (IsLevelForbid(curLevel_))
    {
        return *this;
    }

    if (pos_ + 3 < MAXLINE_LOG)
    {
        auto nbytes = snprintf(tmpBuffer_ + pos_, MAXLINE_LOG - pos_, "%hhd", a);
        if (nbytes > 0) pos_ += nbytes;
    }

    return  *this;
}


Logger&  Logger::operator<< (char a)
{
    if (IsLevelForbid(curLevel_))
    {
        return *this;
    }
    if (pos_ + 3 < MAXLINE_LOG)
    {
        auto nbytes = snprintf(tmpBuffer_ + pos_, MAXLINE_LOG - pos_, "%hhu", a);
        if (nbytes > 0) pos_ += nbytes;
    }

    return  *this;
}

Logger&  Logger::operator<< (unsigned short a)
{
    if (IsLevelForbid(curLevel_))
    {
        return *this;
    }
    if (pos_ + 5 < MAXLINE_LOG)
    {
        auto nbytes = snprintf(tmpBuffer_ + pos_, MAXLINE_LOG - pos_, "%hu", a);
        if (nbytes > 0) pos_ += nbytes;
    }

    return  *this;
}

Logger&  Logger::operator<< (short a)
{
    if (IsLevelForbid(curLevel_))
    {
        return *this;
    }
    if (pos_ + 5 < MAXLINE_LOG)
    {
        auto nbytes = snprintf(tmpBuffer_ + pos_, MAXLINE_LOG - pos_, "%hd", a);
        if (nbytes > 0) pos_ += nbytes;
    }

    return  *this;
}

Logger&  Logger::operator<< (unsigned int a)
{
    if (IsLevelForbid(curLevel_))
    {
        return *this;
    }
    if (pos_ + 10 < MAXLINE_LOG)
    {
        auto nbytes = snprintf(tmpBuffer_ + pos_, MAXLINE_LOG - pos_, "%u", a);
        if (nbytes > 0) pos_ += nbytes;
    }

    return  *this;
}

Logger&  Logger::operator<< (int a)
{
    if (IsLevelForbid(curLevel_))
    {
        return *this;
    }
    if (pos_ + 10 < MAXLINE_LOG)
    {
        auto nbytes = snprintf(tmpBuffer_ + pos_, MAXLINE_LOG - pos_, "%d", a);
        if (nbytes > 0) pos_ += nbytes;
    }

    return  *this;
}

Logger&  Logger::operator<< (unsigned long a)
{
    if (IsLevelForbid(curLevel_))
    {
        return *this;
    }
    if (pos_ + 20 < MAXLINE_LOG)
    {
        auto nbytes = snprintf(tmpBuffer_ + pos_, MAXLINE_LOG - pos_, "%lu", a);
        if (nbytes > 0) pos_ += nbytes;
    }

    return  *this;
}

Logger&  Logger::operator<< (long a)
{
    if (IsLevelForbid(curLevel_))
    {
        return *this;
    }
    if (pos_ + 20 < MAXLINE_LOG)
    {
        auto nbytes = snprintf(tmpBuffer_ + pos_, MAXLINE_LOG - pos_, "%ld", a);
        if (nbytes > 0) pos_ += nbytes;
    }

    return  *this;
}

Logger&  Logger::operator<< (unsigned long long a)
{
    if (IsLevelForbid(curLevel_))
    {
        return *this;
    }
    if (pos_ + 20 < MAXLINE_LOG)
    {
        auto nbytes = snprintf(tmpBuffer_ + pos_, MAXLINE_LOG - pos_, "%llu", a);
        if (nbytes > 0) pos_ += nbytes;
    }

    return  *this;
}

Logger&  Logger::operator<< (long long a)
{
    if (IsLevelForbid(curLevel_))
    {
        return *this;
    }
    if (pos_ + 20 < MAXLINE_LOG)
    {
        auto nbytes = snprintf(tmpBuffer_ + pos_, MAXLINE_LOG - pos_, "%lld", a);
        if (nbytes > 0) pos_ += nbytes;
    }

    return  *this;
}

Logger&  Logger::operator<< (double a)
{
    if (IsLevelForbid(curLevel_))
    {
        return *this;
    }
    if (pos_ + 20 < MAXLINE_LOG)
    {
        auto nbytes = snprintf(tmpBuffer_ + pos_, MAXLINE_LOG - pos_, "%.6g", a);
        if (nbytes > 0) pos_ += nbytes;
    }
    
    return  *this;
}

bool Logger::Update()
{
    BufferSequence  data;
    buffer_.ProcessBuffer(data);
    
    AttachedBuffer  abf(data);
    auto nWritten = _Log(abf.ReadAddr(), abf.ReadableSize());
    buffer_.Skip(nWritten);
    
    return nWritten != 0;
}

void   Logger::_Reset()
{
    curLevel_ = 0;
    pos_  = PREFIX_LEVEL_LEN + PREFIX_TIME_LEN ;
}

size_t  Logger::_Log(const char* data, size_t dataLen)
{
    const auto minLogSize = sizeof(int) + sizeof(size_t);

    size_t   nOffset = 0;
    while (nOffset + minLogSize < dataLen)
    {
        int  level = *(int*)(data + nOffset);
        size_t len = *(size_t* )(data + nOffset + sizeof(int));
        if (dataLen < nOffset + minLogSize + len)
        {
            std::cerr << "_WriteLog skip 0!!!\n ";
            break;
        }

        _WriteLog(level, len, data + nOffset + minLogSize);
        nOffset += minLogSize + len;
    }

    return  nOffset;
}



void Logger::_WriteLog(int level, size_t nLen, const char* data)
{
    assert (nLen > 0 && data);
    
    if (dest_ & logConsole)
    {
        switch (level)
        {
        case logINFO:
            _Color(GREEN_COLOR);
            break;

        case logDEBUG:
            _Color(WHITE_COLOR);
            break;

        case logWARN:
            _Color(YELLOW_COLOR);
            break;

        case logERROR:
            _Color(RED_COLOR);
            break;

        case logUSR:
            _Color(PURPLE_COLOR);
            break;

        default:
            _Color(RED_COLOR);
            break;
        }

        fprintf(stdout, "%.*s", static_cast<int>(nLen), data);
        _Color(NORMAL_COLOR);
    }

    if (dest_ & logFILE)
    {
        while (_CheckChangeFile())
        {
            _CloseLogFile();
            if (!_OpenLogFile(_MakeFileName().c_str()))
            {   //OOPS!!! IMPOSSIBLE!
                break;
            }
        }

        assert (file_.IsOpen());
        file_.Write(data, nLen);
    }
}



LogHelper::LogHelper(LogLevel level) : level_(level)    
{
}
    
Logger& LogHelper::operator=(Logger& log) 
{
    log.Flush(level_);
    return  log;
}



LogManager& LogManager::Instance()
{
    static LogManager mgr;
    return mgr;
}

LogManager::LogManager()
{
    nullLog_.Init(0);
    logThread_.reset(new LogThread);
}

LogManager::~LogManager()
{
    for (auto log : logs_)
    {
        delete log;
    }
}

Logger*  LogManager::CreateLog(unsigned int level ,
               unsigned int dest ,
               const char* pDir)
{
    Logger*  pLog(new Logger);
    if (!pLog->Init(level, dest, pDir))
    {
        delete pLog;
        return &nullLog_;
    }
    else
    {
        std::lock_guard<std::mutex>  guard(logsMutex_);
        logs_.insert(pLog);
    }

    return pLog;
}

bool LogManager::StartLog()
{
    std::cout << "start log thread\n";

    assert (!logThread_->IsAlive());
    logThread_->SetAlive();
    shutdown_ = false;

    ThreadPool::Instance().ExecuteTask(std::bind(&LogThread::Run, logThread_));
    return true;
}

void LogManager::StopLog()
{
    std::cout << "stop log thread\n";
    shutdown_ = true;
    logThread_->Stop();
}

bool LogManager::Update()
{
    bool busy = false;
    
    std::lock_guard<std::mutex>  guard(logsMutex_);
  
    for (auto log : logs_)
    {
        if (log->Update() && !busy)
        {
            busy = true;
        }
    }

    return  busy;
}


void  LogManager::LogThread::Run()
{
    while (IsAlive())
    {
        if (!LogManager::Instance().Update())
            std::this_thread::sleep_for(std::chrono::milliseconds(1));
    }
}


================================================
FILE: QBase/Log/Logger.h
================================================
#ifndef BERT_LOGGER_H
#define BERT_LOGGER_H

#include <string>
#include <set>
#include <memory>

#include "../Threads/ThreadPool.h"
#include "../AsyncBuffer.h"
#include "MemoryFile.h"
#include "../Timer.h"

enum LogLevel
{
    logINFO     = 0x01 << 0,
    logDEBUG    = 0x01 << 1,
    logWARN     = 0x01 << 2,
    logERROR    = 0x01 << 3,
    logUSR      = 0x01 << 4,
    logALL      = 0xFFFFFFFF,
};

enum LogDest
{
    logConsole  = 0x01 << 0,
    logFILE     = 0x01 << 1,
    logSocket   = 0x01 << 2,  // TODO : LOG SERVER
};

unsigned int ConvertLogLevel(const std::string& level);

class Logger
{
public:

	friend class LogManager;

    Logger(const Logger& ) = delete;
    void operator= (const Logger& ) = delete;

    bool Init(unsigned int level = logDEBUG,
              unsigned int dest = logConsole,
              const char* pDir  = 0);
    
    void Flush(LogLevel  level);
    bool IsLevelForbid(unsigned int level)  {  return  !(level & level_); };

    Logger&  operator<<(const char* msg);
    Logger&  operator<<(const unsigned char* msg);
    Logger&  operator<<(const std::string& msg);
    Logger&  operator<<(void* );
    Logger&  operator<<(unsigned char a);
    Logger&  operator<<(char a);
    Logger&  operator<<(unsigned short a);
    Logger&  operator<<(short a);
    Logger&  operator<<(unsigned int a);
    Logger&  operator<<(int a);
    Logger&  operator<<(unsigned long a);
    Logger&  operator<<(long a);
    Logger&  operator<<(unsigned long long a);
    Logger&  operator<<(long long a);
    Logger&  operator<<(double a);

    Logger& SetCurLevel(unsigned int level)
    {
        curLevel_ = level;
        return *this;
    }

    bool   Update();

private:
    Logger();
   ~Logger();

    static const size_t MAXLINE_LOG = 2048; // TODO
    char            tmpBuffer_[MAXLINE_LOG];
    std::size_t     pos_;
    
    Time            time_;

    unsigned int    level_;
    std::string     directory_;
    unsigned int    dest_;
    std::string     fileName_;

    unsigned int    curLevel_;

    AsyncBuffer    buffer_;
    OutputMemoryFile file_;
    
    // for optimization
    uint64_t        lastLogSecond_;
    uint64_t        lastLogMSecond_;
    
    std::size_t     _Log(const char* data, std::size_t len);

    bool    _CheckChangeFile();
    const std::string& _MakeFileName();
    bool    _OpenLogFile(const char* name);
    void    _CloseLogFile();
    void    _WriteLog(int level, std::size_t nLen, const char* data);
    void    _Color(unsigned int color);
    void    _Reset();
};



class LogHelper
{
public:
    LogHelper(LogLevel level);
    Logger& operator=(Logger& log);

private:
    LogLevel    level_;
};



class LogManager
{
public:
    static LogManager& Instance();

    ~LogManager();
    
    LogManager(const LogManager& ) = delete;
    void operator=(const LogManager& ) = delete;

    Logger*  CreateLog(unsigned int level = logDEBUG,
                       unsigned int dest = logConsole,
                       const char* pDir  = 0);

    bool    StartLog();
    void    StopLog();
    bool    Update();

    Logger* NullLog()  {  return  &nullLog_;  }
    bool    IsShutdown() const { return shutdown_; }

private:
    LogManager();

    Logger  nullLog_;

    std::mutex          logsMutex_;
    std::set<Logger* >  logs_;
    

    class LogThread
    {
    public:
        LogThread() : alive_(false) {}
        
        void  SetAlive() { alive_ = true; }
        bool  IsAlive() const { return alive_; }
        void  Stop() {  alive_ = false; }
        
        void  Run();
    private:
        std::atomic<bool> alive_;
    };
    
    std::shared_ptr<LogThread>  logThread_;
    std::atomic<bool> shutdown_;
};

extern __thread Logger*  g_log;
extern __thread unsigned g_logLevel;
extern __thread unsigned g_logDest;

#undef INF
#undef DBG
#undef WRN
#undef ERR
#undef USR

#define  LOG_DBG(x)      (LogHelper(logDEBUG))=(x ? x : LogManager::Instance().NullLog())->SetCurLevel(logDEBUG)
#define  LOG_INF(x)      (LogHelper(logINFO))=(x ? x : LogManager::Instance().NullLog())->SetCurLevel(logINFO)
#define  LOG_WRN(x)      (LogHelper(logWARN))=(x ? x : LogManager::Instance().NullLog())->SetCurLevel(logWARN)
#define  LOG_ERR(x)      (LogHelper(logERROR))=(x ? x : LogManager::Instance().NullLog())->SetCurLevel(logERROR)
#define  LOG_USR(x)      (LogHelper(logUSR))=(x ? x : LogManager::Instance().NullLog())->SetCurLevel(logUSR)

#define  DBG      LOG_DBG(g_log)
#define  INF      LOG_INF(g_log)
#define  WRN      LOG_WRN(g_log)
#define  ERR      LOG_ERR(g_log)
#define  USR      LOG_USR(g_log)

#endif



================================================
FILE: QBase/Log/MemoryFile.cc
================================================
#include <errno.h>
#include <fcntl.h>
#include <assert.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>


#include "MemoryFile.h"

using std::size_t;

static const size_t kDefaultSize = 1 * 1024 * 1024;

static const int   kInvalidFile = -1;
static char* const kInvalidAddr = reinterpret_cast<char*>(-1);

InputMemoryFile::InputMemoryFile() : file_(kInvalidFile),
                                     memory_(kInvalidAddr),
                                     offset_(0),
                                     size_(0)
{
}

InputMemoryFile::~InputMemoryFile()
{
    Close();
}

bool InputMemoryFile::_MapReadOnly()
{
    assert (file_ != kInvalidFile);
    assert (size_ == 0);

    struct stat st;
    fstat(file_, &st);
    size_ = st.st_size;

    memory_ = (char* )::mmap(0, size_, PROT_READ, MAP_PRIVATE, file_, 0);
    return memory_ != kInvalidAddr;
}

void InputMemoryFile::_CheckAvail(std::size_t len)
{
    if (offset_ + len > size_)
    {
        std::string s("Not enough data, require " + std::to_string(len) + ", only has " + std::to_string(size_ - offset_));
        throw std::runtime_error(std::move(s));
    }
}

void InputMemoryFile::Attach(const char* data, size_t len)
{
    memory_ = (char* )data;
    size_ = len;
    offset_ = 0;
    file_ = kInvalidFile;
}

bool  InputMemoryFile::Open(const char* file)
{
    Close();

    file_ = ::open(file, O_RDONLY);

    if (file_ == kInvalidFile)
    {
        char err[128];
        snprintf(err, sizeof err - 1, "OpenForRead %s failed\n", file);
        return false;
    }

    offset_ = 0;
    return _MapReadOnly();
}

void  InputMemoryFile::Close()
{
    if (file_ != kInvalidFile)
    {
        ::munmap(memory_, size_);
        ::close(file_);

        file_      = kInvalidFile;
        size_      = 0;
        memory_   = kInvalidAddr;
        offset_    = 0;
    }
}

const char* InputMemoryFile::Read(std::size_t& len)
{
    if (size_ <= offset_)
        return 0;

    if (offset_ + len > size_)
        len = size_ - offset_;

    return  memory_ + offset_;
}

void InputMemoryFile::Skip(size_t len)
{
    _CheckAvail(len);
    offset_ += len;
}

bool InputMemoryFile::IsOpen() const
{
    return  file_ != kInvalidFile;
}


// OutputMemoryFile

OutputMemoryFile::OutputMemoryFile() : file_(kInvalidFile),
                                       memory_(kInvalidAddr),
                                       offset_(0),
                                       size_(0),
                                       syncPos_(0)
{
}

OutputMemoryFile::~OutputMemoryFile()
{
    Close();
}

void OutputMemoryFile::_ExtendFileSize(size_t  size)
{
    assert(file_ != kInvalidFile);

    if (size > size_)
        Truncate(size);
}

bool  OutputMemoryFile::Open(const std::string&  file, bool bAppend)
{
    return Open(file.c_str(), bAppend);
}

bool  OutputMemoryFile::Open(const char* file, bool bAppend)
{
    Close();

    file_ = ::open(file, O_RDWR | O_CREAT | (bAppend ? O_APPEND : 0), 0644);

    if (file_ == kInvalidFile)
    {
        char err[128];
        snprintf(err, sizeof err - 1, "OpenWriteOnly %s failed\n", file);
        perror(err);
        return false;
    }
    if (bAppend)
    {
        struct stat st;
        fstat(file_, &st);
        size_ = std::max<decltype(size_)>(st.st_size, kDefaultSize);
        offset_ = st.st_size;
    }
    else
    {
        size_ = kDefaultSize;
        offset_ = 0;
    }

    ::ftruncate(file_, size_);
    return _MapWriteOnly();
}

void  OutputMemoryFile::Close()
{
    if (file_ != kInvalidFile)
    {
        ::munmap(memory_, size_);
        ::ftruncate(file_, offset_);
        ::close(file_);

        file_ = kInvalidFile;
        size_ = 0;
        memory_ = kInvalidAddr;
        offset_ = 0;
        syncPos_ = 0;
    }
}

bool    OutputMemoryFile::Sync()
{
    if (file_ == kInvalidFile)
        return false;

    if (syncPos_ >= offset_)
        return false;

    ::msync(memory_ + syncPos_, offset_ - syncPos_, MS_SYNC);
    syncPos_ = offset_;
    
    return true;
}

bool OutputMemoryFile::_MapWriteOnly()
{
    if (size_ == 0 || file_ == kInvalidFile)
        return false;

#if 0
    // codes below cause coredump when file size > 4MB
    if (m_memory != kInvalidAddr)
        ::munmap(m_memory, m_size);
#endif
    memory_ = (char*)::mmap(0, size_, PROT_WRITE, MAP_SHARED, file_, 0);
    return (memory_ != kInvalidAddr);
}

void OutputMemoryFile::Truncate(std::size_t  size)
{
    if (size == size_)
        return;

    size_ = size;
    ::ftruncate(file_, size);

    if (offset_> size_)
        offset_ = size_;

    _MapWriteOnly();
}

void OutputMemoryFile::TruncateTailZero()
{
    if (file_ == kInvalidFile)
        return;

    size_t tail = size_;
    while (tail > 0 && memory_[--tail] == '\0')
        ;

    ++ tail;

    Truncate(tail);
}

bool OutputMemoryFile::IsOpen() const
{
    return  file_ != kInvalidFile;
}

// consumer
void OutputMemoryFile::Write(const void* data, size_t len)
{
    _AssureSpace(len);
    assert(memory_);

    ::memcpy(memory_ + offset_, data, len);
    offset_ += len;
    assert(offset_ <= size_);
}

void OutputMemoryFile::_AssureSpace(size_t  size)
{
    size_t  newSize = size_;

    while (offset_ + size > newSize)
    {
        if (newSize == 0)
            newSize = kDefaultSize;
        else
            newSize <<= 1;
    }

    _ExtendFileSize(newSize);
}



================================================
FILE: QBase/Log/MemoryFile.h
================================================
#ifndef BERT_MEMORYFILE_H
#define BERT_MEMORYFILE_H

#include <string>
#include <stdexcept>

class InputMemoryFile
{
public:
    InputMemoryFile();
   ~InputMemoryFile();

    bool Open(const char* file);
    void Close();

    void Attach(const char* data, size_t len);

    const char* Read(std::size_t& len);
    template <typename T>
    T Read();
    void Skip(std::size_t len);

    bool IsOpen() const;

private:
    bool _MapReadOnly();
    void _CheckAvail(std::size_t len);

    int file_;
    char* memory_;
    std::size_t offset_;
    std::size_t size_;
};

template <typename T>
inline T InputMemoryFile::Read()
{
    _CheckAvail(sizeof(T));

    T res(*reinterpret_cast<T* >(memory_ + offset_));
    offset_ += sizeof(T);
    
    return res;
}


class OutputMemoryFile
{
public:
    OutputMemoryFile();
   ~OutputMemoryFile();

    bool Open(const std::string& file, bool bAppend = true);
    bool Open(const char* file, bool bAppend = true);
    void Close();
    bool Sync();

    void Truncate(std::size_t size);
    //!! if process terminated abnormally, erase the trash data
    //requirement: text file.
    void TruncateTailZero();

    void Write(const void* data, std::size_t len);
    template <typename T>
    void Write(const T& t);
    
    std::size_t Offset() const { return offset_; }
    bool IsOpen() const;

private:
    bool _MapWriteOnly();
    void _ExtendFileSize(std::size_t size);
    void _AssureSpace(std::size_t size);

    int file_;
    char* memory_;
    std::size_t offset_;
    std::size_t size_;
    std::size_t syncPos_;
};


template <typename T>
inline void OutputMemoryFile::Write(const T& t)
{
    this->Write(&t, sizeof t);
}

#endif



================================================
FILE: QBase/NetThreadPool.cc
================================================

#include "NetThreadPool.h"
#include "StreamSocket.h"
#include "Log/Logger.h"
#include "Timer.h"

#if defined(__gnu_linux__)
#include "EPoller.h"
#elif defined(__APPLE__)
#include "Kqueue.h"
#else
#error "Only support osx and linux"
#endif

#include <cassert>
#include <errno.h>


namespace Internal
{

NetThread::NetThread() : running_(true), newCnt_(0)
{
#if defined(__gnu_linux__)
    poller_.reset(new Epoller);
#else
    poller_.reset(new Kqueue);
#endif
}

NetThread::~NetThread()
{
}

void NetThread::AddSocket(PSOCKET task, uint32_t events)
{
    std::lock_guard<std::mutex>    guard(mutex_);
    newTasks_.push_back(std::make_pair(task, events)); 
    ++ newCnt_;

    assert (newCnt_ == static_cast<int>(newTasks_.size()));
}

void NetThread::ModSocket(PSOCKET task, uint32_t events)
{
    poller_->ModSocket(task->GetSocket(), events, task.get());
}

void NetThread::RemoveSocket(PSOCKET task, uint32_t events)
{
    poller_->DelSocket(task->GetSocket(), events);
}

void NetThread::_TryAddNewTasks()
{
    if (newCnt_ > 0 && mutex_.try_lock())
    { 
        NewTasks  tmp;
        newTasks_.swap(tmp); 
        newCnt_ = 0; 
        mutex_.unlock();

        auto iter(tmp.begin()),
             end (tmp.end());

        for (; iter != end; ++ iter) 
            _AddSocket(iter->first, iter->second); 
    }
}

void NetThread::_AddSocket(PSOCKET task, uint32_t events)
{
    if (poller_->AddSocket(task->GetSocket(), events, task.get()))
        tasks_.push_back(task);
}

//////////////////////////////////
void RecvThread::Run()
{
    // init log;
    g_logLevel = logALL;
    g_logDest  = logFILE;
    if (g_logLevel && g_logDest)
    {
        g_log = LogManager::Instance().CreateLog(g_logLevel, g_logDest, "recvthread_log");
    }

    std::deque<PSOCKET >::iterator it;

    int loopCount = 0;
    while (IsAlive())
    {
        _TryAddNewTasks();

        if (tasks_.empty())
        {
            std::this_thread::sleep_for(std::chrono::microseconds(100));
            continue;
        }

        const int nReady = poller_->Poll(firedEvents_, static_cast<int>(tasks_.size()), 1);
        for (int i = 0; i < nReady; ++ i)
        {
            assert (!(firedEvents_[i].events & EventTypeWrite));

            Socket* sock = (Socket* )firedEvents_[i].userdata;

            if (firedEvents_[i].events & EventTypeRead)
            {
                if (!sock->OnReadable())
                {
                    sock->OnError();
                }
            }

            if (firedEvents_[i].events & EventTypeError)
            {
                sock->OnError();
            }
        }
        
        if (nReady == 0)
            loopCount *= 2;
        
        if (++ loopCount < 100000)
            continue;

        loopCount = 0;

        for (auto it(tasks_.begin());
             it != tasks_.end();
             )
        {
            if ((*it)->Invalid())
            {
                NetThreadPool::Instance().DisableRead(*it);
                RemoveSocket(*it, EventTypeRead);
                it = tasks_.erase(it);
            }
            else
            {
                ++ it;
            }
        }
    }
}

void SendThread::Run( )
{
    // init log;
    g_logLevel = logALL;
    g_logDest  = logFILE;
    if (g_logLevel && g_logDest)
    {
        g_log = LogManager::Instance().CreateLog(g_logLevel, g_logDest, "sendthread_log");
    }
    
    std::deque<PSOCKET >::iterator    it;
    
    while (IsAlive())
    {
        _TryAddNewTasks();

        size_t  nOut = 0;
        for (it = tasks_.begin(); it != tasks_.end(); )
        {
            Socket::SocketType  type  = (*it)->GetSocketType();
            Socket*  sock = (*it).get();
            
            if (type == Socket::SocketType_Stream)
            {
                StreamSocket*  tcpSock = static_cast<StreamSocket* >(sock);
                if (!tcpSock->Send())
                    tcpSock->OnError();
            }
            
            if (sock->Invalid())
            {
                NetThreadPool::Instance().DisableWrite(*it);
                RemoveSocket(*it, EventTypeWrite);
                it = tasks_.erase(it);
            }
            else
            {
                if (sock->epollOut_)
                    ++ nOut;

                ++ it;
            }
        }
        
        if (nOut == 0)
        {
            std::this_thread::sleep_for(std::chrono::microseconds(100));
            continue;
        }

        const int nReady = poller_->Poll(firedEvents_, static_cast<int>(tasks_.size()), 1);
        for (int i = 0; i < nReady; ++ i)
        {
            Socket* sock = (Socket* )firedEvents_[i].userdata;
            
            assert (!(firedEvents_[i].events & EventTypeRead));
            if (firedEvents_[i].events & EventTypeWrite)
            {
                if (!sock->OnWritable())
                {
                    sock->OnError();
                }
            }
            
            if (firedEvents_[i].events & EventTypeError)
            {
                sock->OnError();
            }
        }
    }
}


void NetThreadPool::StopAllThreads()
{
    recvThread_->Stop();
    recvThread_.reset();
    sendThread_->Stop();
    sendThread_.reset();

    INF << "Stop all recv and send threads";
}

bool NetThreadPool::AddSocket(PSOCKET sock, uint32_t  events)
{
    if (events & EventTypeRead)
    {
        if (!recvThread_)
            return false;

        recvThread_->AddSocket(sock, EventTypeRead);
    }

    if (events & EventTypeWrite)
    {
        if (!sendThread_)
            return false;
    
        sendThread_->AddSocket(sock, EventTypeWrite);
    }

    return true;
}

bool NetThreadPool::StartAllThreads()
{
    recvThread_.reset(new RecvThread);
    sendThread_.reset(new SendThread);
    
    ThreadPool::Instance().ExecuteTask(std::bind(&RecvThread::Run, recvThread_));
    ThreadPool::Instance().ExecuteTask(std::bind(&SendThread::Run, sendThread_));

    return  true;
}
    

void NetThreadPool::EnableRead(const std::shared_ptr<Socket>& sock)
{
    if (recvThread_)
        recvThread_->ModSocket(sock, EventTypeRead);
}

void NetThreadPool::EnableWrite(const std::shared_ptr<Socket>& sock)
{
    if (sendThread_)
        sendThread_->ModSocket(sock, EventTypeWrite);
}
   
void NetThreadPool::DisableRead(const std::shared_ptr<Socket>& sock)
{
    if (recvThread_)
        recvThread_->ModSocket(sock, 0);
}

void NetThreadPool::DisableWrite(const std::shared_ptr<Socket>& sock)
{
    if (sendThread_)
        sendThread_->ModSocket(sock, 0);
}

}



================================================
FILE: QBase/NetThreadPool.h
================================================
#ifndef BERT_NETTHREADPOOL_H
#define BERT_NETTHREADPOOL_H

#include <deque>
#include <vector>
#include <unistd.h>
#include <memory>
#include <atomic>
#include <mutex>
#include "Poller.h"
#include "Threads/ThreadPool.h"

inline long GetCpuNum()
{
    return  sysconf(_SC_NPROCESSORS_ONLN);
}

class   Socket;
typedef std::shared_ptr<Socket> PSOCKET;

namespace Internal
{


class NetThread
{
public:
    NetThread();
    virtual ~NetThread();

    bool IsAlive() const  {  return running_; }
    void Stop()           {  running_ = false;}

    void AddSocket(PSOCKET , uint32_t event);
    void ModSocket(PSOCKET , uint32_t event);
    void RemoveSocket(PSOCKET, uint32_t event);

protected:
    std::unique_ptr<Poller>        poller_;
    std::vector<FiredEvent > firedEvents_;    
    std::deque<PSOCKET>      tasks_;
    void  _TryAddNewTasks();

private:
    std::atomic<bool> running_;

    std::mutex   mutex_;
    typedef std::vector<std::pair<std::shared_ptr<Socket>, uint32_t> >    NewTasks; 
    NewTasks     newTasks_; 
    std::atomic<int> newCnt_;
    void _AddSocket(PSOCKET , uint32_t  event);
};

class RecvThread : public NetThread
{
public:
    void Run();
};

class SendThread : public NetThread
{
public:
    void Run();
};


///////////////////////////////////////////////
class NetThreadPool
{
    std::shared_ptr<RecvThread> recvThread_;
    std::shared_ptr<SendThread> sendThread_;

public:
    NetThreadPool() = default;

    NetThreadPool(const NetThreadPool& ) = delete;
    void operator= (const NetThreadPool& ) = delete;

    bool AddSocket(PSOCKET , uint32_t event);
    bool StartAllThreads();
    void StopAllThreads();
    
    void EnableRead(const std::shared_ptr<Socket>& sock);
    void EnableWrite(const std::shared_ptr<Socket>& sock);
    void DisableRead(const std::shared_ptr<Socket>& sock);
    void DisableWrite(const std::shared_ptr<Socket>& sock);

    static NetThreadPool& Instance()
    {
        static  NetThreadPool    pool;
        return  pool;
    }
};

}

#endif



================================================
FILE: QBase/Poller.h
================================================
#ifndef BERT_POLLER_H
#define BERT_POLLER_H

#include <vector>

enum EventType
{
    EventTypeRead  = 0x1,
    EventTypeWrite = 0x1 << 1,
    EventTypeError = 0x1 << 2,
};

struct FiredEvent
{
    int   events;
    void* userdata;

    FiredEvent() : events(0), userdata(0)
    {
    }
};

class Poller
{
public:
    Poller() : multiplexer_(-1)
    {
    }

    virtual ~Poller()
    {
    }

    virtual bool AddSocket(int sock, int events, void* userPtr) = 0;
    virtual bool ModSocket(int sock, int events, void* userPtr) = 0;
    virtual bool DelSocket(int sock, int events) = 0;

    virtual int Poll(std::vector<FiredEvent>& events, std::size_t maxEv, int timeoutMs) = 0;

protected:
    int  multiplexer_;
};

#endif



================================================
FILE: QBase/README.md
================================================
# QBase

QBase最初是C++03代码,由于历史原因,再加上它也极其稳定,我不打算替换了。

感兴趣的可以看我的另外一个最新后台开发基础库[ananas](https://github.com/loveyacper/ananas)


================================================
FILE: QBase/Server.cc
================================================
#include <signal.h>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <sys/resource.h>
#include "Server.h"
#include "ListenSocket.h"
#include "ClientSocket.h"
#include "StreamSocket.h"
#include "NetThreadPool.h"
#include "Timer.h"
#include "Log/Logger.h"

using Internal::NetThreadPool;


void Server::IntHandler(int signum)
{
    if (Server::Instance() != NULL)
        Server::Instance()->Terminate();
}

void Server::HupHandler(int signum)
{
    if (Server::Instance() != NULL)
        Server::Instance()->reloadCfg_ = true;
}

Server* Server::sinstance_ = nullptr;

std::set<int> Server::slistenSocks_;

Server::Server() : bTerminate_(false), reloadCfg_(false)
{
    if (sinstance_ == NULL)
        sinstance_ = this;
    else
        ::abort();
}

Server::~Server()
{
    sinstance_ = NULL;
}

bool Server::_RunLogic() 
{
    return tasks_.DoMsgParse();
}

bool Server::TCPBind(const SocketAddr& addr, int tag)
{
    using Internal::ListenSocket;

    auto s(std::make_shared<ListenSocket>(tag));

    if (s->Bind(addr))
    {
        slistenSocks_.insert(s->GetSocket());
        return true;
    }
    
    return false;
}


void Server::TCPReconnect(const SocketAddr& peer, int tag)
{
    INF << __FUNCTION__ << peer.GetIP();

    Timer* pTimer = TimerManager::Instance().CreateTimer();
    pTimer->Init(2 * 1000, 1);
    pTimer->SetCallback([&, tag, peer]() {
        USR << "OnTimer reconnect to " << peer.GetIP() << ":" << peer.GetPort();
        Server::Instance()->TCPConnect(peer, [=]() { Server::Instance()->TCPReconnect(peer, tag); }, tag);
    });


    TimerManager::Instance().AsyncAddTimer(pTimer);
}

void Server::TCPConnect(const SocketAddr& peer, int tag)
{
    _TCPConnect(peer, nullptr, tag);
}

void Server::TCPConnect(const SocketAddr& peer, const std::function<void ()>& cb, int tag)
{
    _TCPConnect(peer, &cb, tag);
}

void Server::_TCPConnect(const SocketAddr& peer, const std::function<void ()>* cb, int tag)
{
    auto client(std::make_shared<ClientSocket>(tag));
    if (cb)
        client->SetFailCallback(*cb);

    client->Connect(peer);
}

void Server::MainLoop(bool daemon)
{
    struct sigaction sig;
    ::memset(&sig, 0, sizeof(sig));
    sig.sa_handler = &Server::IntHandler;
    sigaction(SIGINT, &sig, NULL);
    sigaction(SIGQUIT, &sig, NULL);
    sigaction(SIGABRT, &sig, NULL);
    sigaction(SIGTERM, &sig, NULL);
    sig.sa_handler =  &Server::HupHandler;
    sigaction(SIGHUP, &sig, NULL);

    sig.sa_handler = SIG_IGN;
    sigaction(SIGPIPE, &sig, NULL);

    ::pthread_atfork(nullptr, nullptr, AtForkHandler);
    
    ::srand(static_cast<unsigned int>(time(NULL)));
    ::srandom(static_cast<unsigned int>(time(NULL)));

    // daemon must be first, before descriptor open, threads create
    if (daemon)
    {
        ::daemon(1, 0);
    }
    
    if (NetThreadPool::Instance().StartAllThreads() &&
        _Init() &&
        LogManager::Instance().StartLog())
    {
        while (!bTerminate_)
        {
            if (reloadCfg_)
            {
                ReloadConfig();
                reloadCfg_ = false;
            }

            if (!_RunLogic())
                std::this_thread::sleep_for(std::chrono::microseconds(100));
        }
    }

    tasks_.Clear();
    _Recycle();
    NetThreadPool::Instance().StopAllThreads();
    LogManager::Instance().StopLog();
    
    ThreadPool::Instance().JoinAll();
}


std::shared_ptr<StreamSocket> Server::_OnNewConnection(int tcpsock, int tag)
{
    WRN << "implement your tcp accept, now close socket " << tcpsock;
    return std::shared_ptr<StreamSocket>(nullptr);
}

void Server::NewConnection(int sock, int tag, const std::function<void ()>& cb)
{
    if (sock == INVALID_SOCKET)
        return;

    auto conn = _OnNewConnection(sock, tag);
    
    if (!conn)
    {
        Socket::CloseSocket(sock);
        return;
    }

    conn->SetOnDisconnect(cb);

    if (NetThreadPool::Instance().AddSocket(conn, EventTypeRead | EventTypeWrite))
        tasks_.AddTask(conn);
}

void Server::AtForkHandler()
{
    for (auto sock : slistenSocks_)
    {
        close(sock);
    }
}

void Server::DelListenSock(int sock)
{
    if (sock == INVALID_SOCKET)
        return;
    
    auto n = slistenSocks_.erase(sock);

    if (n != 1)
        ERR << "Failed DelListenSock " << sock;
    else
        INF << "Success DelListenSock " << sock;
}


================================================
FILE: QBase/Server.h
================================================

#ifndef BERT_SERVER_H
#define BERT_SERVER_H

#include <set>
#include <functional>
#include "TaskManager.h"

struct SocketAddr;

class Server    // Should singleton
{
protected:
    virtual bool _RunLogic();
    virtual void _Recycle() { }
    virtual bool _Init() = 0;
    
    Server();

    Server(const Server& ) = delete;
    void operator= (const Server& ) = delete;
    
public:
    virtual ~Server();

    bool  TCPBind(const SocketAddr& listenAddr, int tag);
    void  TCPReconnect(const SocketAddr& peer, int tag);

    static Server*  Instance() {   return   sinstance_;  }

    bool IsTerminate() const { return bTerminate_; }
    void Terminate()  { bTerminate_ = true; }

    void MainLoop(bool daemon = false);
    void NewConnection(int sock, int tag, const std::function<void ()>& cb = std::function<void ()>());

    void TCPConnect(const SocketAddr& peer, int tag);
    void TCPConnect(const SocketAddr& peer, const std::function<void ()>& cb, int tag);

    size_t  TCPSize() const  {  return  tasks_.TCPSize(); }

    // SIGHUP handler, in fact, you should load config use this function;
    virtual void ReloadConfig()    { }

    static void IntHandler(int sig);
    static void HupHandler(int sig);

    std::shared_ptr<StreamSocket>  FindTCP(unsigned int id) const { return tasks_.FindTCP(id); }
    
    static void AtForkHandler();
    static void DelListenSock(int sock);

private:
    virtual std::shared_ptr<StreamSocket> _OnNewConnection(int tcpsock, int tag);
    void _TCPConnect(const SocketAddr& peer, const std::function<void()>* cb = nullptr, int tag = -1);

    std::atomic<bool> bTerminate_;
    Internal::TaskManager   tasks_;
    bool          reloadCfg_;
    static Server*   sinstance_;
    
    static std::set<int>  slistenSocks_;
};

#endif



================================================
FILE: QBase/Socket.cc
================================================

#include <cassert>

#include <errno.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <sys/ioctl.h>
#include <net/if.h>

#if defined(__APPLE__)
#include <unistd.h>
#endif

#include "Socket.h"
#include "NetThreadPool.h"
#include "Log/Logger.h"

std::atomic<std::size_t> Socket::sid_;

Socket::Socket() : localSock_(INVALID_SOCKET),
                   epollOut_(false),
                   invalid_(false)
{
    ++ sid_;
    
    std::size_t expect = 0;
    sid_.compare_exchange_strong(expect, 1);
                   
    id_ = sid_;
}

Socket::~Socket()
{
    CloseSocket(localSock_);
}

int Socket::CreateUDPSocket()
{
    return ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
}

bool Socket::OnError()   
{
    bool expect = false;
    if (invalid_.compare_exchange_strong(expect, true))
    {
        return true;
    }

    return false;
}

int Socket::CreateTCPSocket()
{
    return ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
}

void Socket::CloseSocket(int& sock)
{
    if (sock != INVALID_SOCKET)
    {
        ::shutdown(sock, SHUT_RDWR);
        ::close(sock);
        DBG << "CloseSocket " << sock;
        sock = INVALID_SOCKET;
    }
}

void  Socket::SetNonBlock(int sock, bool nonblock)
{
    int flag = ::fcntl(sock, F_GETFL, 0); 
    assert(flag >= 0 && "Non Block failed");

    if (nonblock)
        flag = ::fcntl(sock, F_SETFL, flag | O_NONBLOCK);
    else
        flag = ::fcntl(sock, F_SETFL, flag & ~O_NONBLOCK);
    
}

void Socket::SetNodelay(int sock)
{
    int nodelay = 1;
    ::setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const char*)&nodelay, sizeof(int));
}

void Socket::SetSndBuf(int sock, socklen_t winsize)
{
    ::setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (const char*)&winsize, sizeof(winsize));
}

void Socket::SetRcvBuf(int sock, socklen_t winsize)
{
    ::setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (const char*)&winsize, sizeof(winsize));
}

void Socket::SetReuseAddr(int sock)
{
    int reuse = 1;
    ::setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse));
}

bool Socket::GetLocalAddr(int  sock, SocketAddr& addr)
{
    sockaddr_in localAddr;
    socklen_t   len = sizeof(localAddr);

    if (0 == ::getsockname(sock, (struct sockaddr*)&localAddr, &len))
    {
        addr.Init(localAddr);
    }
    else
    {
        return  false;
    }

    return  true;
}

bool  Socket::GetPeerAddr(int  sock, SocketAddr& addr)
{
    sockaddr_in  remoteAddr;
    socklen_t    len = sizeof(remoteAddr);
    if (0 == ::getpeername(sock, (struct sockaddr*)&remoteAddr, &len))
    {
        addr.Init(remoteAddr);
    }
    else
    {
        return  false;
    }

    return  true;
}

void Socket::GetMyAddrInfo(unsigned int* addrs, int num)
{
    char buff[BUFSIZ];
    struct ifconf conf;
    conf.ifc_len = BUFSIZ;
    conf.ifc_buf = buff;

    int sock = CreateUDPSocket();
    ioctl(sock, SIOCGIFCONF, &conf);
    int maxnum  = conf.ifc_len / sizeof(struct ifreq);
    struct ifreq* ifr = conf.ifc_req;

    int cnt = 0;
    for(int i=0; cnt < num && i < maxnum;i++)
    {
        if (NULL == ifr)
            break;

        ioctl(sock, SIOCGIFFLAGS, ifr);

        if(((ifr->ifr_flags & IFF_LOOPBACK) == 0) && (ifr->ifr_flags & IFF_UP))
        {
            struct sockaddr_in *pAddr = (struct sockaddr_in *)(&ifr->ifr_addr);
            addrs[cnt ++] = pAddr->sin_addr.s_addr;
        }
        ++ ifr;
    }

    for ( ; cnt < num; ++ cnt)
    {
        addrs[cnt] = 0;
    }

    close(sock);
}




================================================
FILE: QBase/Socket.h
================================================

#ifndef BERT_SOCKET_H
#define BERT_SOCKET_H

#include <arpa/inet.h>
#include <string.h>
#include <string>
#include <memory>
#include <atomic>
#include <functional>

#define INVALID_SOCKET (int)(~0)
#define SOCKET_ERROR (-1)
#define INVALID_PORT (-1)


struct SocketAddr
{
    SocketAddr()
    {
        Clear();
    }
    
    SocketAddr(const SocketAddr& other)
    {
        memcpy(&addr_, &other.addr_, sizeof addr_);
    }

    SocketAddr& operator= (const SocketAddr&  other)
    {
        if (this != &other)
            memcpy(&addr_, &other.addr_, sizeof addr_);

        return *this;
    }

    SocketAddr(const sockaddr_in& addr)
    {
        Init(addr);
    }

    // ip port format:  127.0.0.1:6379
    SocketAddr(const std::string& ipport)
    {
        std::string::size_type p = ipport.find_first_of(':');
        std::string ip = ipport.substr(0, p);
        std::string port = ipport.substr(p + 1);

        Init(ip.c_str(), static_cast<uint16_t>(std::stoi(port)));
    }

    SocketAddr(uint32_t  netip, uint16_t netport)
    {
        Init(netip, netport);
    }

    SocketAddr(const char* ip, uint16_t hostport)
    {
        Init(ip, hostport);
    }

    void Init(const sockaddr_in& addr)
    {
        memcpy(&addr_, &addr, sizeof(addr));
    }

    void Init(uint32_t netip, uint16_t netport)
    {
        addr_.sin_family = AF_INET;       
        addr_.sin_addr.s_addr = netip;       
        addr_.sin_port = netport;
    }

    void Init(const char* ip, uint16_t hostport)
    {
        addr_.sin_family = AF_INET;
        addr_.sin_addr.s_addr = ::inet_addr(ip);
        addr_.sin_port = htons(hostport);
    }

    const sockaddr_in& GetAddr() const
    {
        return addr_;
    }

    const char* GetIP() const
    {
        return ::inet_ntoa(addr_.sin_addr);
    }
    
    const char* GetIP(char* buf, socklen_t size) const
    {
        return ::inet_ntop(AF_INET, (const char*)&addr_.sin_addr, buf, size);
    }

    unsigned short GetPort() const
    {
        return ntohs(addr_.sin_port);
    }
    
    std::string ToString() const
    {
        char tmp[32];
        const char* res = inet_ntop(AF_INET,
                                    &addr_.sin_addr,
                                    tmp,
                                    (socklen_t)(sizeof tmp));

        return std::string(res) + ":" + std::to_string(ntohs(addr_.sin_port));
    }

    bool  Empty() const { return  0 == addr_.sin_family; }
    void  Clear()       { memset(&addr_, 0, sizeof addr_); }
    
    inline friend bool operator== (const SocketAddr& a, const SocketAddr& b)
    {
        return a.addr_.sin_family      ==  b.addr_.sin_family &&
               a.addr_.sin_addr.s_addr ==  b.addr_.sin_addr.s_addr &&
               a.addr_.sin_port        ==  b.addr_.sin_port ;
    }
    
    inline friend bool operator!= (const SocketAddr& a, const SocketAddr& b)
    {
        return !(a == b);
    }

    sockaddr_in addr_;
};

// custom specialization of std::hash can be injected into std
namespace std
{ 
    template<>
    struct hash<SocketAddr> 
    { 
        typedef SocketAddr argument_type; 
        typedef std::size_t result_type; 
        result_type operator()(const argument_type& s) const noexcept 
        {
            result_type h1 = std::hash<short>{}(s.addr_.sin_family); 
            result_type h2 = std::hash<unsigned short>{}(s.addr_.sin_port); 
            result_type h3 = std::hash<unsigned int>{}(s.addr_.sin_addr.s_addr);
            result_type tmp = h1 ^ (h2 << 1);
            return h3 ^ (tmp << 1);
        }
    }; 
}


namespace Internal
{
class SendThread;
}

// Abstraction for a TCP socket
class Socket : public std::enable_shared_from_this<Socket>
{
    friend class Internal::SendThread;

public:
    virtual ~Socket();
    
    Socket(const Socket& ) = delete;
    void operator= (const Socket& ) = delete;

    enum SocketType
    {
        SocketType_Invalid= -1,
        SocketType_Listen,
        SocketType_Client,
        SocketType_Stream,
    };

    virtual SocketType GetSocketType() const { return SocketType_Invalid; }
    bool Invalid() const { return invalid_; }
    
    int  GetSocket() const { return localSock_; }
    std::size_t GetID() const { return id_; }

    virtual bool OnReadable() { return false; }
    virtual bool OnWritable() { return false; }
    virtual bool OnError();
    virtual void OnConnect()  { }
    virtual void OnDisconnect()  { }

    static int CreateTCPSocket();
    static int CreateUDPSocket();
    static void CloseSocket(int &sock);
    static void SetNonBlock(int sock, bool nonBlock = true);
    static void SetNodelay(int sock);
    static void SetSndBuf(int sock, socklen_t size = 128 * 1024);
    static void SetRcvBuf(int sock, socklen_t size = 128 * 1024);
    static void SetReuseAddr(int sock);
    static bool GetLocalAddr(int sock, SocketAddr& );
    static bool GetPeerAddr(int sock,  SocketAddr& );
    static void GetMyAddrInfo(unsigned int* addrs, int num);

protected:
    Socket();

    // The local socket
    int localSock_;
    bool epollOut_;

private:
    std::atomic<bool> invalid_;
    std::size_t id_;
    static std::atomic<std::size_t> sid_;
};


#endif



================================================
FILE: QBase/StreamSocket.cc
================================================
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/tcp.h>

#include "StreamSocket.h"
#include "Server.h"
#include "NetThreadPool.h"
#include "Log/Logger.h"

using std::size_t;

StreamSocket::StreamSocket()
{
}

StreamSocket::~StreamSocket()
{
    INF << __FUNCTION__ << " peer ("
        << peerAddr_.ToString()
        << ")";
}

bool StreamSocket::Init(int fd, const SocketAddr& peer)
{
    if (fd < 0)
        return false;

    peerAddr_ = peer;
    localSock_ = fd;
    SetNonBlock(localSock_);

    INF << __FUNCTION__ << " peer address ("
        << peerAddr_.ToString()
        << "), local socket is " << fd;
    
#if defined(__APPLE__)
    int set = 1;
    setsockopt(localSock_, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
#endif

    return  true;
}

int StreamSocket::Recv()
{
    if (recvBuf_.Capacity() == 0)
    {
        recvBuf_.InitCapacity(64 * 1024); // First recv data, allocate buffer
    }
    
    BufferSequence  buffers;
    recvBuf_.GetSpace(buffers);
    if (buffers.count == 0)
    {
        WRN << "Recv buffer is full";
        return 0;
    }

    int ret = static_cast<int>(::readv(localSock_, buffers.buffers, static_cast<int>(buffers.count)));
    if (ret == ERRORSOCKET && (EAGAIN == errno || EWOULDBLOCK == errno))
        return 0;

    if (ret > 0)
        recvBuf_.AdjustWritePtr(ret);

    return (0 == ret) ? EOFSOCKET : ret;
}


int StreamSocket::_Send(const BufferSequence& bf)
{
    auto  total = bf.TotalBytes();
    if (total == 0)
        return 0;

    int ret = static_cast<int>(::writev(localSock_, bf.buffers, static_cast<int>(bf.count)));
    if (ERRORSOCKET == ret && (EAGAIN == errno || EWOULDBLOCK == errno))
    {
        epollOut_ = true;
        ret = 0;
    }
    else if (ret > 0 && static_cast<size_t>(ret) < total)
    {
        epollOut_ = true;
    }
    else if (static_cast<size_t>(ret) == total)
    {
        epollOut_ = false;
    }

    return ret;
}


bool StreamSocket::SendPacket(const void* data, size_t bytes)
{
    if (data && bytes > 0)
        sendBuf_.Write(data, bytes);

    return true;
}

bool StreamSocket::SendPacket(Buffer& bf)
{
    return SendPacket(bf.ReadAddr(), bf.ReadableSize());
}


bool StreamSocket::SendPacket(AttachedBuffer& af)
{
    return SendPacket(af.ReadAddr(), af.ReadableSize());
}

bool StreamSocket::SendPacket(qedis::UnboundedBuffer& ubf)
{
    return SendPacket(ubf.ReadAddr(), ubf.ReadableSize());
}

bool StreamSocket::OnReadable()
{
    int nBytes = StreamSocket::Recv();
    if (nBytes < 0)
    {
        INF << __FUNCTION__ << " failed, peer address ("
            << peerAddr_.ToString()
            << "), local socket is "
            << localSock_;
        
        Internal::NetThreadPool::Instance().DisableRead(shared_from_this());
        return false;
    }

    return true;
}

bool StreamSocket::Send()
{
    if (epollOut_)
        return true;

    BufferSequence  bf;
    sendBuf_.ProcessBuffer(bf);
    
    size_t  total = bf.TotalBytes();
    if (total == 0)  return true;
    
    int  nSent = _Send(bf);
    
    if (nSent > 0)
    {
        sendBuf_.Skip(nSent);
    }
        
    if (epollOut_)
    {
        Internal::NetThreadPool::Instance().EnableWrite(shared_from_this());
        INF << __FUNCTION__ << " peer address ("
            << peerAddr_.ToString()
            << "), local socket is "
            << localSock_
            << ", register write event";
    }
    
    return  nSent >= 0;
}

// drive by EPOLLOUT
bool StreamSocket::OnWritable()
{
    BufferSequence  bf;
    sendBuf_.ProcessBuffer(bf);
    
    size_t  total = bf.TotalBytes();
    int     nSent = 0;
    if (total > 0)
    {
        nSent = _Send(bf);
        if (nSent > 0)
            sendBuf_.Skip(nSent);
    }
    else
    {
        epollOut_ = false;
    }

    if (!epollOut_)
    {
        INF << __FUNCTION__ << " peer address ("
            << peerAddr_.ToString()
            << "), local socket is "
            << localSock_
            << ", unregister write event";
        Internal::NetThreadPool::Instance().DisableWrite(shared_from_this());
    }

    return  nSent >= 0;
}

bool StreamSocket::OnError()
{
    if (Socket::OnError())
    {
        ERR << __FUNCTION__ << " peer address ("
            << peerAddr_.ToString()
            << "), local socket is "
            << localSock_;

        if (onDisconnect_)
            onDisconnect_();

        return true;
    }
        
    return false;
}

bool StreamSocket::DoMsgParse()
{
    bool busy = false;
    while (!recvBuf_.IsEmpty())
    {
        BufferSequence  datum;
        recvBuf_.GetDatum(datum, recvBuf_.ReadableSize());

        AttachedBuffer af(datum);
        auto  bodyLen = _HandlePacket(af.ReadAddr(), af.ReadableSize());
        if (bodyLen > 0)
        {
            busy = true;
            recvBuf_.AdjustReadPtr(bodyLen);
        }
        else
        {
            break;
        }
    }

    return  busy;
}



================================================
FILE: QBase/StreamSocket.h
================================================

#ifndef BERT_STREAMSOCKET_H
#define BERT_STREAMSOCKET_H

#include "AsyncBuffer.h"
#include "Socket.h"
#include <sys/types.h>
#include <sys/socket.h>

using PacketLength = int32_t;

// Abstraction for a TCP connection
class StreamSocket : public Socket
{
    friend class SendThread;
public:
    StreamSocket();
   ~StreamSocket();

    bool       Init(int localfd, const SocketAddr& peer);
    SocketType GetSocketType() const { return SocketType_Stream; }

public:
    // Receive data
    int    Recv();
public:
    // Send data
    bool   SendPacket(const void* , std::size_t );
    bool   SendPacket(Buffer&  bf);
    bool   SendPacket(AttachedBuffer& abf);
    bool   SendPacket(qedis::UnboundedBuffer& ubf);
    template <int N>
    bool   SendPacket(StackBuffer<N>&  sb);

    bool   OnReadable();
    bool   OnWritable();
    bool   OnError();

    bool  DoMsgParse(); // false if no msg

    void  SetOnDisconnect(const std::function<void ()>& cb = std::function<void ()>()) { onDisconnect_ = cb; }
    
    // send thread
    bool  Send();
    
    const SocketAddr& GetPeerAddr() const { return peerAddr_; }

protected:
    SocketAddr  peerAddr_;

private:
    std::function<void ()> onDisconnect_;

    int    _Send(const BufferSequence& bf);
    virtual PacketLength _HandlePacket(const char* msg, std::size_t len) = 0;

    // For human readability
    enum
    {
        TIMEOUTSOCKET =  0,
        ERRORSOCKET   = -1,
        EOFSOCKET     = -2,
    };

    Buffer recvBuf_;
    AsyncBuffer sendBuf_;
};

template <int N>
inline bool  StreamSocket::SendPacket(StackBuffer<N>& sf)
{
    return  SendPacket(sf.ReadAddr(), sf.ReadableSize());
}

#endif



================================================
FILE: QBase/TaskManager.cc
================================================
#include <cassert>
#include "TaskManager.h"
#include "StreamSocket.h"
#include "Log/Logger.h"

namespace Internal
{

TaskManager::~TaskManager()
{
    assert(Empty() && "Why you do not clear container before exit?");
}
    
     
bool TaskManager::AddTask(PTCPSOCKET task)
{   
    std::lock_guard<std::mutex> guard(lock_);
    newTasks_.push_back(task);
    ++ newCnt_;

    return true;
}

TaskManager::PTCPSOCKET TaskManager::FindTCP(unsigned int id) const
{
    if (id > 0)
    {
        auto it = tcpSockets_.find(id);
        if (it != tcpSockets_.end())
            return it->second;
    }
           
    return PTCPSOCKET();
}

bool TaskManager::_AddTask(PTCPSOCKET task)
{   
    //bool succ = tcpSockets_.insert(std::map<int, PTCPSOCKET>::value_type(task->GetID(), task)).second;
    bool succ = tcpSockets_.insert({task->GetID(), task}).second;
    return succ;    
}


void TaskManager::_RemoveTask(std::map<int, PTCPSOCKET>::iterator& it)    
{
    tcpSockets_.erase(it ++);
}


bool TaskManager::DoMsgParse()
{
    if (newCnt_ > 0 && lock_.try_lock())
    {
        NEWTASKS_T tmpNewTask;
        tmpNewTask.swap(newTasks_);
        newCnt_ = 0;
        lock_.unlock();

        for (const auto& task : tmpNewTask)
        {
            if (!_AddTask(task))
            {
                ERR << "Why can not insert tcp socket "
                    << task->GetSocket()
                    << ", id = "
                    << task->GetID();
            }
            else
            {
                INF << "New connection from "
                    << task->GetPeerAddr().ToString()
                    << ", id = "
                    << task->GetID();

                task->OnConnect();
            }
        }
    }

    bool busy = false;

    for (auto it(tcpSockets_.begin()); it != tcpSockets_.end(); )
    {
        if (!it->second || it->second->Invalid())
        {
            if (it->second)
            {
                INF << "Close connection from "
                    << it->second->GetPeerAddr().ToString()
                    << ", id = "
                    << it->second->GetID();

                it->second->OnDisconnect();
            }
            _RemoveTask(it);
        }
        else
        {
            if (it->second->DoMsgParse() && !busy)
                busy = true;

            ++ it;
        }
    }

    return busy;
}

}



================================================
FILE: QBase/TaskManager.h
================================================
#ifndef BERT_TASKMANAGER_H
#define BERT_TASKMANAGER_H

#include <vector>
#include <map>
#include <mutex>
#include <memory>
#include <atomic>

class StreamSocket;

namespace Internal
{

class TaskManager 
{
    typedef std::shared_ptr<StreamSocket>     PTCPSOCKET;
    typedef std::vector<PTCPSOCKET>     NEWTASKS_T;

public:
    TaskManager() : newCnt_(0) { }
    ~TaskManager();
    
    bool AddTask(PTCPSOCKET );

    bool Empty() const { return tcpSockets_.empty(); }
    void Clear()  { tcpSockets_.clear(); }
    PTCPSOCKET  FindTCP(unsigned int id) const;
    
    size_t TCPSize() const  {  return  tcpSockets_.size(); }

    bool DoMsgParse();

private:
    bool _AddTask(PTCPSOCKET task);
    void _RemoveTask(std::map<int, PTCPSOCKET>::iterator& );
    std::map<int, PTCPSOCKET>  tcpSockets_;

    // Lock for new tasks
    std::mutex      lock_;
    NEWTASKS_T      newTasks_; 
    std::atomic<int> newCnt_; // vector::empty() is not thread-safe !!!
};

}

#endif



================================================
FILE: QBase/Threads/ThreadPool.cc
================================================
#include "ThreadPool.h"

__thread bool ThreadPool::working_ = true;

ThreadPool::ThreadPool() : waiters_(0), shutdown_(false)
{
    monitor_ = std::thread([this]() { this->_MonitorRoutine(); } );
    maxIdleThread_ = std::max(1U, std::thread::hardware_concurrency());
    pendingStopSignal_ = 0;
}

ThreadPool::~ThreadPool()
{
    JoinAll();
}

ThreadPool& ThreadPool::Instance()
{
    static ThreadPool  pool;
    return pool;
}

void    ThreadPool::SetMaxIdleThread(unsigned int m)
{
    if (0 < m && m <= kMaxThreads)
        maxIdleThread_ = m;
}

void    ThreadPool::JoinAll()
{
    decltype(workers_)  tmp;
    
    {
        std::unique_lock<std::mutex>  guard(mutex_);
        if (shutdown_)
            return;
        
        shutdown_ = true;
        cond_.notify_all();
        
        tmp.swap(workers_);
        workers_.clear();
    }
    
    for (auto& t : tmp)
    {
        if (t.joinable())
            t.join();
    }
    
    if (monitor_.joinable())
        monitor_.join();
}

void   ThreadPool::_CreateWorker()
{
    std::thread  t([this]() { this->_WorkerRoutine(); } );
    workers_.push_back(std::move(t));
}

void   ThreadPool::_WorkerRoutine()
{
    working_ = true;
    
    while (working_)
    {
        std::function<void ()>   task;
        
        {
            std::unique_lock<std::mutex>    guard(mutex_);
            
            ++ waiters_;
            cond_.wait(guard, [this]()->bool { return this->shutdown_ || !tasks_.empty(); } );
            -- waiters_;
            
            if (this->shutdown_ && tasks_.empty())
                return;
            
            task = std::move(tasks_.front());
            tasks_.pop_front();
        }
        
        task();
    }
    
    // if reach here, this thread is recycled by monitor thread
    -- pendingStopSignal_;
}

void   ThreadPool::_MonitorRoutine()
{
    while (!shutdown_)
    {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        
        std::unique_lock<std::mutex>   guard(mutex_);
        if (shutdown_)
            return;
        
        auto nw = waiters_;

        // if there is any pending stop signal to consume waiters
        nw -= pendingStopSignal_;

        while (nw -- > maxIdleThread_)
        {
            tasks_.push_back([this]() { working_ = false; });
            cond_.notify_one();
            ++ pendingStopSignal_;
        }
    }
}


================================================
FILE: QBase/Threads/ThreadPool.h
================================================
#ifndef BERT_THREADPOOL_H
#define BERT_THREADPOOL_H

#include <deque>
#include <functional>
#include <thread>
#include <memory>
#include <future>
#include <atomic>
#include <mutex>
#include <condition_variable>


class ThreadPool final
{
public:
    ~ThreadPool();
    
    ThreadPool(const ThreadPool& ) = delete;
    void operator=(const ThreadPool& ) = delete;
    
    static ThreadPool& Instance();
    
    template <typename F, typename... Args>
    auto    ExecuteTask(F&& f, Args&&... args) -> std::future<typename std::result_of<F (Args...)>::type>;
    
    void    JoinAll();
    void    SetMaxIdleThread(unsigned int m);
    
private:
    ThreadPool();
    
    void   _CreateWorker();
    void   _WorkerRoutine();
    void   _MonitorRoutine();
    
    std::thread      monitor_;
    std::atomic<unsigned> maxIdleThread_;
    std::atomic<unsigned> pendingStopSignal_;
    
    static __thread   bool      working_;
    std::deque<std::thread>     workers_;
    
    std::mutex                  mutex_;
    std::condition_variable     cond_;
    unsigned                    waiters_;
    bool                        shutdown_;
    std::deque<std::function<void ()> > tasks_;
    
    static const int  kMaxThreads = 256;
};


template <typename F, typename... Args>
auto ThreadPool::ExecuteTask(F&& f, Args&&... args) -> std::future<typename std::result_of<F (Args...)>::type>
{
    using  resultType = typename std::result_of<F (Args...)>::type;
    
    auto task = std::make_shared<std::packaged_task<resultType ()> >(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
    
    {
        std::unique_lock<std::mutex>     guard(mutex_);
        if (shutdown_)
        {
            return std::future<resultType>();
        }
        
        tasks_.emplace_back( [=]() { (*task)(); } );
        if (waiters_ == 0)
        {
            _CreateWorker();
        }
        
        cond_.notify_one();
    }
    
    return task->get_future();
}

#endif



================================================
FILE: QBase/Timer.cc
================================================
#include <cstdlib>
#include <cstdio>
#include <cassert>
#include <cstring>
#include "Timer.h"

uint64_t Now()
{
    struct timeval now;
    ::gettimeofday(&now, 0);
    return  uint64_t(now.tv_sec * 1000UL + now.tv_usec / 1000UL);
}

static bool  IsLeapYear(int year)
{
    return  (year % 400 == 0 ||
            (year % 4 == 0 && year % 100 != 0));
}

static int DaysOfMonth(int year, int month)
{
    const int monthDay[13] = {-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    if (2 == month && IsLeapYear(year))
        return 29;

    return  monthDay[month];
}



Time::Time() : ms_(0), valid_(false)
{
    tm_.tm_year = 0;
    this->Now();
}

Time::Time(const Time& other) : ms_(other.ms_)
{
    tm_.tm_year = 0;
    valid_ = false;
}


Time::Time(int hour, int min, int sec)
{
    this->Now();

    //如果hour小于当前的hour,则换天了,如果当前天数是本月最后一天,则换月;如果本月是12月,则换年
    int day   = GetDay();
    int mon   = GetMonth();
    int year  = GetYear();

    bool  tomorrow = false;
    if (hour < GetHour() ||
       (hour == GetHour() && min < GetMinute()) ||
       (hour == GetHour() && min == GetMinute() && sec < GetSecond()))
        tomorrow = true;

    if (tomorrow)
    {
        if (DaysOfMonth(year, mon) == day)
        {
            day = 1;

            if (12 == mon)
            {
                mon = 1;
                ++ year;
            }
            else
                ++ mon;
        }
        else
        {
            ++ day;
        }
    }

    // 构造tm
    struct tm  stm;
    stm.tm_sec = sec;
    stm.tm_min = min;
    stm.tm_hour= hour;
    stm.tm_mday= day;
    stm.tm_mon = mon - 1;
    stm.tm_year = year - 1900;
    stm.tm_yday = 0;
    stm.tm_isdst = 0;

    time_t tt = mktime(&stm);
    ms_ = tt * 1000UL;
    valid_ = false;
}

void Time::_UpdateTm()  const
{
    if (valid_)  
        return;

    valid_ = true; 
    const time_t now(ms_ / 1000UL); 
    ::localtime_r(&now, &tm_);
}

void Time::Now()
{
    ms_ = ::Now();
    valid_ = false;
}

// from 2015 to 2025
static const char* YEAR[] = { "2015", "2016", "2017", "2018",
    "2019", "2020", "2021", "2022", "2023", "2024", "2025",
     nullptr,
};

std::size_t Time::FormatTime(char* buf) const
{
    static char NUMBER[60][2] = {""};

    static bool bFirst = true;
    if (bFirst)
    {
        bFirst = false;
        for (size_t i = 0; i < sizeof NUMBER / sizeof NUMBER[0]; ++ i)
        {
            char tmp[3]; 
            snprintf(tmp, 3, "%02d", static_cast<int>(i));
            memcpy(NUMBER[i], tmp, 2);
        }
    }

    _UpdateTm();
    
#if  1
    memcpy(buf, YEAR[tm_.tm_year + 1900 - 2015], 4);
    buf[4] = '-';
    memcpy(buf + 5, NUMBER[tm_.tm_mon + 1], 2);
    buf[7] = '-';
    memcpy(buf + 8, NUMBER[tm_.tm_mday], 2);
    buf[10] = '[';
    memcpy(buf + 11, NUMBER[tm_.tm_hour], 2);
    buf[13] = ':';
    memcpy(buf + 14, NUMBER[tm_.tm_min], 2);
    buf[16] = ':';
    memcpy(buf + 17, NUMBER[tm_.tm_sec], 2);
    buf[19] = '.';
    snprintf(buf + 20, 5, "%03d]", static_cast<int>(ms_ % 1000));
#else
    
    snprintf(buf, 25, "%04d-%02d-%02d[%02d:%02d:%02d.%03d]",
             tm_.tm_year+1900, tm_.tm_mon+1, tm_.tm_mday,
             tm_.tm_hour, tm_.tm_min, tm_.tm_sec,
             static_cast<int>(ms_ % 1000));
#endif
    
    return 24;
}

void Time::AddDelay(uint64_t delay)
{
    ms_   += delay;
    valid_ = false;
}

Time& Time::operator= (const Time & other)
{
    if (this != &other)
    {
        ms_    = other.ms_;
        valid_ = false;
    }
    return *this;
}




Timer::Timer(): next_(nullptr), prev_(nullptr)
{
}

void  Timer::Init(uint32_t interval, int32_t count)
{
    interval_ = interval;
    count_ = count;
    triggerTime_.Now();
    triggerTime_.AddDelay(interval);
}


bool Timer::OnTimer()
{
    if (!func_)
        return false;

    if (count_ < 0 || -- count_ >= 0)
    {
        triggerTime_.AddDelay(interval_);
        func_();

        return true;
    }

    return false;        
}

TimerManager::TimerManager() : count_(0)
{
    for (int i = 0; i < LIST1_SIZE; ++ i)
    {
        m_list1[i] = new Timer();
    }

    for (int i = 0; i < LIST_SIZE; ++ i)
    {
        m_list2[i] = new Timer();
        m_list3[i] = new Timer();
        m_list4[i] = new Timer();
        m_list5[i] = new Timer();
    }
}

TimerManager::~TimerManager()
{
    Timer* pTimer = nullptr;
    for (int i = 0; i < LIST1_SIZE; ++ i)
    {
        while ((pTimer = m_list1[i]->next_) )
        {
            KillTimer(pTimer);
            delete pTimer;
        }
    
        delete m_list1[i];
    }

    for (int i = 0; i < LIST_SIZE; ++ i)
    {
        while ((pTimer = m_list2[i]->next_) )
        {
            KillTimer(pTimer);
            delete pTimer;
        }
        delete m_list2[i];

        while ((pTimer = m_list3[i]->next_) )
        {
            KillTimer(pTimer);
            delete pTimer;
        }
        delete m_list3[i];

        while ((pTimer = m_list4[i]->next_) )
        {
            KillTimer(pTimer);
            delete pTimer;
        }
        delete m_list4[i];

        while ((pTimer = m_list5[i]->next_) )
        {
            KillTimer(pTimer);
            delete pTimer;
        }
        delete m_list5[i];
    }
    
    for (auto t : freepool_)
        delete t;
}

TimerManager&  TimerManager::Instance()
{
    static TimerManager mgr;
    return  mgr;
}

Timer* TimerManager::CreateTimer()
{
    Timer* timer = nullptr;
    if (freepool_.empty())
    {
        timer = new Timer();
    }
    else
    {
        timer = *(freepool_.begin());
        freepool_.erase(freepool_.begin());
    }

    return timer;
}

bool TimerManager::UpdateTimers(const Time& now)
{
    if (count_ > 0 && lock_.try_lock())
    {
        decltype(timers_) tmp;
        tmp.swap(timers_);
        count_ = 0;
        lock_.unlock();

        for (auto timer : tmp)
        {
            AddTimer(timer);
        }
    }

    const bool hasUpdated(m_lastCheckTime <= now);

    while (m_lastCheckTime <= now)
    {
        int index = m_lastCheckTime & (LIST1_SIZE - 1);
        if (index == 0 &&
            !_Cacsade(m_list2, _Index(0)) &&
            !_Cacsade(m_list3, _Index(1)) &&
            !_Cacsade(m_list4, _Index(2)))
        {
            _Cacsade(m_list5, _Index(3));
        }

        m_lastCheckTime.AddDelay(1);

        Timer* timer;
        while ((timer = m_list1[index]->next_))
        {
            KillTimer(timer);
            if (timer->OnTimer())
                AddTimer(timer);
            else
                freepool_.insert(timer);
        }
    }        

    return hasUpdated;
}


void TimerManager::AddTimer(Timer* timer)
{
    uint32_t diff      =  static_cast<uint32_t>(timer->triggerTime_ - m_lastCheckTime);
    uint64_t trigTime  =  timer->triggerTime_.MilliSeconds();
    Timer* pListHead   = nullptr;
    
    if ((int32_t)diff < 0)
    {
        pListHead = m_list1[m_lastCheckTime.MilliSeconds() & (LIST1_SIZE - 1)];
    }
    else if (diff < static_cast<uint32_t>(LIST1_SIZE))
    {
        pListHead = m_list1[trigTime & (LIST1_SIZE - 1)];
    }
    else if (diff < 1 << (LIST1_BITS + LIST_BITS))
    {
        pListHead = m_list2[(trigTime >> LIST1_BITS) & (LIST_SIZE - 1)];
    }
    else if (diff < 1 << (LIST1_BITS + 2 * LIST_BITS))
    {
        pListHead = m_list3[(trigTime >> (LIST1_BITS + LIST_BITS)) & (LIST_SIZE - 1)];
    }
    else if (diff < 1 << (LIST1_BITS + 3 * LIST_BITS))
    {
        pListHead = m_list4[(trigTime >> (LIST1_BITS + 2 * LIST_BITS)) & (LIST_SIZE - 1)];
    }
    else
    {
        pListHead = m_list5[(trigTime >> (LIST1_BITS + 3 * LIST_BITS)) & (LIST_SIZE - 1)];
    }

    assert(!pListHead->prev_);

    timer->prev_ = pListHead;
    timer->next_ = pListHead->next_;
    if (pListHead->next_)
        pListHead->next_->prev_ = timer;
    pListHead->next_ = timer;
    
    freepool_.erase(timer);
}

void TimerManager::AsyncAddTimer(Timer* timer)
{
    std::lock_guard<std::mutex>  guard(lock_);

    timers_.push_back(timer);
    ++ count_;
    assert (count_ == timers_.size());
}

void TimerManager::ScheduleAt(Timer* timer, const Time& triggerTime)
{
    if (!timer)
        return;

    timer->triggerTime_ = triggerTime;
    AddTimer(timer);
}


void TimerManager::KillTimer(Timer* timer)
{
    if (!timer)
        return;

    if (timer->prev_)
    {
        timer->prev_->next_ = timer->next_;

        if (timer->next_)
        {
            timer->next_->prev_ = timer->prev_;
            timer->next_ = nullptr;
        }

        timer->prev_ = nullptr;
    }
}

bool TimerManager::_Cacsade(Timer* pList[], int index)
{
    assert (pList);

    if (index < 0 ||
        index >= LIST_SIZE)
        return  false;

    assert (pList[index]);

    if (!pList[index]->next_)
        return false;

    Timer* tmpListHead = pList[index]->next_;
    pList[index]->next_ = nullptr;

    while (tmpListHead)
    {
        Timer* next = tmpListHead->next_;

        tmpListHead->next_ = nullptr;
        tmpListHead->prev_ = nullptr;
        
        AddTimer(tmpListHead);
        tmpListHead = next;
    }

    return true;
}



================================================
FILE: QBase/Timer.h
================================================

#ifndef BERT_TIMER_H
#define BERT_TIMER_H

#include <vector>
#include <set>
#include <ctime>
#include <sys/time.h>
#include <stdint.h>
#include <functional>
#include <memory>
#include <mutex>
#include <atomic>

uint64_t Now();

class Time
{
public:
    Time();
    Time(const Time& other);
    Time(int hour, int min, int sec); // TODO year month day, and Effective cpp item 18

    void        Now();
    uint64_t    MilliSeconds() const { return ms_; }
    std::size_t FormatTime(char* buf) const;
    void        AddDelay(uint64_t delay);

    int GetYear()   const { _UpdateTm(); return tm_.tm_year + 1900;  } 
    int GetMonth()  const { _UpdateTm(); return tm_.tm_mon + 1;  } 
    int GetDay()    const { _UpdateTm(); return tm_.tm_mday; }
    int GetHour()   const { _UpdateTm(); return tm_.tm_hour; }
    int GetMinute() const { _UpdateTm(); return tm_.tm_min;  }
    int GetSecond() const { _UpdateTm(); return tm_.tm_sec;  }

    Time&    operator= (const Time& );
    operator uint64_t() const { return ms_; }

private:
    uint64_t    ms_;      // milliseconds from 1970
    mutable tm  tm_;
    mutable bool valid_;
    
    void    _UpdateTm()  const;
};


class Timer
{
    friend class TimerManager;
public:
    void  Init(uint32_t interval, int32_t count = -1);
    bool  OnTimer();
    void  SetRemainCnt(int32_t remain) {  count_ = remain; }
    bool  IsWorking() const {  return  prev_ != nullptr; }

    template <typename F, typename... Args>
    void SetCallback(F&& f, Args&&... args)
    {
        auto temp = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
        func_ = [temp]() { (void)temp(); };
    }

private:
    Timer();

    std::function<void ()> func_;
    Timer* next_;
    Timer* prev_;
    Time     triggerTime_;
    uint32_t interval_;
    int32_t  count_;
};

class TimerManager
{
public:
    ~TimerManager();

    TimerManager(const TimerManager& ) = delete;
    void operator= (const TimerManager& ) = delete;

    static  TimerManager&   Instance();

    bool    UpdateTimers(const Time& now);
    void    ScheduleAt(Timer* pTimer, const Time& triggerTime);
    void    AddTimer(Timer* timer);
    void    AsyncAddTimer(Timer* timer);
    void    KillTimer(Timer* pTimer);

    Timer*  CreateTimer();

private:
    TimerManager();

    bool _Cacsade(Timer* pList[], int index);
    int _Index(int level);

    static const int LIST1_BITS = 8;
    static const int LIST_BITS  = 6;
    static const int LIST1_SIZE = 1 << LIST1_BITS;
    static const int LIST_SIZE  = 1 << LIST_BITS;

    Time  m_lastCheckTime;

    Timer* m_list1[LIST1_SIZE]; // 256 ms
    Timer* m_list2[LIST_SIZE];  // 64 * 256ms = 16s
    Timer* m_list3[LIST_SIZE];  // 64 * 64 * 256ms = 17m
    Timer* m_list4[LIST_SIZE];  // 64 * 64 * 64 * 256ms = 18h
    Timer* m_list5[LIST_SIZE];  // 64 * 64 * 64 * 64 * 256ms = 49 days

    // timer pool
    std::set<Timer* > freepool_;

    // async add
    std::mutex lock_;
    std::atomic<std::size_t> count_;
    std::vector<Timer* > timers_;
};

inline int TimerManager::_Index(int level)
{
    uint64_t current = m_lastCheckTime;
    current >>= (LIST1_BITS + level * LIST_BITS);
    return current & (LIST_SIZE - 1);
}

#endif



================================================
FILE: QBase/UnboundedBuffer.cc
================================================

#include "UnboundedBuffer.h"
#include <iostream>
#include <limits>
#include <cassert>

namespace qedis
{

const std::size_t UnboundedBuffer::MAX_BUFFER_SIZE = std::numeric_limits<std::size_t>::max() / 2;


std::size_t UnboundedBuffer::Write(const void* pData, std::size_t nSize)
{
    return PushData(pData, nSize);
}

std::size_t UnboundedBuffer::PushData(const void* pData, std::size_t nSize)
{
    std::size_t nBytes  = PushDataAt(pData, nSize);
    AdjustWritePtr(nBytes);

    return nBytes;
}

std::size_t UnboundedBuffer::PushDataAt(const void* pData, std::size_t nSize, std::size_t offset)
{
    if (!pData || nSize == 0)
        return 0;

    if (ReadableSize() == UnboundedBuffer::MAX_BUFFER_SIZE)
        return 0;

    _AssureSpace(nSize + offset);

    assert (nSize + offset <= WritableSize());

   	::memcpy(&buffer_[writePos_ + offset], pData, nSize);
    return  nSize;
}

std::size_t UnboundedBuffer::PeekData(void* pBuf, std::size_t nSize)
{
    std::size_t nBytes  = PeekDataAt(pBuf, nSize);
    AdjustReadPtr(nBytes);

    return nBytes;
}

std::size_t UnboundedBuffer::PeekDataAt(void* pBuf, std::size_t nSize, std::size_t offset)
{
    const std::size_t dataSize = ReadableSize();
    if (!pBuf ||
         nSize == 0 ||
         dataSize <= offset)
        return 0;

    if (nSize + offset > dataSize)
        nSize = dataSize - offset;

	::memcpy(pBuf, &buffer_[readPos_ + offset], nSize);

    return nSize;
}


void UnboundedBuffer::_AssureSpace(std::size_t nSize)
{
    if (nSize <= WritableSize())
        return;

    std::size_t maxSize = buffer_.size();

    while (nSize > WritableSize() + readPos_)
    {
        if (maxSize < 64)
            maxSize = 64;
        else if (maxSize <= UnboundedBuffer::MAX_BUFFER_SIZE)
            maxSize += (maxSize / 2);
        else 
            break;

        buffer_.resize(maxSize);
    }
        
    if (readPos_ > 0)
    {
        std::size_t dataSize = ReadableSize();
        std::cout << dataSize << " bytes moved from " << readPos_ << std::endl;
        ::memmove(&buffer_[0], &buffer_[readPos_], dataSize);
        readPos_  = 0;
        writePos_ = dataSize;
    }
}

void UnboundedBuffer::Shrink(bool tight)
{
    assert (buffer_.capacity() == buffer_.size());

    if (buffer_.empty())
    { 
        assert (readPos_ == 0);
        assert (writePos_ == 0);
        return;
    }

    std::size_t oldCap   = buffer_.size();
    std::size_t dataSize = ReadableSize();
    if (!tight && dataSize > oldCap / 2)
        return;

    std::vector<char>  tmp;
    tmp.resize(dataSize);
    memcpy(&tmp[0], &buffer_[readPos_], dataSize);
    tmp.swap(buffer_);

    readPos_  = 0;
    writePos_ = dataSize;

    std::cout << oldCap << " shrink to " << buffer_.size() << std::endl;
}

void UnboundedBuffer::Clear()
{
    readPos_ = writePos_ = 0; 
}


void UnboundedBuffer::Swap(UnboundedBuffer& buf)
{
    buffer_.swap(buf.buffer_);
    std::swap(readPos_, buf.readPos_);
    std::swap(writePos_, buf.writePos_);
}

#if 0
int main()
{
    UnboundedBuffer    buf;
    std::size_t ret = buf.PushData("hello", 5);
    assert (ret == 5);

    char tmp[10];
    ret = buf.PeekData(tmp, sizeof tmp);
    assert(ret == 5);
    assert(tmp[0] == 'h');

    assert(buf.IsEmpty());

    ret = buf.PushData("world", 5);
    assert (ret == 5);
    ret = buf.PushData("abcde", 5);
    assert (ret == 5);
    ret = buf.PeekData(tmp, 5);
    assert(tmp[0] == 'w');

    buf.Clear();
    buf.Shrink();

#if 1
    ret = buf.PeekData(tmp, 5);
    if (ret == 5)
    {
        assert(tmp[0] == 'a');
        assert(tmp[1] == 'b');
    }
#endif
    buf.Shrink();

    return 0;
}

#endif

}


================================================
FILE: QBase/UnboundedBuffer.h
================================================

#ifndef BERT_UNBOUNDEDBUFFER_H
#define BERT_UNBOUNDEDBUFFER_H

#include <cstring>
#include <vector>

namespace qedis
{

class UnboundedBuffer
{
public:
    UnboundedBuffer() :
        readPos_(0),
        writePos_(0)
    {
    }

    std::size_t PushDataAt(const void* pData, std::size_t nSize, std::size_t offset = 0);
    std::size_t PushData(const void* pData, std::size_t nSize);
    std::size_t Write(const void* pData, std::size_t nSize);
    void AdjustWritePtr(std::size_t nBytes) {   writePos_ += nBytes; }

    std::size_t  PeekDataAt(void* pBuf, std::size_t nSize, std::size_t offset = 0);
    std::size_t  PeekData(void* pBuf, std::size_t nSize);
    void AdjustReadPtr(std::size_t nBytes) {   readPos_  += nBytes; }

    char* ReadAddr()  {  return &buffer_[readPos_];  }
    char* WriteAddr() {  return &buffer_[writePos_]; }

    bool IsEmpty() const { return ReadableSize() == 0; }
    std::size_t ReadableSize() const {  return writePos_ - readPos_;  }
    std::size_t WritableSize() const {  return buffer_.size() - writePos_;  }

    void Shrink(bool tight = false);
    void Clear();
    void Swap(UnboundedBuffer& buf);

    static const std::size_t  MAX_BUFFER_SIZE;
private:
    void     _AssureSpace(std::size_t size);
    std::size_t readPos_;
    std::size_t writePos_;
    std::vector<char>  buffer_;
};

}

#endif



================================================
FILE: QBase/lzf/lzf.h
================================================
/*
 * Copyright (c) 2000-2008 Marc Alexander Lehmann <schmorp@schmorp.de>
 * 
 * Redistribution and use in source and binary forms, with or without modifica-
 * tion, are permitted provided that the following conditions are met:
 * 
 *   1.  Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 * 
 *   2.  Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
 * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
 * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
 * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Alternatively, the contents of this file may be used under the terms of
 * the GNU General Public License ("GPL") version 2 or any later version,
 * in which case the provisions of the GPL are applicable instead of
 * the above. If you wish to allow the use of your version of this file
 * only under the terms of the GPL and not to allow others to use your
 * version of this file under the BSD license, indicate your decision
 * by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL. If you do not delete the
 * provisions above, a recipient may use your version of this file under
 * either the BSD or the GPL.
 */

#ifndef LZF_H
#define LZF_H

/***********************************************************************
**
**	lzf -- an extremely fast/free compression/decompression-method
**	http://liblzf.plan9.de/
**
**	This algorithm is believed to be patent-free.
**
***********************************************************************/

#define LZF_VERSION 0x0105 /* 1.5, API version */

/*
 * Compress in_len bytes stored at the memory block starting at
 * in_data and write the result to out_data, up to a maximum length
 * of out_len bytes.
 *
 * If the output buffer is not large enough or any error occurs return 0,
 * otherwise return the number of bytes used, which might be considerably
 * more than in_len (but less than 104% of the original size), so it
 * makes sense to always use out_len == in_len - 1), to ensure _some_
 * compression, and store the data uncompressed otherwise (with a flag, of
 * course.
 *
 * lzf_compress might use different algorithms on different systems and
 * even different runs, thus might result in different compressed strings
 * depending on the phase of the moon or similar factors. However, all
 * these strings are architecture-independent and will result in the
 * original data when decompressed using lzf_decompress.
 *
 * The buffers must not be overlapping.
 *
 * If the option LZF_STATE_ARG is enabled, an extra argument must be
 * supplied which is not reflected in this header file. Refer to lzfP.h
 * and lzf_c.c.
 *
 */
unsigned int 
lzf_compress (const void *const in_data,  unsigned int in_len,
              void             *out_data, unsigned int out_len);

/*
 * Decompress data compressed with some version of the lzf_compress
 * function and stored at location in_data and length in_len. The result
 * will be stored at out_data up to a maximum of out_len characters.
 *
 * If the output buffer is not large enough to hold the decompressed
 * data, a 0 is returned and errno is set to E2BIG. Otherwise the number
 * of decompressed bytes (i.e. the original length of the data) is
 * returned.
 *
 * If an error in the compressed data is detected, a zero is returned and
 * errno is set to EINVAL.
 *
 * This function is very fast, about as fast as a copying loop.
 */
unsigned int 
lzf_decompress (const void *const in_data,  unsigned int in_len,
                void             *out_data, unsigned int out_len);

#endif



================================================
FILE: QBase/lzf/lzfP.h
================================================
/*
 * Copyright (c) 2000-2007 Marc Alexander Lehmann <schmorp@schmorp.de>
 * 
 * Redistribution and use in source and binary forms, with or without modifica-
 * tion, are permitted provided that the following conditions are met:
 * 
 *   1.  Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 * 
 *   2.  Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
 * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
 * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
 * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Alternatively, the contents of this file may be used under the terms of
 * the GNU General Public License ("GPL") version 2 or any later version,
 * in which case the provisions of the GPL are applicable instead of
 * the above. If you wish to allow the use of your version of this file
 * only under the terms of the GPL and not to allow others to use your
 * version of this file under the BSD license, indicate your decision
 * by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL. If you do not delete the
 * provisions above, a recipient may use your version of this file under
 * either the BSD or the GPL.
 */

#ifndef LZFP_h
#define LZFP_h

#define STANDALONE 1 /* at the moment, this is ok. */

#ifndef STANDALONE
# include "lzf.h"
#endif

/*
 * Size of hashtable is (1 << HLOG) * sizeof (char *)
 * decompression is independent of the hash table size
 * the difference between 15 and 14 is very small
 * for small blocks (and 14 is usually a bit faster).
 * For a low-memory/faster configuration, use HLOG == 13;
 * For best compression, use 15 or 16 (or more, up to 23).
 */
#ifndef HLOG
# define HLOG 16
#endif

/*
 * Sacrifice very little compression quality in favour of compression speed.
 * This gives almost the same compression as the default code, and is
 * (very roughly) 15% faster. This is the preferred mode of operation.
 */
#ifndef VERY_FAST
# define VERY_FAST 1
#endif

/*
 * Sacrifice some more compression quality in favour of compression speed.
 * (roughly 1-2% worse compression for large blocks and
 * 9-10% for small, redundant, blocks and >>20% better speed in both cases)
 * In short: when in need for speed, enable this for binary data,
 * possibly disable this for text data.
 */
#ifndef ULTRA_FAST
# define ULTRA_FAST 0
#endif

/*
 * Unconditionally aligning does not cost very much, so do it if unsure
 */
#ifndef STRICT_ALIGN
# define STRICT_ALIGN !(defined(__i386) || defined (__amd64))
#endif

/*
 * You may choose to pre-set the hash table (might be faster on some
 * modern cpus and large (>>64k) blocks, and also makes compression
 * deterministic/repeatable when the configuration otherwise is the same).
 */
#ifndef INIT_HTAB
# define INIT_HTAB 0
#endif

/*
 * Avoid assigning values to errno variable? for some embedding purposes
 * (linux kernel for example), this is necessary. NOTE: this breaks
 * the documentation in lzf.h.
 */
#ifndef AVOID_ERRNO
# define AVOID_ERRNO 0
#endif

/*
 * Whether to pass the LZF_STATE variable as argument, or allocate it
 * on the stack. For small-stack environments, define this to 1.
 * NOTE: this breaks the prototype in lzf.h.
 */
#ifndef LZF_STATE_ARG
# define LZF_STATE_ARG 0
#endif

/*
 * Whether to add extra checks for input validity in lzf_decompress
 * and return EINVAL if the input stream has been corrupted. This
 * only shields against overflowing the input buffer and will not
 * detect most corrupted streams.
 * This check is not normally noticeable on modern hardware
 * (<1% slowdown), but might slow down older cpus considerably.
 */
#ifndef CHECK_INPUT
# define CHECK_INPUT 1
#endif

/*****************************************************************************/
/* nothing should be changed below */

typedef unsigned char u8;

typedef const u8 *LZF_STATE[1 << (HLOG)];

#if !STRICT_ALIGN
/* for unaligned accesses we need a 16 bit datatype. */
# include <limits.h>
# if USHRT_MAX == 65535
    typedef unsigned short u16;
# elif UINT_MAX == 65535
    typedef unsigned int u16;
# else
#  undef STRICT_ALIGN
#  define STRICT_ALIGN 1
# endif
#endif

#if ULTRA_FAST
# if defined(VERY_FAST)
#  undef VERY_FAST
# endif
#endif

#if INIT_HTAB
# ifdef __cplusplus
#  include <cstring>
# else
#  include <string.h>
# endif
#endif

#endif



================================================
FILE: QBase/lzf/lzf_c.c
================================================
/*
 * Copyright (c) 2000-2008 Marc Alexander Lehmann <schmorp@schmorp.de>
 * 
 * Redistribution and use in source and binary forms, with or without modifica-
 * tion, are permitted provided that the following conditions are met:
 * 
 *   1.  Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 * 
 *   2.  Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
 * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
 * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
 * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Alternatively, the contents of this file may be used under the terms of
 * the GNU General Public License ("GPL") version 2 or any later version,
 * in which case the provisions of the GPL are applicable instead of
 * the above. If you wish to allow the use of your version of this file
 * only under the terms of the GPL and not to allow others to use your
 * version of this file under the BSD license, indicate your decision
 * by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL. If you do not delete the
 * provisions above, a recipient may use your version of this file under
 * either the BSD or the GPL.
 */

#include "lzfP.h"

#define HSIZE (1 << (HLOG))

/*
 * don't play with this unless you benchmark!
 * decompression is not dependent on the hash function
 * the hashing function might seem strange, just believe me
 * it works ;)
 */
#ifndef FRST
# define FRST(p) (((p[0]) << 8) | p[1])
# define NEXT(v,p) (((v) << 8) | p[2])
# if ULTRA_FAST
#  define IDX(h) ((( h             >> (3*8 - HLOG)) - h  ) & (HSIZE - 1))
# elif VERY_FAST
#  define IDX(h) ((( h             >> (3*8 - HLOG)) - h*5) & (HSIZE - 1))
# else
#  define IDX(h) ((((h ^ (h << 5)) >> (3*8 - HLOG)) - h*5) & (HSIZE - 1))
# endif
#endif
/*
 * IDX works because it is very similar to a multiplicative hash, e.g.
 * ((h * 57321 >> (3*8 - HLOG)) & (HSIZE - 1))
 * the latter is also quite fast on newer CPUs, and compresses similarly.
 *
 * the next one is also quite good, albeit slow ;)
 * (int)(cos(h & 0xffffff) * 1e6)
 */

#if 0
/* original lzv-like hash function, much worse and thus slower */
# define FRST(p) (p[0] << 5) ^ p[1]
# define NEXT(v,p) ((v) << 5) ^ p[2]
# define IDX(h) ((h) & (HSIZE - 1))
#endif

#define        MAX_LIT        (1 <<  5)
#define        MAX_OFF        (1 << 13)
#define        MAX_REF        ((1 << 8) + (1 << 3))

#if __GNUC__ >= 3
# define expect(expr,value)         __builtin_expect ((expr),(value))
# define inline                     inline
#else
# define expect(expr,value)         (expr)
# define inline                     static
#endif

#define expect_false(expr) expect ((expr) != 0, 0)
#define expect_true(expr)  expect ((expr) != 0, 1)

/*
 * compressed format
 *
 * 000LLLLL <L+1>    ; literal
 * LLLooooo oooooooo ; backref L
 * 111ooooo LLLLLLLL oooooooo ; backref L+7
 *
 */

unsigned int
lzf_compress (const void *const in_data, unsigned int in_len,
	      void *out_data, unsigned int out_len
#if LZF_STATE_ARG
              , LZF_STATE htab
#endif
              )
{
#if !LZF_STATE_ARG
  LZF_STATE htab;
#endif
  const u8 **hslot;
  const u8 *ip = (const u8 *)in_data;
        u8 *op = (u8 *)out_data;
  const u8 *in_end  = ip + in_len;
        u8 *out_end = op + out_len;
  const u8 *ref;

  /* off requires a type wide enough to hold a general pointer difference.
   * ISO C doesn't have that (size_t might not be enough and ptrdiff_t only
   * works for differences within a single object). We also assume that no
   * no bit pattern traps. Since the only platform that is both non-POSIX
   * and fails to support both assumptions is windows 64 bit, we make a
   * special workaround for it.
   */
#if defined (WIN32) && defined (_M_X64)
  unsigned _int64 off; /* workaround for missing POSIX compliance */
#else
  unsigned long off;
#endif
  unsigned int hval;
  int lit;

  if (!in_len || !out_len)
    return 0;

#if INIT_HTAB
  memset (htab, 0, sizeof (htab));
# if 0
  for (hslot = htab; hslot < htab + HSIZE; hslot++)
    *hslot++ = ip;
# endif
#endif

  lit = 0; op++; /* start run */

  hval = FRST (ip);
  while (ip < in_end - 2)
    {
      hval = NEXT (hval, ip);
      hslot = htab + IDX (hval);
      ref = *hslot; *hslot = ip;

      if (1
#if INIT_HTAB
          && ref < ip /* the next test will actually take care of this, but this is faster */
#endif
          && (off = ip - ref - 1) < MAX_OFF
          && ip + 4 < in_end
          && ref > (u8 *)in_data
#if STRICT_ALIGN
          && ref[0] == ip[0]
          && ref[1] == ip[1]
          && ref[2] == ip[2]
#else
          && *(u16 *)ref == *(u16 *)ip
          && ref[2] == ip[2]
#endif
        )
        {
          /* match found at *ref++ */
          unsigned int len = 2;
          unsigned int maxlen = (unsigned int)(in_end - ip - len);
          maxlen = maxlen > MAX_REF ? MAX_REF : maxlen;

          op [- lit - 1] = lit - 1; /* stop run */
          op -= !lit; /* undo run if length is zero */

          if (expect_false (op + 3 + 1 >= out_end))
            return 0;

          for (;;)
            {
              if (expect_true (maxlen > 16))
                {
                  len++; if (ref [len] != ip [len]) break;
                  len++; if (ref [len] != ip [len]) break;
                  len++; if (ref [len] != ip [len]) break;
                  len++; if (ref [len] != ip [len]) break;

                  len++; if (ref [len] != ip [len]) break;
                  len++; if (ref [len] != ip [len]) break;
                  len++; if (ref [len] != ip [len]) break;
                  len++; if (ref [len] != ip [len]) break;

                  len++; if (ref [len] != ip [len]) break;
                  len++; if (ref [len] != ip [len]) break;
                  len++; if (ref [len] != ip [len]) break;
                  len++; if (ref [len] != ip [len]) break;

                  len++; if (ref [len] != ip [len]) break;
                  len++; if (ref [len] != ip [len]) break;
                  len++; if (ref [len] != ip [len]) break;
                  len++; if (ref [len] != ip [len]) break;
                }

              do
                len++;
              while (len < maxlen && ref[len] == ip[len]);

              break;
            }

          len -= 2; /* len is now #octets - 1 */
          ip++;

          if (len < 7)
            {
              *op++ = (off >> 8) + (len << 5);
            }
          else
            {
              *op++ = (off >> 8) + (  7 << 5);
              *op++ = len - 7;
            }

          *op++ = off;
          lit = 0; op++; /* start run */

          ip += len + 1;

          if (expect_false (ip >= in_end - 2))
            break;

#if ULTRA_FAST || VERY_FAST
          --ip;
# if VERY_FAST && !ULTRA_FAST
          --ip;
# endif
          hval = FRST (ip);

          hval = NEXT (hval, ip);
          htab[IDX (hval)] = ip;
          ip++;

# if VERY_FAST && !ULTRA_FAST
          hval = NEXT (hval, ip);
          htab[IDX (hval)] = ip;
          ip++;
# endif
#else
          ip -= len + 1;

          do
            {
              hval = NEXT (hval, ip);
              htab[IDX (hval)] = ip;
              ip++;
            }
          while (len--);
#endif
        }
      else
        {
          /* one more literal byte we must copy */
          if (expect_false (op >= out_end))
            return 0;

          lit++; *op++ = *ip++;

          if (expect_false (lit == MAX_LIT))
            {
              op [- lit - 1] = lit - 1; /* stop run */
              lit = 0; op++; /* start run */
            }
        }
    }

  if (op + 3 > out_end) /* at most 3 bytes can be missing here */
    return 0;

  while (ip < in_end)
    {
      lit++; *op++ = *ip++;

      if (expect_false (lit == MAX_LIT))
        {
          op [- lit - 1] = lit - 1; /* stop run */
          lit = 0; op++; /* start run */
        }
    }

  op [- lit - 1] = lit - 1; /* end run */
  op -= !lit; /* undo run if length is zero */

  return (unsigned int)(op - (u8 *)out_data);
}



================================================
FILE: QBase/lzf/lzf_d.c
================================================
/*
 * Copyright (c) 2000-2007 Marc Alexander Lehmann <schmorp@schmorp.de>
 * 
 * Redistribution and use in source and binary forms, with or without modifica-
 * tion, are permitted provided that the following conditions are met:
 * 
 *   1.  Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 * 
 *   2.  Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
 * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
 * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
 * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Alternatively, the contents of this file may be used under the terms of
 * the GNU General Public License ("GPL") version 2 or any later version,
 * in which case the provisions of the GPL are applicable instead of
 * the above. If you wish to allow the use of your version of this file
 * only under the terms of the GPL and not to allow others to use your
 * version of this file under the BSD license, indicate your decision
 * by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL. If you do not delete the
 * provisions above, a recipient may use your version of this file under
 * either the BSD or the GPL.
 */

#include "lzfP.h"

#if AVOID_ERRNO
# define SET_ERRNO(n)
#else
# include <errno.h>
# define SET_ERRNO(n) errno = (n)
#endif

/*
#if (__i386 || __amd64) && __GNUC__ >= 3
# define lzf_movsb(dst, src, len)                \
   asm ("rep movsb"                              \
        : "=D" (dst), "=S" (src), "=c" (len)     \
        :  "0" (dst),  "1" (src),  "2" (len));
#endif
*/

unsigned int 
lzf_decompress (const void *const in_data,  unsigned int in_len,
                void             *out_data, unsigned int out_len)
{
  u8 const *ip = (const u8 *)in_data;
  u8       *op = (u8 *)out_data;
  u8 const *const in_end  = ip + in_len;
  u8       *const out_end = op + out_len;

  do
    {
      unsigned int ctrl = *ip++;

      if (ctrl < (1 << 5)) /* literal run */
        {
          ctrl++;

          if (op + ctrl > out_end)
            {
              SET_ERRNO (E2BIG);
              return 0;
            }

#if CHECK_INPUT
          if (ip + ctrl > in_end)
            {
              SET_ERRNO (EINVAL);
              return 0;
            }
#endif

#ifdef lzf_movsb
          lzf_movsb (op, ip, ctrl);
#else
          do
            *op++ = *ip++;
          while (--ctrl);
#endif
        }
      else /* back reference */
        {
          unsigned int len = ctrl >> 5;

          u8 *ref = op - ((ctrl & 0x1f) << 8) - 1;

#if CHECK_INPUT
          if (ip >= in_end)
            {
              SET_ERRNO (EINVAL);
              return 0;
            }
#endif
          if (len == 7)
            {
              len += *ip++;
#if CHECK_INPUT
              if (ip >= in_end)
                {
                  SET_ERRNO (EINVAL);
                  return 0;
                }
#endif
            }

          ref -= *ip++;

          if (op + len + 2 > out_end)
            {
              SET_ERRNO (E2BIG);
              return 0;
            }

          if (ref < (u8 *)out_data)
            {
              SET_ERRNO (EINVAL);
              return 0;
            }

#ifdef lzf_movsb
          len += 2;
          lzf_movsb (op, ref, len);
#else
          *op++ = *ref++;
          *op++ = *ref++;

          do
            *op++ = *ref++;
          while (--len);
#endif
        }
    }
  while (ip < in_end);

  return (unsigned int)(op - (u8 *)out_data);
}



================================================
FILE: QSentinel/CMakeLists.txt
================================================
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)

INCLUDE(${PROJECT_SOURCE_DIR}/CMakeCommon)

LINK_DIRECTORIES(../../leveldb)

AUX_SOURCE_DIRECTORY(. CLUSTER_SRC)
AUX_SOURCE_DIRECTORY(./zookeeper CLUSTER_SRC)

SET(LIBRARY_OUTPUT_PATH ../../bin)
ADD_LIBRARY(qcluster SHARED ${CLUSTER_SRC})

INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/QBase)
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/QedisCore)

TARGET_LINK_LIBRARIES(qcluster; qbaselib; qediscore; leveldb; pthread)
ADD_DEPENDENCIES(qcluster qediscore qbaselib leveldb)

SET_TARGET_PROPERTIES(qcluster PROPERTIES LINKER_LANGUAGE CXX)


================================================
FILE: QSentinel/QClusterClient.cc
================================================
#if QEDIS_CLUSTER

#include "Log/Logger.h"
#include "Server.h"

#include "QConfig.h"
#include "QCommand.h"
#include "QClusterClient.h"

#if USE_ZOOKEEPER
#include "zookeeper/ZookeeperConn.h"
#endif

namespace qedis
{

PacketLength QClusterClient::_HandlePacket(const char* data, std::size_t bytes)
{
    const char* ptr = data;
    
    bool result = conn_->ParseMessage(ptr, bytes);
    if (!result)
    {
        OnError(); 
        return 0;
    }

    return static_cast<PacketLength>(ptr - data);
}

bool QClusterClient::Init(int fd, const SocketAddr& peer)
{ 
    if (!StreamSocket::Init(fd, peer))
        return false;

    auto me = std::static_pointer_cast<QClusterClient>(shared_from_this()); 
    SocketAddr myAddr(g_config.ip.c_str(), g_config.port);

#if USE_ZOOKEEPER
    QClusterConn* conn = new ZookeeperConn(me, g_config.setid, myAddr.ToString());
#else
#error "Only support zookeeper for now, supporting etcd is in progress"
#endif

    conn->SetOnBecomeMaster([](const std::vector<SocketAddr>& slaves) {
        INF << "I become master";
        std::vector<QString> cmd {"slaveof", "no", "one"};
        slaveof(cmd, nullptr);

        for (const auto& addr : slaves)
        {
            INF << "Try connect to slave " << addr.ToString();
            // connect to slaves and send 'slave of me' 
            Server::Instance()->TCPConnect(addr, ConnectionTag::kSlaveClient);
        }
        // 读取所有set的数据保存其版本号 
        // *set的数据格式是  1,3,4,7|2:1,4
        // 含义:本set负责slot 1347,但是现在正在将slot 1,4迁移到set2上
    });

    conn->SetOnBecomeSlave([](const std::string& master) {
        INF << "I become slave of " << master;
        std::vector<QString> cmd(SplitString(master, ':'));
        slaveof({"slaveof", cmd[0], cmd[1]}, nullptr);
    });

    conn_.reset(conn);

    return true; 
}

void QClusterClient::OnConnect()
{
    conn_->OnConnect();
}

void QClusterClient::OnDisconnect()
{
    conn_->OnDisconnect();
}

} // end namespace qedis

#endif



================================================
FILE: QSentinel/QClusterClient.h
================================================
#ifndef BERT_QCLUSTERCLIENT_H
#define BERT_QCLUSTERCLIENT_H

#if QEDIS_CLUSTER

#include "StreamSocket.h"
#include "QClusterInterface.h"

namespace ConnectionTag
{
   const int kSentinelClient = 2;
}


namespace qedis
{

class QClusterClient: public StreamSocket
{
public:
    void OnConnect() override;
    void OnDisconnect() override;
    bool Init(int fd, const SocketAddr& peer);
    
private:
    PacketLength _HandlePacket(const char*, std::size_t) override;

    std::unique_ptr<QClusterConn> conn_;
};
    
}

#endif // endif QEDIS_CLUSTER

#endif // endif BERT_QCLUSTERCLIENT_H



================================================
FILE: QSentinel/QClusterInterface.h
================================================
#ifndef BERT_CLUSTERINTERFACE_H
#define BERT_CLUSTERINTERFACE_H

#if QEDIS_CLUSTER

#include <vector>
#include <string>
#include <functional>

#include "Socket.h"

namespace ConnectionTag
{
   const int kSlaveClient = 3;
}

namespace qedis
{

class QClusterConn
{ 
public:
    virtual ~QClusterConn()
    {
    }

    void SetOnBecomeMaster(std::function<void (const std::vector<SocketAddr>& )> cb)
    {
        onBecomeMaster_ = std::move(cb);
    }

    void SetOnBecomeSlave(std::function<void (const std::string& )> cb)
    {
        onBecomeSlave_ = std::move(cb);
    }

public:
    virtual bool ParseMessage(const char*& data, size_t len) = 0;
    virtual void OnConnect() = 0;
    virtual void OnDisconnect() = 0;

protected:
    std::function<void (const std::vector<SocketAddr>& )> onBecomeMaster_;
    std::function<void (const std::string& )> onBecomeSlave_;

};

} // end namespace qedis

#endif // endif QEDIS_CLUSTER

#endif // endif BERT_CLUSTERINTERFACE_H



================================================
FILE: QSentinel/README.md
================================================
# Qedis高可用集群

利用Zookeeper实现的Qedis高可用集群,功能类似redis-sentinel。在此基础上可实现sacle-out集群。

## 环境需求
* C++11、CMake
* zookeeper
* Linux 或 MAC OS

## 集群特性
 搭建Zookeeper,监视一组互为主备的Qedis进程以实现高可用;

 当然也可以使用官方redis-sentinel。

 scale-out集群正在开发中...

## 简单原理

    /servers
        /set-1
            /qedis-(127.0.0.1:6379)-0001
            /qedis-(127.0.0.1:6381)-0003
            /qedis-(127.0.0.1:6382)-0004
            /qedis-(127.0.0.1:6385)-0007
        /set-2
            /qedis-(127.0.0.1:16379)-0004
            /qedis-(127.0.0.1:16389)-0007
            /qedis-(127.0.0.1:16399)-0008

 一组Qedis进程形成一个set,set内最多只有一个master,其它都是slave,且没有级联复制结构。

 通过配置文件中setid来配置set,相同setid的Qedis进程将形成一个set。

 通过设置配置文件中cluster开关,Qedis在启动时,将尝试向Zookeeper的/servers/set-{id}/下创建自己的临时顺序节点。

 创建成功后,获取孩子列表,看自己的节点序号是不是最小。

 如果是最小,则是master,向所有孩子发送slaveof my_addr的命令;

 如果不是,则监视比自己序号大的孩子中序号最小的节点。比如我的序号是7,孩子列表序号是1,3,4,7,则我监视4节点。

 当我收到监视的节点被删除的通知,则判断自己是否是master(因为启动时已经获得孩子列表了)。

 是或不是,都继续重复上述过的逻辑。


================================================
FILE: QSentinel/zookeeper/ZookeeperConn.cc
================================================
#if QEDIS_CLUSTER

#include <unistd.h>
#include "ZookeeperConn.h"
#include "Log/Logger.h"
#include "QCommon.h"

#include "zookeeper.jute.h"
#include "proto.h"

static int deserialize_prime_response(struct prime_struct* req, AttachedBuffer& buffer)
{
    buffer >> req->len;
    req->len = ntohl(req->len); 

    buffer >> req->protocolVersion;
    req->protocolVersion = ntohl(req->protocolVersion); 

    buffer >> req->timeOut;
    req->timeOut = ntohl(req->timeOut);

    buffer >> req->sessionId;
    req->sessionId = htonll(req->sessionId); 

    buffer >> req->passwd_len;
    req->passwd_len = ntohl(req->passwd_len); 

    memcpy(req->passwd, buffer.ReadAddr(), sizeof(req->passwd)); 
    return 0;
}
          
          
const int kTimeout = 15 * 1000; // ms

namespace qedis
{
    
    
ZookeeperConn::ZookeeperConn(const std::shared_ptr<StreamSocket>& c, int setId, const std::string& addr) :
    xid_(0),
    setId_(setId),
    addr_(addr),
    state_(State::kNone),
    pingTimer_(nullptr),
    sock_(c)
{
    lastPing_.tv_sec = 0;
    lastPing_.tv_usec = 0;
    sessionInfo_.passwd[0] = '\0';
    sessionFile_ = "zk.session" + addr;
}

ZookeeperConn::~ZookeeperConn()
{
}

bool ZookeeperConn::ParseMessage(const char*& data, size_t len)
{
    switch (state_)
    {
    case State::kHandshaking:
        {
            if (len < HANDSHAKE_RSP_SIZE)
                return true;

            struct prime_struct rsp;
            AttachedBuffer buffer(const_cast<char* >(data), len);
            deserialize_prime_response(&rsp, buffer);
            data += sizeof(int) + rsp.len;
        
            if (!_ProcessHandshake(rsp))
                return false;
        }
        break;

    case State::kConnected:
        {
            if (len < 4)
                return true;

            int thisLen = *(int*)data;
            thisLen = ntohl(thisLen);
            if (sizeof(thisLen) + thisLen > len)
                return true;

            struct ReplyHeader hdr;
            struct iarchive *ia = create_buffer_iarchive(const_cast<char* >(data) + 4, thisLen); 
            deserialize_ReplyHeader(ia, "hdr", &hdr);

            // update zxid
            if (hdr.zxid > 0)
                sessionInfo_.lastSeenZxid = hdr.zxid;

            if (!_ProcessResponse(hdr, ia))
                return false;

            data += thisLen + sizeof(thisLen);
        }
        break;

    default:
        assert (false);
        break;
    }

    return true;
}

void ZookeeperConn::OnConnect()
{
    assert (state_ == State::kNone);

    {
        auto del = [this](FILE* fp) {
            ::fclose(fp);
            ::unlink(this->sessionFile_.c_str());
        };

        std::unique_ptr<FILE, decltype(del)> _(fopen(sessionFile_.data(), "rb"), del);
        FILE* const fp = _.get();

        if (fp)
            fread(&sessionInfo_, sizeof sessionInfo_, 1, fp);
    }

    char buffer_req[HANDSHAKE_REQ_SIZE];
    int len = sizeof(buffer_req);
    
    struct connect_req req; 
    req.protocolVersion = 0; 
    req.sessionId = sessionInfo_.sessionId;
    req.passwd_len = sizeof(req.passwd);
    req.timeOut = kTimeout;
    req.lastZxidSeen = sessionInfo_.lastSeenZxid;
    memcpy(req.passwd, sessionInfo_.passwd, req.passwd_len);
                    
    StackBuffer<HANDSHAKE_REQ_SIZE + 4> buf;
    buf << htonl(len)
        << htonl(req.protocolVersion)
        << htonll(req.lastZxidSeen)
        << htonl(req.timeOut)
        << htonll(req.sessionId)
        << htonl(req.passwd_len);

    if (req.passwd_len > 0)
        buf.PushData(req.passwd, req.passwd_len);

    auto s = sock_.lock();
    if (s)
    {
        state_ = State::kHandshaking;
        s->SendPacket(buf);
    }
}

void ZookeeperConn::OnDisconnect()
{
    if (pingTimer_)
        TimerManager::Instance().KillTimer(pingTimer_);
}

static struct ACL _OPEN_ACL_UNSAFE_ACL[] = {{0x1f,
                                                 {const_cast<char*>("world"),
                                                  const_cast<char*>("anyone")
                                                 }
                                           }};
struct ACL_vector ZOO_OPEN_ACL_UNSAFE = { 1, _OPEN_ACL_UNSAFE_ACL};

    
static std::string MakeParentNode(int setid)
{
    std::string path("/servers/set-");
    path += std::to_string(setid); 

    return path;
}

// /servers/set-{setid}/qedis(ip:port)-xxxseq
static std::string MakeNodePath(int setid, const std::string& addr)
{
    std::string path(MakeParentNode(setid));
    path += "/qedis(" + addr + ")-";

    return path;
}

static int GetNodeSeq(const std::string& path)
{
    // /servers/set-{setid}/qedis(ip:port)-xxxseq
    auto pos = path.find_last_of('-');
    if (pos == std::string::npos)
        return -1;

    std::string number(path.substr(pos + 1));
    return std::stoi(number);
}

static std::string GetNodeAddr(const std::string& path)
{
    // /servers/set-{setid}/qedis(ip:port)-xxxseq
    auto start = path.find_first_of('(');
    auto end = path.find_first_of(')');
    if (start == std::string::npos ||
        end == std::string::npos)
        return std::string();

    return path.substr(start + 1, end - start - 1);
}

void ZookeeperConn::_RunForMaster(int setid, const std::string& value)
{
    INF << __FUNCTION__ << ", setid " << setid << ", value " << value;

    struct oarchive* oa = create_buffer_oarchive();
    struct RequestHeader h = { STRUCT_INITIALIZER (xid , _GetXid()), STRUCT_INITIALIZER (type ,ZOO_CREATE_OP) };
    int rc = serialize_RequestHeader(oa, "header", &h);

    if (rc < 0) return;

    std::string path(MakeNodePath(setid, addr_));

    struct CreateRequest req;
    req.path = const_cast<char* >(path.data());
    req.data.buff = const_cast<char* >(value.data());
    req.data.len = static_cast<int32_t>(value.size());
    req.flags = ZOO_SEQUENCE | ZOO_EPHEMERAL;
    req.acl = ZOO_OPEN_ACL_UNSAFE;
    rc = rc < 0 ? rc : serialize_CreateRequest(oa, "req", &req);

    _SendPacket(h, oa);
}

int ZookeeperConn::_GetXid() const
{
    return ++ xid_; 
}
    
bool ZookeeperConn::_ProcessHandshake(const prime_struct& rsp)
{
    if (sessionInfo_.sessionId && sessionInfo_.sessionId != rsp.sessionId)
    {
        DBG << "expired, new session " << rsp.sessionId;
        return false;
    }

    const bool resumedSession = (sessionInfo_.sessionId == rsp.sessionId);
    if (resumedSession)
        DBG << "resume session Id " << rsp.sessionId;
    else
        DBG << "new session Id " << rsp.sessionId;

    sessionInfo_.sessionId = rsp.sessionId;
    memcpy(sessionInfo_.passwd, rsp.passwd, rsp.passwd_len);

    std::unique_ptr<FILE, decltype(fclose)*> _(fopen(sessionFile_.data(), "wb"), fclose);
    FILE* fp = _.get();
    fwrite(&sessionInfo_, sizeof sessionInfo_, 1, fp);

    state_ = State::kConnected;

    _InitPingTimer();
                
    if (resumedSession)
    {
        // My node must exists
        if (!_GetSiblings(MakeParentNode(setId_)))
            return false;
    }
    else
    {
        // Create my node
        _RunForMaster(setId_, addr_);
    }

    return true;
}

void ZookeeperConn::_InitPingTimer()
{
    assert (!pingTimer_);
    pingTimer_ = TimerManager::Instance().CreateTimer();
    pingTimer_->Init(kTimeout / 2);
    pingTimer_->SetCallback([this]() {
        struct oarchive *oa = create_buffer_oarchive();
        struct RequestHeader h = { STRUCT_INITIALIZER(xid, PING_XID), STRUCT_INITIALIZER (type , ZOO_PING_OP) };

        serialize_RequestHeader(oa, "header", &h); 
        gettimeofday(&this->lastPing_, nullptr);

        _SendPacket(h, oa);
    });

    TimerManager::Instance().AsyncAddTimer(pingTimer_);
}

bool ZookeeperConn::_IsMaster() const
{
    if (siblings_.empty())
        return false;

    auto me = siblings_.find(seq_);
    assert (me != siblings_.end());

    return me == siblings_.begin();
}

bool ZookeeperConn::_ProcessWatchEvent(const ReplyHeader& hdr, iarchive* ia)
{
    struct WatcherEvent evt;
    deserialize_WatcherEvent(ia, "event", &evt);

    INF << "WatcherEventType " << evt.type
        << ", state " << evt.state
        << ", path " << evt.path;

    switch (evt.type)
    {
        case DELETED_EVENT_DEF:
            _OnNodeDelete(evt.path);
            break;

        default:
            break;
    }

    deallocate_WatcherEvent(&evt);
    return true;
}

bool ZookeeperConn::_ProcessResponse(const ReplyHeader& hdr, iarchive* ia)
{
    if (hdr.xid == WATCHER_EVENT_XID)
    {
        return _ProcessWatchEvent(hdr, ia);
    }

    // TODO process some other watcher events

    if (pendingRequests_.empty())
    {
        ERR << "Can not find request " << hdr.xid;
        return false;
    }

    const Request& req = pendingRequests_.front();
    QEDIS_DEFER
    {
        pendingRequests_.pop_front();
    };

    if (req.xid != hdr.xid)
    {
        ERR << "wrong req xid " << req.xid << ", wrong order response " << hdr.xid;
        return false;
    }

    if (req.type != ZOO_PING_OP)
        INF << "req.type " << req.type;

    switch (req.type)
    {
    case ZOO_PING_OP:
        {
            timeval now;
            gettimeofday(&now, nullptr);
            int microseconds = (now.tv_sec - lastPing_.tv_sec) * 1000000;
            microseconds += (now.tv_usec - lastPing_.tv_usec);
            if (microseconds > 10 * 1000)
                WRN << "recv ping used microseconds " << microseconds;
        }
        break;

    case ZOO_CREATE_OP:
        {
            CreateResponse rsp;
            if (deserialize_CreateResponse(ia, "rsp", &rsp) != 0)
            {
                ERR << "deserialize_CreateResponse failed";
                return false;
            }

            QEDIS_DEFER
            {
                deallocate_CreateResponse(&rsp);
            };

            assert (node_.empty());
            node_ = rsp.path;
            seq_ = GetNodeSeq(node_);
            assert (seq_ >= 0);

            DBG << "my node seq " << seq_
                << " for my node " << node_
                << ", addr " << GetNodeAddr(node_);

            if (!_GetSiblings(MakeParentNode(setId_)))
                return false;
        }
        break;

    case ZOO_GETCHILDREN2_OP:
        {
            GetChildren2Response rsp;
            if (deserialize_GetChildren2Response(ia, "rsp", &rsp) != 0)
            {
                ERR << "deserialize_GetChildren2Response failed";
                return false;
            }

            QEDIS_DEFER
            {
                deallocate_GetChildren2Response(&rsp);
            };

            siblings_.clear();
            for (int i = 0; i < rsp.children.count; ++ i)
            {
                const std::string& node = rsp.children.data[i];
                int seq = GetNodeSeq(node);
                assert (seq >= 0);

                if (node_.empty())
                {
                    std::string addr = GetNodeAddr(node);
                    if (addr == addr_)
                    {
                        node_ = node;
                        seq_ = seq;
                        DBG << "Resumed session: my seq " << seq_
                            << " for my node " << node_
                            << ", addr " << GetNodeAddr(node_);
                    }
                }


                INF << "Get sibling " << node;
                siblings_.insert({seq, node});
            }

            auto me = siblings_.find(seq_);
            assert (me != siblings_.end());
            if (me == siblings_.begin())
            {
                // I am master!先获取节点分片信息,再执行slaveof no one等
                if (!_GetData(MakeParentNode(setId_), true))
                {
                    ERR << "_GetData failed for set " << setId_;
                    return false;
                }
            }
            else
            {
                // monitor the node bigger than me
                auto brother = -- me; // I'll watch you
                _Exists(MakeParentNode(setId_) + "/" + brother->second, true);
            }
        }
        break;

    case ZOO_GETDATA_OP:
        {
            GetDataResponse drsp;
            if (deserialize_GetDataResponse(ia, "rsp", &drsp) != 0)
            {
                ERR << "deserialize_GetDataResponse failed";
                return false;
            }

            QEDIS_DEFER
            {
                deallocate_GetDataResponse(&drsp);
            };
                
            // 获取了节点分片信息

            std::vector<SocketAddr> slaves;
            slaves.reserve(siblings_.size());

            auto me = siblings_.find(seq_);
            assert (me != siblings_.end());
            auto slave = me;
            for (++ slave; slave != siblings_.end(); ++ slave)
            {
                SocketAddr addr(GetNodeAddr(slave->second));
                slaves.push_back(addr);
            }

#if 0
            std::vector<int> shardings;
            std::unordered_map<int, std::vector<int> > migration; // dst set & shardings
            {
                // *set的数据格式是  1,3,4,7|2:1,4
                std::string data(drsp.data.buff, drsp.data.len);
                std::vector<QString> tmp(SplitString(data, '|'));
                std::vector<QString> shardingStr(SplitString(tmp[0], ','));
                auto it = tmp.begin();
                for (++ it; it != tmp.end(); ++ it)
                {
                    std::vector<QString> dstAndShardingStr(SplitString(*it, ':'));
                    assert (dstAndShardingStr.size() == 2);

                    int dstSetId = std::stoi(dstAndShardingStr[0]);
                    std::vector<QString> migrateStr(SplitString(dstAndShardingStr[1], ','));
                    std::vector<int> migrates;
                    migrates.reserve(migrateStr.size());
                    for (const auto& s : migrateStr)
                        migrates.push_back(std::stoi(s));

                    migration[dstSetId] = migrates;
                }
            }
#endif

            if (onBecomeMaster_)
                onBecomeMaster_(slaves);
        }
        break;

    case ZOO_EXISTS_OP:
        {
            if (hdr.err == ZNONODE)
            {
                _OnNodeDelete(req.path);
            }
            else
            {
                assert (hdr.err == ZOK);
                ExistsResponse rsp;
                if (deserialize_ExistsResponse(ia, "rsp", &rsp) != 0)
                {
                    ERR << "deserialize_ExistsResponse failed";
                    return false;
                }

                QEDIS_DEFER
                {
                    deallocate_ExistsResponse(&rsp);
                };

                DBG << "Exists response version " << rsp.stat.version;
                if (onBecomeSlave_)
                {
                    std::string master = GetNodeAddr(siblings_.begin()->second);
                    if (master.empty())
                        return false;

                    onBecomeSlave_(master);
                }
            }
        }
        break;

    default:
        break;
    }

    return true;
}

bool ZookeeperConn::_GetSiblings(const std::string& parent)
{
    struct oarchive* oa = create_buffer_oarchive();

    struct RequestHeader h = { STRUCT_INITIALIZER( xid, _GetXid()), STRUCT_INITIALIZER (type ,ZOO_GETCHILDREN2_OP)};
    struct GetChildren2Request req;
    req.path = const_cast<char* >(parent.data());
    req.watch = 0;
    
    int rc = serialize_RequestHeader(oa, "header", &h); 
    rc = rc < 0 ? rc : serialize_GetChildren2Request(oa, "req", &req);

    if (!_SendPacket(h, oa, &parent))
        return false;

    return rc >= 0;
}

bool ZookeeperConn::_GetData(const std::string& node, bool watch)
{
    struct oarchive* oa = create_buffer_oarchive();

    struct RequestHeader h = { STRUCT_INITIALIZER( xid, _GetXid()), STRUCT_INITIALIZER(type ,ZOO_GETDATA_OP)};
    struct GetDataRequest req;
    req.path = const_cast<char* >(node.data());
    req.watch = watch ? 1 : 0;
    
    int rc = serialize_RequestHeader(oa, "header", &h); 
    rc = rc < 0 ? rc : serialize_GetDataRequest(oa, "req", &req);

    if (!_SendPacket(h, oa, &node))
        return false;

    return rc >= 0;
}


bool ZookeeperConn::_Exists(const std::string& sibling, bool watch)
{
    struct oarchive* oa = create_buffer_oarchive();

    struct RequestHeader h = { STRUCT_INITIALIZER( xid, _GetXid()), STRUCT_INITIALIZER (type ,ZOO_EXISTS_OP)};
    struct ExistsRequest req;
    req.path = const_cast<char* >(sibling.data());
    req.watch = watch ? 1 : 0;
    
    int rc = serialize_RequestHeader(oa, "header", &h); 
    rc = rc < 0 ? rc : serialize_ExistsRequest(oa, "req", &req);

    if (!_SendPacket(h, oa, &sibling))
        return false;

    return rc >= 0;
}

bool ZookeeperConn::_SendPacket(const RequestHeader& h, struct oarchive* oa, const std::string* v)
{
    auto s = sock_.lock();
    if (!s)
        return false;
        
    int totalLen = htonl(get_buffer_len(oa));
    s->SendPacket(&totalLen, sizeof totalLen);
    s->SendPacket(get_buffer(oa), get_buffer_len(oa));

    Request r;
    r.xid = h.xid;
    r.type = h.type;
    if (v) r.path = *v;

    pendingRequests_.emplace_back(std::move(r));
   
    close_buffer_oarchive(&oa, 1);
    return true;
}

void ZookeeperConn::_OnNodeDelete(const std::string& node)
{
    const std::string siblingName = node.substr(node.find_last_of('/') + 1);
    const int seq = GetNodeSeq(siblingName);
    siblings_.erase(seq);
    if (_IsMaster())
    {
        // Though I'll be master, I must broadcast this fact to all children.
        bool succ = _GetSiblings(MakeParentNode(setId_));
        if (!succ)
            ERR << __FUNCTION__ << ", _GetSiblings failed with " << setId_;
    }
    else
    {
        auto me = siblings_.find(seq_);
        assert (me != siblings_.begin());
        assert (me != siblings_.end());

        auto brother = -- me; // I'll watch you
        _Exists(MakeParentNode(setId_) + "/" + brother->second, true);
    }
}

} // end namespace qedis

#endif


================================================
FILE: QSentinel/zookeeper/ZookeeperConn.h
================================================
#ifndef BERT_ZOOKEEPERCONN_H
#define BERT_ZOOKEEPERCONN_H

#include <list>
#include <map>
#include "StreamSocket.h"
#include "../QClusterInterface.h"

struct prime_struct;
struct RequestHeader;
struct ReplyHeader;
struct iarchive;
struct oarchive;

class Timer;

namespace qedis
{

class ZookeeperConn : public QClusterConn
{
public:
    ZookeeperConn(const std::shared_ptr<StreamSocket>& c, int setId, const std::string& addr);
    ~ZookeeperConn();

    bool ParseMessage(const char*& data, size_t len) override;
    void OnConnect() override;
    void OnDisconnect() override;

private:
    void _RunForMaster(int setid, const std::string& val);
    bool _ProcessHandshake(const prime_struct& rsp);
    bool _ProcessResponse(const ReplyHeader& header, iarchive* ia);
    bool _ProcessWatchEvent(const ReplyHeader& header, iarchive* ia);
    bool _GetSiblings(const std::string& parent);
    bool _GetData(const std::string& node, bool watch = true);
    bool _Exists(const std::string& sibling, bool watch = true);
    void _InitPingTimer();
    bool _IsMaster() const;
    bool _SendPacket(const RequestHeader& h, struct oarchive* oa, const std::string* = nullptr);
    void _OnNodeDelete(const std::string& node);

    int _GetXid() const;
    mutable int xid_;

    const int setId_;
    const std::string addr_;

    enum class State
    {
        kNone,
        kHandshaking,
        kConnected,
    } state_;

    struct Request
    {
        int type;
        int xid;
        std::string path;
    };
    std::list<Request> pendingRequests_;

    timeval lastPing_;

    // my node & seq
    std::string node_;
    int seq_;
    // nodes in my set
    std::map<int, std::string> siblings_;

#pragma pack(1)
    struct SessionInfo
    {
        int64_t sessionId{0};
        char passwd[16];
        // ? zk_cli doesn't persist this field
        int64_t lastSeenZxid {0};
    } sessionInfo_;
#pragma pack()

    std::string sessionFile_;
    Timer* pingTimer_;
    std::weak_ptr<StreamSocket> sock_;
};

} // end namespace qedis

#endif //endif BERT_ZOOKEEPERCONN_H



================================================
FILE: QSentinel/zookeeper/proto.h
================================================
/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef PROTO_H_
#define PROTO_H_

#ifdef __cplusplus
extern "C" {
#endif


const int ZOO_EPHEMERAL = 1 << 0;
const int ZOO_SEQUENCE = 1 << 1;

#define ZOO_NOTIFY_OP 0
#define ZOO_CREATE_OP 1
#define ZOO_DELETE_OP 2
#define ZOO_EXISTS_OP 3
#define ZOO_GETDATA_OP 4
#define ZOO_SETDATA_OP 5
#define ZOO_GETACL_OP 6
#define ZOO_SETACL_OP 7
#define ZOO_GETCHILDREN_OP 8
#define ZOO_SYNC_OP 9
#define ZOO_PING_OP 11
#define ZOO_GETCHILDREN2_OP 12
#define ZOO_CHECK_OP 13
#define ZOO_MULTI_OP 14
#define ZOO_CLOSE_OP -11
#define ZOO_SETAUTH_OP 100
#define ZOO_SETWATCHES_OP 101


/* the size of connect request */
#define HANDSHAKE_REQ_SIZE 44
/* connect request */
struct connect_req {
    int32_t protocolVersion;
    int64_t lastZxidSeen;
    int32_t timeOut;
    int64_t sessionId;
    int32_t passwd_len;
    char passwd[16];
};

#define HANDSHAKE_RSP_SIZE 40
/* the connect response */
struct prime_struct {
    int32_t len;
    int32_t protocolVersion;
    int32_t timeOut;
    int64_t sessionId;
    int32_t passwd_len;
    char passwd[16];
}; 

enum ZOO_ERRORS {
  ZOK = 0, /*!< Everything is OK */

  /** System and server-side errors.
   * This is never thrown by the server, it shouldn't be used other than
   * to indicate a range. Specifically error codes greater than this
   * value, but lesser than {@link #ZAPIERROR}, are system errors. */
  ZSYSTEMERROR = -1,
  ZRUNTIMEINCONSISTENCY = -2, /*!< A runtime inconsistency was found */
  ZDATAINCONSISTENCY = -3, /*!< A data inconsistency was found */
  ZCONNECTIONLOSS = -4, /*!< Connection to the server has been lost */
  ZMARSHALLINGERROR = -5, /*!< Error while marshalling or unmarshalling data */
  ZUNIMPLEMENTED = -6, /*!< Operation is unimplemented */
  ZOPERATIONTIMEOUT = -7, /*!< Operation timeout */
  ZBADARGUMENTS = -8, /*!< Invalid arguments */
  ZINVALIDSTATE = -9, /*!< Invliad zhandle state */

  /** API errors.
   * This is never thrown by the server, it shouldn't be used other than
   * to indicate a range. Specifically error codes greater than this
   * value are API errors (while values less than this indicate a 
   * {@link #ZSYSTEMERROR}).
   */
  ZAPIERROR = -100,
  ZNONODE = -101, /*!< Node does not exist */
  ZNOAUTH = -102, /*!< Not authenticated */
  ZBADVERSION = -103, /*!< Version conflict */
  ZNOCHILDRENFOREPHEMERALS = -108, /*!< Ephemeral nodes may not have children */
  ZNODEEXISTS = -110, /*!< The node already exists */
  ZNOTEMPTY = -111, /*!< The node has children */
  ZSESSIONEXPIRED = -112, /*!< The session has been expired by the server */
  ZINVALIDCALLBACK = -113, /*!< Invalid callback specified */
  ZINVALIDACL = -114, /*!< Invalid ACL specified */
  ZAUTHFAILED = -115, /*!< Client authentication failed */
  ZCLOSING = -116, /*!< ZooKeeper is closing */
  ZNOTHING = -117, /*!< (not error) no server responses to process */
  ZSESSIONMOVED = -118 /*!<session moved to another server, so operation is ignored */ 
};

static const int WATCHER_EVENT_XID = -1;
static const int PING_XID = -2;
static const int AUTH_XID = -4;
static const int SET_WATCHES_XID = -8;

/* zookeeper event type constants */
#define CREATED_EVENT_DEF 1
#define DELETED_EVENT_DEF 2
#define CHANGED_EVENT_DEF 3
#define CHILD_EVENT_DEF 4
#define SESSION_EVENT_DEF -1
#define NOTWATCHING_EVENT_DEF -2


/* zookeeper state constants */
#define EXPIRED_SESSION_STATE_DEF -112
#define AUTH_FAILED_STATE_DEF -113
#define CONNECTING_STATE_DEF 1
#define ASSOCIATING_STATE_DEF 2
#define CONNECTED_STATE_DEF 3
#define NOTCONNECTED_STATE_DEF 999


#ifdef __cplusplus
}
#endif

#endif /*PROTO_H_*/


================================================
FILE: QSentinel/zookeeper/recordio.c
================================================
/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "recordio.h"
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <netinet/in.h>

void deallocate_String(char **s)
{
    if (*s)
        free(*s);
    *s = 0;
}

void deallocate_Buffer(struct buffer *b)
{
    if (b->buff)
        free(b->buff);
    b->buff = 0;
}

struct buff_struct {
    int32_t len;
    int32_t off;
    char *buffer;
};

static int resize_buffer(struct buff_struct *s, int newlen)
{
    char *buffer= NULL;
    while (s->len < newlen) {
        s->len *= 2;
    }
    buffer = (char*)realloc(s->buffer, s->len);
    if (!buffer) {
        s->buffer = 0;
        return -ENOMEM;
    }
    s->buffer = buffer;
    return 0;
}

int oa_start_record(struct oarchive *oa, const char *tag)
{
    return 0;
}
int oa_end_record(struct oarchive *oa, const char *tag)
{
    return 0;
}
int oa_serialize_int(struct oarchive *oa, const char *tag, const int32_t *d)
{
    struct buff_struct *priv = oa->priv;
    int32_t i = htonl(*d);
    if ((priv->len - priv->off) < sizeof(i)) {
        int rc = resize_buffer(priv, priv->len + sizeof(i));
        if (rc < 0) return rc;
    }
    memcpy(priv->buffer+priv->off, &i, sizeof(i));
    priv->off+=sizeof(i);
    return 0;
}
#ifndef __APPLE__
int64_t htonll(int64_t v)
{
    int i = 0;
    char *s = (char *)&v;
    if (htonl(1) == 1) {
        return v;
    }
    for (i = 0; i < 4; i++) {
        int tmp = s[i];
        s[i] = s[8-i-1];
        s[8-i-1] = tmp;
    }

    return v;
}
#endif

int oa_serialize_long(struct oarchive *oa, const char *tag, const int64_t *d)
{
    const int64_t i = htonll(*d);
    struct buff_struct *priv = oa->priv;
    if ((priv->len - priv->off) < sizeof(i)) {
        int rc = resize_buffer(priv, priv->len + sizeof(i));
        if (rc < 0) return rc;
    }
    memcpy(priv->buffer+priv->off, &i, sizeof(i));
    priv->off+=sizeof(i);
    return 0;
}
int oa_start_vector(struct oarchive *oa, const char *tag, const int32_t *count)
{
    return oa_serialize_int(oa, tag, count);
}
int oa_end_vector(struct oarchive *oa, const char *tag)
{
    return 0;
}
int oa_serialize_bool(struct oarchive *oa, const char *name, const int32_t *i)
{
    //return oa_serialize_int(oa, name, i);
    struct buff_struct *priv = oa->priv;
    if ((priv->len - priv->off) < 1) {
        int rc = resize_buffer(priv, priv->len + 1);
        if (rc < 0)
            return rc;
    }
    priv->buffer[priv->off] = (*i == 0 ? '\0' : '\1');
    priv->off++;
    return 0;
}
static const int32_t negone = -1;
int oa_serialize_buffer(struct oarchive *oa, const char *name,
        const struct buffer *b)
{
    struct buff_struct *priv = oa->priv;
    int rc;
    if (!b) {
        return oa_serialize_int(oa, "len", &negone);
    }
    rc = oa_serialize_int(oa, "len", &b->len);
    if (rc < 0)
        return rc;
    // this means a buffer of NUll 
    // with size of -1. This is 
    // waht we use in java serialization for NULL
    if (b->len == -1) {
      return rc;
    }
    if ((priv->len - priv->off) < b->len) {
        rc = resize_buffer(priv, priv->len + b->len);
        if (rc < 0)
            return rc;
    }
    memcpy(priv->buffer+priv->off, b->buff, b->len);
    priv->off += b->len;
    return 0;
}
int oa_serialize_string(struct oarchive *oa, const char *name, char **s)
{
    struct buff_struct *priv = oa->priv;
    int32_t len;
    int rc;
    if (!*s) {
        oa_serialize_int(oa, "len", &negone);
        return 0;
    }
    len = strlen(*s);
    rc = oa_serialize_int(oa, "len", &len);
    if (rc < 0)
        return rc;
    if ((priv->len - priv->off) < len) {
        rc = resize_buffer(priv, priv->len + len);
        if (rc < 0)
            return rc;
    }
    memcpy(priv->buffer+priv->off, *s, len);
    priv->off += len;
    return 0;
}
int ia_start_record(struct iarchive *ia, const char *tag)
{
    return 0;
}
int ia_end_record(struct iarchive *ia, const char *tag)
{
    return 0;
}
int ia_deserialize_int(struct iarchive *ia, const char *tag, int32_t *count)
{
    struct buff_struct *priv = ia->priv;
    if ((priv->len - priv->off) < sizeof(*count)) {
        return -E2BIG;
    }
    memcpy(count, priv->buffer+priv->off, sizeof(*count));
    priv->off+=sizeof(*count);
    *count = ntohl(*count);
    return 0;
}

int ia_deserialize_long(struct iarchive *ia, const char *tag, int64_t *count)
{
    struct buff_struct *priv = ia->priv;
    int64_t v = 0;
    if ((priv->len - priv->off) < sizeof(*count)) {
        return -E2BIG;
    }
    memcpy(count, priv->buffer+priv->off, sizeof(*count));
    priv->off+=sizeof(*count);
    v = htonll(*count); // htonll and  ntohll do the same
    *count = v;
    return 0;
}
int ia_start_vector(struct iarchive *ia, const char *tag, int32_t *count)
{
    return ia_deserialize_int(ia, tag, count);
}
int ia_end_vector(struct iarchive *ia, const char *tag)
{
    return 0;
}
int ia_deserialize_bool(struct iarchive *ia, const char *name, int32_t *v)
{
    struct buff_struct *priv = ia->priv;
    //fprintf(stderr, "Deserializing bool %d\n", priv->off);
    //return ia_deserialize_int(ia, name, v);
    if ((priv->len - priv->off) < 1) {
        return -E2BIG;
    }
    *v = priv->buffer[priv->off];
    priv->off+=1;
    //fprintf(stderr, "Deserializing bool end %d\n", priv->off);
    return 0;
}
int ia_deserialize_buffer(struct iarchive *ia, const char *name,
        struct buffer *b)
{
    struct buff_struct *priv = ia->priv;
    int rc = ia_deserialize_int(ia, "len", &b->len);
    if (rc < 0)
        return rc;
    if ((priv->len - priv->off) < b->len) {
        return -E2BIG;
    }
    // set the buffer to null
    if (b->len == -1) {
       b->buff = NULL;
       return rc;
    }
    b->buff = malloc(b->len);
    if (!b->buff) {
        return -ENOMEM;
    }
    memcpy(b->buff, priv->buffer+priv->off, b->len);
    priv->off += b->len;
    return 0;
}
int ia_deserialize_string(struct iarchive *ia, const char *name, char **s)
{
    struct buff_struct *priv = ia->priv;
    int32_t len;
    int rc = ia_deserialize_int(ia, "len", &len);
    if (rc < 0)
        return rc;
    if ((priv->len - priv->off) < len) {
        return -E2BIG;
    }
    if (len < 0) {
        return -EINVAL;
    }
    *s = malloc(len+1);
    if (!*s) {
        return -ENOMEM;
    }
    memcpy(*s, priv->buffer+priv->off, len);
    (*s)[len] = '\0';
    priv->off += len;
    return 0;
}

static struct iarchive ia_default = { STRUCT_INITIALIZER (start_record ,ia_start_record),
        STRUCT_INITIALIZER (end_record ,ia_end_record), STRUCT_INITIALIZER (start_vector , ia_start_vector),
        STRUCT_INITIALIZER (end_vector ,ia_end_vector), STRUCT_INITIALIZER (deserialize_Bool , ia_deserialize_bool),
        STRUCT_INITIALIZER (deserialize_Int ,ia_deserialize_int),
        STRUCT_INITIALIZER (deserialize_Long , ia_deserialize_long) ,
        STRUCT_INITIALIZER (deserialize_Buffer, ia_deserialize_buffer),
        STRUCT_INITIALIZER (deserialize_String, ia_deserialize_string)   };

static struct oarchive oa_default = { STRUCT_INITIALIZER (start_record , oa_start_record),
        STRUCT_INITIALIZER (end_record , oa_end_record), STRUCT_INITIALIZER (start_vector , oa_start_vector),
        STRUCT_INITIALIZER (end_vector , oa_end_vector), STRUCT_INITIALIZER (serialize_Bool , oa_serialize_bool),
        STRUCT_INITIALIZER (serialize_Int , oa_serialize_int),
        STRUCT_INITIALIZER (serialize_Long , oa_serialize_long) ,
        STRUCT_INITIALIZER (serialize_Buffer , oa_serialize_buffer),
        STRUCT_INITIALIZER (serialize_String , oa_serialize_string) };

struct iarchive *create_buffer_iarchive(char *buffer, int len)
{
    struct iarchive *ia = malloc(sizeof(*ia));
    struct buff_struct *buff = malloc(sizeof(struct buff_struct));
    if (!ia) return 0;
    if (!buff) {
        free(ia);
        return 0;
    }
    *ia = ia_default;
    buff->off = 0;
    buff->buffer = buffer;
    buff->len = len;
    ia->priv = buff;
    return ia;
}

struct oarchive *create_buffer_oarchive()
{
    struct oarchive *oa = malloc(sizeof(*oa));
    struct buff_struct *buff = malloc(sizeof(struct buff_struct));
    if (!oa) return 0;
    if (!buff) {
        free(oa);
        return 0;
    }
    *oa = oa_default;
    buff->off = 0;
    buff->buffer = malloc(128);
    buff->len = 128;
    oa->priv = buff;
    return oa;
}

void close_buffer_iarchive(struct iarchive **ia)
{
    free((*ia)->priv);
    free(*ia);
    *ia = 0;
}

void close_buffer_oarchive(struct oarchive **oa, int free_buffer)
{
    if (free_buffer) {
        struct buff_struct *buff = (struct buff_struct *)(*oa)->priv;
        if (buff->buffer) {
            free(buff->buffer);
        }
    }
    free((*oa)->priv);
    free(*oa);
    *oa = 0;
}

char *get_buffer(struct oarchive *oa)
{
    struct buff_struct *buff = oa->priv;
    return buff->buffer;
}
int get_buffer_len(struct oarchive *oa)
{
    struct buff_struct *buff = oa->priv;
    return buff->off;
}


================================================
FILE: QSentinel/zookeeper/recordio.h
================================================
/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef __RECORDIO_H__
#define __RECORDIO_H__

#include <sys/types.h>
#define STRUCT_INITIALIZER(l,r) .l = r

#ifdef __cplusplus
extern "C" {
#endif

struct buffer {
    int32_t len;
    char *buff;
};

void deallocate_String(char **s);
void deallocate_Buffer(struct buffer *b);
void deallocate_vector(void *d);
struct iarchive {
    int (*start_record)(struct iarchive *ia, const char *tag);
    int (*end_record)(struct iarchive *ia, const char *tag);
    int (*start_vector)(struct iarchive *ia, const char *tag, int32_t *count);
    int (*end_vector)(struct iarchive *ia, const char *tag);
    int (*deserialize_Bool)(struct iarchive *ia, const char *name, int32_t *);
    int (*deserialize_Int)(struct iarchive *ia, const char *name, int32_t *);
    int (*deserialize_Long)(struct iarchive *ia, const char *name, int64_t *);
    int (*deserialize_Buffer)(struct iarchive *ia, const char *name,
            struct buffer *);
    int (*deserialize_String)(struct iarchive *ia, const char *name, char **);
    void *priv;
};
struct oarchive {
    int (*start_record)(struct oarchive *oa, const char *tag);
    int (*end_record)(struct oarchive *oa, const char *tag);
    int (*start_vector)(struct oarchive *oa, const char *tag, const int32_t *count);
    int (*end_vector)(struct oarchive *oa, const char *tag);
    int (*serialize_Bool)(struct oarchive *oa, const char *name, const int32_t *);
    int (*serialize_Int)(struct oarchive *oa, const char *name, const int32_t *);
    int (*serialize_Long)(struct oarchive *oa, const char *name,
            const int64_t *);
    int (*serialize_Buffer)(struct oarchive *oa, const char *name,
            const struct buffer *);
    int (*serialize_String)(struct oarchive *oa, const char *name, char **);
    void *priv;
};

struct oarchive *create_buffer_oarchive(void);
void close_buffer_oarchive(struct oarchive **oa, int free_buffer);
struct iarchive *create_buffer_iarchive(char *buffer, int len);
void close_buffer_iarchive(struct iarchive **ia);
char *get_buffer(struct oarchive *);
int get_buffer_len(struct oarchive *);

#if defined(__APPLE__)
#else
int64_t htonll(int64_t v);
#endif

#ifdef __cplusplus
}
#endif

#endif


================================================
FILE: QSentinel/zookeeper/zookeeper.jute.c
================================================
/**
* Licensed to the Apac
Download .txt
gitextract_0j0gzhnc/

├── .gitignore
├── .travis.yml
├── CMakeCommon
├── CMakeLists.txt
├── LICENSE
├── Makefile
├── Modules/
│   ├── CMakeLists.txt
│   ├── QHashModule.cc
│   ├── QHashModule.h
│   ├── QListModule.cc
│   ├── QListModule.h
│   ├── QModuleInit.cc
│   ├── QModuleInit.h
│   ├── QSetModule.cc
│   └── QSetModule.h
├── QBase/
│   ├── AsyncBuffer.cc
│   ├── AsyncBuffer.h
│   ├── Buffer.h
│   ├── CMakeLists.txt
│   ├── ClientSocket.cc
│   ├── ClientSocket.h
│   ├── ConfigParser.cc
│   ├── ConfigParser.h
│   ├── Delegate.h
│   ├── EPoller.cc
│   ├── EPoller.h
│   ├── Kqueue.cc
│   ├── Kqueue.h
│   ├── ListenSocket.cc
│   ├── ListenSocket.h
│   ├── Log/
│   │   ├── Logger.cc
│   │   ├── Logger.h
│   │   ├── MemoryFile.cc
│   │   └── MemoryFile.h
│   ├── NetThreadPool.cc
│   ├── NetThreadPool.h
│   ├── Poller.h
│   ├── README.md
│   ├── Server.cc
│   ├── Server.h
│   ├── Socket.cc
│   ├── Socket.h
│   ├── StreamSocket.cc
│   ├── StreamSocket.h
│   ├── TaskManager.cc
│   ├── TaskManager.h
│   ├── Threads/
│   │   ├── ThreadPool.cc
│   │   └── ThreadPool.h
│   ├── Timer.cc
│   ├── Timer.h
│   ├── UnboundedBuffer.cc
│   ├── UnboundedBuffer.h
│   └── lzf/
│       ├── lzf.h
│       ├── lzfP.h
│       ├── lzf_c.c
│       └── lzf_d.c
├── QSentinel/
│   ├── CMakeLists.txt
│   ├── QClusterClient.cc
│   ├── QClusterClient.h
│   ├── QClusterInterface.h
│   ├── README.md
│   └── zookeeper/
│       ├── ZookeeperConn.cc
│       ├── ZookeeperConn.h
│       ├── proto.h
│       ├── recordio.c
│       ├── recordio.h
│       ├── zookeeper.jute.c
│       ├── zookeeper.jute.h
│       └── zookeeper_version.h
├── Qedis.xcodeproj/
│   └── project.pbxproj
├── QedisCore/
│   ├── CMakeLists.txt
│   ├── QAOF.cc
│   ├── QAOF.h
│   ├── QClient.cc
│   ├── QClient.h
│   ├── QCommand.cc
│   ├── QCommand.h
│   ├── QCommon.cc
│   ├── QCommon.h
│   ├── QConfig.cc
│   ├── QConfig.h
│   ├── QDB.cc
│   ├── QDB.h
│   ├── QDumpInterface.h
│   ├── QGlobRegex.cc
│   ├── QGlobRegex.h
│   ├── QHash.cc
│   ├── QHash.h
│   ├── QHelper.cc
│   ├── QHelper.h
│   ├── QKeyCommand.cc
│   ├── QLeveldb.cc
│   ├── QLeveldb.h
│   ├── QList.cc
│   ├── QList.h
│   ├── QMigration.cc
│   ├── QMigration.h
│   ├── QModule.cc
│   ├── QModule.h
│   ├── QMulti.cc
│   ├── QMulti.h
│   ├── QProtoParser.cc
│   ├── QProtoParser.h
│   ├── QPubsub.cc
│   ├── QPubsub.h
│   ├── QReplication.cc
│   ├── QReplication.h
│   ├── QServerCommand.cc
│   ├── QSet.cc
│   ├── QSet.h
│   ├── QSlaveClient.cc
│   ├── QSlaveClient.h
│   ├── QSlowLog.cc
│   ├── QSlowLog.h
│   ├── QSortedSet.cc
│   ├── QSortedSet.h
│   ├── QStore.cc
│   ├── QStore.h
│   ├── QString.cc
│   ├── QString.h
│   ├── crc64.c
│   ├── redisIntset.c
│   ├── redisIntset.h
│   ├── redisZipList.c
│   └── redisZipList.h
├── QedisSvr/
│   ├── CMakeLists.txt
│   ├── Qedis.cc
│   ├── Qedis.h
│   └── QedisLogo.h
├── README.md
├── README.zh.md
├── UnitTest/
│   ├── CMakeLists.txt
│   ├── QGlobRegex_unittest.cc
│   ├── UnitTest.cc
│   └── UnitTest.h
├── cluster/
│   ├── .gitignore
│   ├── CMakeCommon
│   ├── CMakeLists.txt
│   ├── Makefile
│   ├── README.md
│   ├── ananas/
│   │   ├── CMakeLists.txt
│   │   ├── future/
│   │   │   ├── Future.h
│   │   │   ├── Helper.h
│   │   │   └── Try.h
│   │   ├── net/
│   │   │   ├── Acceptor.cc
│   │   │   ├── Acceptor.h
│   │   │   ├── AnanasDebug.cc
│   │   │   ├── AnanasDebug.h
│   │   │   ├── AnanasLogo.h
│   │   │   ├── Buffer.cc
│   │   │   ├── Buffer.h
│   │   │   ├── CMakeLists.txt
│   │   │   ├── Connection.cc
│   │   │   ├── Connection.h
│   │   │   ├── Connector.cc
│   │   │   ├── Connector.h
│   │   │   ├── DatagramSocket.cc
│   │   │   ├── DatagramSocket.h
│   │   │   ├── Epoller.cc
│   │   │   ├── Epoller.h
│   │   │   ├── EventLoop.cc
│   │   │   ├── EventLoop.h
│   │   │   ├── Kqueue.cc
│   │   │   ├── Kqueue.h
│   │   │   ├── Poller.h
│   │   │   ├── Socket.cc
│   │   │   ├── Socket.h
│   │   │   ├── ThreadPool.cc
│   │   │   ├── ThreadPool.h
│   │   │   ├── TimeUtil.cc
│   │   │   ├── TimeUtil.h
│   │   │   ├── Timer.cc
│   │   │   ├── Timer.h
│   │   │   ├── Typedefs.h
│   │   │   └── log/
│   │   │       ├── Logger.cc
│   │   │       ├── Logger.h
│   │   │       ├── MmapFile.cc
│   │   │       ├── MmapFile.h
│   │   │       └── README.md
│   │   └── util/
│   │       ├── Delegate.h
│   │       ├── Scheduler.h
│   │       └── Util.h
│   ├── cluster_conn/
│   │   ├── CMakeLists.txt
│   │   ├── ClusterConn.h
│   │   └── zookeeper/
│   │       ├── CMakeLists.txt
│   │       ├── ZkResponse.h
│   │       ├── ZookeeperContext.cc
│   │       ├── ZookeeperContext.h
│   │       ├── proto.h
│   │       ├── recordio.c
│   │       ├── recordio.h
│   │       ├── zookeeper.jute.c
│   │       └── zookeeper.jute.h
│   └── qedis_proxy/
│       ├── CMakeLists.txt
│       ├── ClientConn.cc
│       ├── ClientConn.h
│       ├── ClientManager.cc
│       ├── ClientManager.h
│       ├── ClusterManager.cc
│       ├── ClusterManager.h
│       ├── Command.cc
│       ├── Command.h
│       ├── ConfigParser.cc
│       ├── ConfigParser.h
│       ├── Protocol.cc
│       ├── Protocol.h
│       ├── ProxyConfig.cc
│       ├── ProxyConfig.h
│       ├── ProxyLog.h
│       ├── QedisConn.cc
│       ├── QedisConn.h
│       ├── QedisManager.cc
│       ├── QedisManager.h
│       ├── ZookeeperConn.cc
│       ├── ZookeeperConn.h
│       └── main.cc
└── qedis.conf
Download .txt
SYMBOL INDEX (1981 symbols across 179 files)

FILE: Modules/QHashModule.cc
  function QError (line 8) | QError hgets(const std::vector<QString>& params, UnboundedBuffer* reply)

FILE: Modules/QHashModule.h
  function namespace (line 8) | namespace qedis

FILE: Modules/QListModule.cc
  function QError (line 9) | QError ldel(const std::vector<QString>& params, UnboundedBuffer* reply)

FILE: Modules/QListModule.h
  function namespace (line 8) | namespace qedis

FILE: Modules/QModuleInit.cc
  function QedisModule_OnLoad (line 14) | bool QedisModule_OnLoad()
  function QedisModule_OnUnLoad (line 61) | void QedisModule_OnUnLoad()

FILE: Modules/QSetModule.cc
  function QError (line 8) | QError skeys(const std::vector<QString>& params, UnboundedBuffer* reply)

FILE: Modules/QSetModule.h
  function namespace (line 8) | namespace qedis

FILE: QBase/AsyncBuffer.h
  function class (line 10) | class AsyncBuffer

FILE: QBase/Buffer.h
  type BufferSequence (line 13) | struct BufferSequence
  function RoundUp2Power (line 34) | inline std::size_t RoundUp2Power(std::size_t size)
  type CircularBuffer (line 420) | typedef CircularBuffer< ::std::vector<char> >  Buffer;
  type CircularBuffer (line 447) | typedef CircularBuffer<char* > AttachedBuffer;
  function AttachedBuffer (line 460) | inline AttachedBuffer::CircularBuffer(const BufferSequence& bf) :

FILE: QBase/ClientSocket.h
  function class (line 9) | class ClientSocket : public Socket

FILE: QBase/ConfigParser.cc
  function SkipBlank (line 11) | static size_t  SkipBlank(const char* data, size_t len, size_t off)
  function main (line 117) | int main()

FILE: QBase/ConfigParser.h
  function class (line 12) | class ConfigParser
  function T (line 47) | T  ConfigParser::_ToType(const std::string& data) const
  function T (line 69) | T  ConfigParser::GetData(const char* key, const T& default_) const

FILE: QBase/Delegate.h
  function call (line 86) | void call(Args&&... args)

FILE: QBase/EPoller.cc
  type Epoll (line 10) | namespace Epoll
    function AddSocket (line 14) | bool AddSocket(int epfd, int socket, uint32_t events, void* ptr)
    function DelSocket (line 31) | bool DelSocket(int epfd, int socket)
    function ModSocket (line 41) | bool ModSocket(int epfd, int socket, uint32_t events, void* ptr)

FILE: QBase/EPoller.h
  function class (line 10) | class Epoller : public Poller

FILE: QBase/Kqueue.cc
  type kevent (line 26) | struct kevent
  type kevent (line 47) | struct kevent
  type timespec (line 87) | struct timespec
  type timespec (line 88) | struct timespec

FILE: QBase/Kqueue.h
  function class (line 9) | class Kqueue : public Poller

FILE: QBase/ListenSocket.cc
  type Internal (line 12) | namespace Internal
    type sockaddr_in (line 46) | struct sockaddr_in
    type sockaddr (line 48) | struct sockaddr
    type sockaddr (line 78) | struct sockaddr

FILE: QBase/ListenSocket.h
  function namespace (line 7) | namespace Internal

FILE: QBase/Log/Logger.cc
  type LogColor (line 11) | enum LogColor
  function ConvertLogLevel (line 31) | unsigned int ConvertLogLevel(const std::string& level)
  function MakeDir (line 62) | static bool MakeDir(const char* pDir)
  type LogLevel (line 153) | enum LogLevel
  function Logger (line 258) | Logger&  Logger::operator<< (const char* msg)
  function Logger (line 277) | Logger&  Logger::operator<< (const unsigned char* msg)
  function Logger (line 282) | Logger&  Logger::operator<< (const std::string& msg)
  function Logger (line 287) | Logger&  Logger::operator<< (void* ptr)
  function Logger (line 305) | Logger&  Logger::operator<< (unsigned char a)
  function Logger (line 322) | Logger&  Logger::operator<< (char a)
  function Logger (line 337) | Logger&  Logger::operator<< (unsigned short a)
  function Logger (line 352) | Logger&  Logger::operator<< (short a)
  function Logger (line 367) | Logger&  Logger::operator<< (unsigned int a)
  function Logger (line 382) | Logger&  Logger::operator<< (int a)
  function Logger (line 397) | Logger&  Logger::operator<< (unsigned long a)
  function Logger (line 412) | Logger&  Logger::operator<< (long a)
  function Logger (line 427) | Logger&  Logger::operator<< (unsigned long long a)
  function Logger (line 442) | Logger&  Logger::operator<< (long long a)
  function Logger (line 457) | Logger&  Logger::operator<< (double a)
  function Logger (line 573) | Logger& LogHelper::operator=(Logger& log)
  function LogManager (line 581) | LogManager& LogManager::Instance()
  function Logger (line 601) | Logger*  LogManager::CreateLog(unsigned int level ,

FILE: QBase/Log/Logger.h
  type LogLevel (line 13) | enum LogLevel
  type LogDest (line 23) | enum LogDest
  function class (line 32) | class Logger
  function class (line 109) | class LogHelper
  function class (line 121) | class LogManager

FILE: QBase/Log/MemoryFile.cc
  type stat (line 36) | struct stat
  type stat (line 158) | struct stat

FILE: QBase/Log/MemoryFile.h
  function class (line 7) | class InputMemoryFile
  function T (line 36) | T InputMemoryFile::Read()
  function class (line 47) | class OutputMemoryFile
  function Write (line 84) | void OutputMemoryFile::Write(const T& t)

FILE: QBase/NetThreadPool.cc
  type Internal (line 19) | namespace Internal

FILE: QBase/NetThreadPool.h
  function GetCpuNum (line 13) | inline long GetCpuNum()
  type std (line 19) | typedef std::shared_ptr<Socket> PSOCKET;
  function namespace (line 21) | namespace Internal

FILE: QBase/Poller.h
  type EventType (line 6) | enum EventType
  type FiredEvent (line 13) | struct FiredEvent

FILE: QBase/Server.cc
  type sigaction (line 103) | struct sigaction

FILE: QBase/Server.h
  type SocketAddr (line 9) | struct SocketAddr
  function class (line 11) | class Server    // Should singleton

FILE: QBase/Socket.cc
  type sockaddr (line 109) | struct sockaddr
  type sockaddr (line 125) | struct sockaddr
  type ifconf (line 140) | struct ifconf
  type ifreq (line 146) | struct ifreq
  type ifreq (line 147) | struct ifreq
  type sockaddr_in (line 159) | struct sockaddr_in
  type sockaddr_in (line 159) | struct sockaddr_in

FILE: QBase/Socket.h
  function SocketAddr (line 17) | struct SocketAddr
  function Init (line 62) | void Init(const sockaddr_in& addr)
  function Init (line 67) | void Init(uint32_t netip, uint16_t netport)
  function Init (line 74) | void Init(const char* ip, uint16_t hostport)
  function Clear (line 113) | void  Clear()       { memset(&addr_, 0, sizeof addr_); }
  function namespace (line 131) | namespace std
  function namespace (line 150) | namespace Internal
  function class (line 156) | class Socket : public std::enable_shared_from_this<Socket>

FILE: QBase/StreamSocket.h
  function class (line 13) | class StreamSocket : public Socket
  function SendPacket (line 70) | bool  StreamSocket::SendPacket(StackBuffer<N>& sf)

FILE: QBase/TaskManager.cc
  type Internal (line 6) | namespace Internal

FILE: QBase/TaskManager.h
  function namespace (line 12) | namespace Internal

FILE: QBase/Threads/ThreadPool.cc
  function ThreadPool (line 17) | ThreadPool& ThreadPool::Instance()

FILE: QBase/Threads/ThreadPool.h
  function task (line 59) | auto task = std::make_shared<std::packaged_task<resultType ()> >(std::bi...

FILE: QBase/Timer.cc
  function Now (line 7) | uint64_t Now()
  function IsLeapYear (line 14) | static bool  IsLeapYear(int year)
  function DaysOfMonth (line 20) | static int DaysOfMonth(int year, int month)
  type tm (line 81) | struct tm
  function Time (line 167) | Time& Time::operator= (const Time & other)
  function TimerManager (line 274) | TimerManager&  TimerManager::Instance()
  function Timer (line 280) | Timer* TimerManager::CreateTimer()

FILE: QBase/Timer.h
  function class (line 17) | class Time
  function class (line 48) | class Timer
  function class (line 75) | class TimerManager
  function _Index (line 121) | inline int TimerManager::_Index(int level)

FILE: QBase/UnboundedBuffer.cc
  type qedis (line 7) | namespace qedis
    function main (line 137) | int main()

FILE: QBase/UnboundedBuffer.h
  function namespace (line 8) | namespace qedis

FILE: QBase/lzf/lzfP.h
  type u8 (line 127) | typedef unsigned char u8;
  type u8 (line 129) | typedef const u8 *LZF_STATE[1 << (HLOG)];
  type u16 (line 135) | typedef unsigned short u16;
  type u16 (line 137) | typedef unsigned int u16;

FILE: QBase/lzf/lzf_c.c
  function lzf_compress (line 98) | unsigned int

FILE: QBase/lzf/lzf_d.c
  function lzf_decompress (line 55) | unsigned int

FILE: QSentinel/QClusterClient.cc
  type qedis (line 14) | namespace qedis
    function PacketLength (line 17) | PacketLength QClusterClient::_HandlePacket(const char* data, std::size...

FILE: QSentinel/QClusterClient.h
  function namespace (line 9) | namespace ConnectionTag
  function namespace (line 15) | namespace qedis

FILE: QSentinel/QClusterInterface.h
  function namespace (line 12) | namespace ConnectionTag
  function namespace (line 17) | namespace qedis

FILE: QSentinel/zookeeper/ZookeeperConn.cc
  function deserialize_prime_response (line 11) | static int deserialize_prime_response(struct prime_struct* req, Attached...
  type qedis (line 35) | namespace qedis
    type prime_struct (line 66) | struct prime_struct
    type ReplyHeader (line 86) | struct ReplyHeader
    type iarchive (line 87) | struct iarchive
    type connect_req (line 129) | struct connect_req
    type ACL (line 162) | struct ACL
    type ACL_vector (line 167) | struct ACL_vector
    function MakeParentNode (line 170) | static std::string MakeParentNode(int setid)
    function MakeNodePath (line 179) | static std::string MakeNodePath(int setid, const std::string& addr)
    function GetNodeSeq (line 187) | static int GetNodeSeq(const std::string& path)
    function GetNodeAddr (line 198) | static std::string GetNodeAddr(const std::string& path)
    type oarchive (line 214) | struct oarchive
    type RequestHeader (line 215) | struct RequestHeader
    type CreateRequest (line 222) | struct CreateRequest
    type oarchive (line 284) | struct oarchive
    type RequestHeader (line 285) | struct RequestHeader
    type WatcherEvent (line 309) | struct WatcherEvent
    type oarchive (line 562) | struct oarchive
    type RequestHeader (line 564) | struct RequestHeader
    type GetChildren2Request (line 565) | struct GetChildren2Request
    type oarchive (line 580) | struct oarchive
    type RequestHeader (line 582) | struct RequestHeader
    type GetDataRequest (line 583) | struct GetDataRequest
    type oarchive (line 599) | struct oarchive
    type RequestHeader (line 601) | struct RequestHeader
    type ExistsRequest (line 602) | struct ExistsRequest
    type oarchive (line 615) | struct oarchive

FILE: QSentinel/zookeeper/ZookeeperConn.h
  type prime_struct (line 9) | struct prime_struct
  type RequestHeader (line 10) | struct RequestHeader
  type ReplyHeader (line 11) | struct ReplyHeader
  type iarchive (line 12) | struct iarchive
  type oarchive (line 13) | struct oarchive
  function class (line 20) | class ZookeeperConn : public QClusterConn

FILE: QSentinel/zookeeper/proto.h
  type connect_req (line 51) | struct connect_req {
  type prime_struct (line 62) | struct prime_struct {
  type ZOO_ERRORS (line 71) | enum ZOO_ERRORS {

FILE: QSentinel/zookeeper/recordio.c
  function deallocate_String (line 26) | void deallocate_String(char **s)
  function deallocate_Buffer (line 33) | void deallocate_Buffer(struct buffer *b)
  type buff_struct (line 40) | struct buff_struct {
  function resize_buffer (line 46) | static int resize_buffer(struct buff_struct *s, int newlen)
  function oa_start_record (line 61) | int oa_start_record(struct oarchive *oa, const char *tag)
  function oa_end_record (line 65) | int oa_end_record(struct oarchive *oa, const char *tag)
  function oa_serialize_int (line 69) | int oa_serialize_int(struct oarchive *oa, const char *tag, const int32_t...
  function htonll (line 82) | int64_t htonll(int64_t v)
  function oa_serialize_long (line 99) | int oa_serialize_long(struct oarchive *oa, const char *tag, const int64_...
  function oa_start_vector (line 111) | int oa_start_vector(struct oarchive *oa, const char *tag, const int32_t ...
  function oa_end_vector (line 115) | int oa_end_vector(struct oarchive *oa, const char *tag)
  function oa_serialize_bool (line 119) | int oa_serialize_bool(struct oarchive *oa, const char *name, const int32...
  function oa_serialize_buffer (line 133) | int oa_serialize_buffer(struct oarchive *oa, const char *name,
  function oa_serialize_string (line 159) | int oa_serialize_string(struct oarchive *oa, const char *name, char **s)
  function ia_start_record (line 181) | int ia_start_record(struct iarchive *ia, const char *tag)
  function ia_end_record (line 185) | int ia_end_record(struct iarchive *ia, const char *tag)
  function ia_deserialize_int (line 189) | int ia_deserialize_int(struct iarchive *ia, const char *tag, int32_t *co...
  function ia_deserialize_long (line 201) | int ia_deserialize_long(struct iarchive *ia, const char *tag, int64_t *c...
  function ia_start_vector (line 214) | int ia_start_vector(struct iarchive *ia, const char *tag, int32_t *count)
  function ia_end_vector (line 218) | int ia_end_vector(struct iarchive *ia, const char *tag)
  function ia_deserialize_bool (line 222) | int ia_deserialize_bool(struct iarchive *ia, const char *name, int32_t *v)
  function ia_deserialize_buffer (line 235) | int ia_deserialize_buffer(struct iarchive *ia, const char *name,
  function ia_deserialize_string (line 258) | int ia_deserialize_string(struct iarchive *ia, const char *name, char **s)
  type iarchive (line 281) | struct iarchive
  type oarchive (line 289) | struct oarchive
  type iarchive (line 297) | struct iarchive
  type iarchive (line 299) | struct iarchive
  type buff_struct (line 300) | struct buff_struct
  type buff_struct (line 300) | struct buff_struct
  type oarchive (line 314) | struct oarchive
  type oarchive (line 316) | struct oarchive
  type buff_struct (line 317) | struct buff_struct
  type buff_struct (line 317) | struct buff_struct
  function close_buffer_iarchive (line 331) | void close_buffer_iarchive(struct iarchive **ia)
  function close_buffer_oarchive (line 338) | void close_buffer_oarchive(struct oarchive **oa, int free_buffer)
  type oarchive (line 351) | struct oarchive
  type buff_struct (line 353) | struct buff_struct
  function get_buffer_len (line 356) | int get_buffer_len(struct oarchive *oa)

FILE: QSentinel/zookeeper/recordio.h
  type buffer (line 28) | struct buffer {
  type buffer (line 34) | struct buffer
  type iarchive (line 36) | struct iarchive {
  type oarchive (line 49) | struct oarchive {
  type oarchive (line 64) | struct oarchive
  type oarchive (line 65) | struct oarchive
  type iarchive (line 66) | struct iarchive
  type iarchive (line 67) | struct iarchive
  type oarchive (line 68) | struct oarchive
  type oarchive (line 69) | struct oarchive

FILE: QSentinel/zookeeper/zookeeper.jute.c
  function serialize_Id (line 22) | int serialize_Id(struct oarchive *out, const char *tag, struct Id *v){
  function deserialize_Id (line 30) | int deserialize_Id(struct iarchive *in, const char *tag, struct Id*v){
  function deallocate_Id (line 38) | void deallocate_Id(struct Id*v){
  function serialize_ACL (line 42) | int serialize_ACL(struct oarchive *out, const char *tag, struct ACL *v){
  function deserialize_ACL (line 50) | int deserialize_ACL(struct iarchive *in, const char *tag, struct ACL*v){
  function deallocate_ACL (line 58) | void deallocate_ACL(struct ACL*v){
  function serialize_Stat (line 61) | int serialize_Stat(struct oarchive *out, const char *tag, struct Stat *v){
  function deserialize_Stat (line 78) | int deserialize_Stat(struct iarchive *in, const char *tag, struct Stat*v){
  function deallocate_Stat (line 95) | void deallocate_Stat(struct Stat*v){
  function serialize_StatPersisted (line 97) | int serialize_StatPersisted(struct oarchive *out, const char *tag, struc...
  function deserialize_StatPersisted (line 112) | int deserialize_StatPersisted(struct iarchive *in, const char *tag, stru...
  function deallocate_StatPersisted (line 127) | void deallocate_StatPersisted(struct StatPersisted*v){
  function serialize_StatPersistedV1 (line 129) | int serialize_StatPersistedV1(struct oarchive *out, const char *tag, str...
  function deserialize_StatPersistedV1 (line 143) | int deserialize_StatPersistedV1(struct iarchive *in, const char *tag, st...
  function deallocate_StatPersistedV1 (line 157) | void deallocate_StatPersistedV1(struct StatPersistedV1*v){
  function serialize_ConnectRequest (line 159) | int serialize_ConnectRequest(struct oarchive *out, const char *tag, stru...
  function deserialize_ConnectRequest (line 170) | int deserialize_ConnectRequest(struct iarchive *in, const char *tag, str...
  function deallocate_ConnectRequest (line 181) | void deallocate_ConnectRequest(struct ConnectRequest*v){
  function serialize_ConnectResponse (line 184) | int serialize_ConnectResponse(struct oarchive *out, const char *tag, str...
  function deserialize_ConnectResponse (line 194) | int deserialize_ConnectResponse(struct iarchive *in, const char *tag, st...
  function deallocate_ConnectResponse (line 204) | void deallocate_ConnectResponse(struct ConnectResponse*v){
  function allocate_String_vector (line 207) | int allocate_String_vector(struct String_vector *v, int32_t len) {
  function deallocate_String_vector (line 217) | int deallocate_String_vector(struct String_vector *v) {
  function serialize_String_vector (line 228) | int serialize_String_vector(struct oarchive *out, const char *tag, struc...
  function deserialize_String_vector (line 240) | int deserialize_String_vector(struct iarchive *in, const char *tag, stru...
  function serialize_SetWatches (line 252) | int serialize_SetWatches(struct oarchive *out, const char *tag, struct S...
  function deserialize_SetWatches (line 262) | int deserialize_SetWatches(struct iarchive *in, const char *tag, struct ...
  function deallocate_SetWatches (line 272) | void deallocate_SetWatches(struct SetWatches*v){
  function serialize_RequestHeader (line 277) | int serialize_RequestHeader(struct oarchive *out, const char *tag, struc...
  function deserialize_RequestHeader (line 285) | int deserialize_RequestHeader(struct iarchive *in, const char *tag, stru...
  function deallocate_RequestHeader (line 293) | void deallocate_RequestHeader(struct RequestHeader*v){
  function serialize_MultiHeader (line 295) | int serialize_MultiHeader(struct oarchive *out, const char *tag, struct ...
  function deserialize_MultiHeader (line 304) | int deserialize_MultiHeader(struct iarchive *in, const char *tag, struct...
  function deallocate_MultiHeader (line 313) | void deallocate_MultiHeader(struct MultiHeader*v){
  function serialize_AuthPacket (line 315) | int serialize_AuthPacket(struct oarchive *out, const char *tag, struct A...
  function deserialize_AuthPacket (line 324) | int deserialize_AuthPacket(struct iarchive *in, const char *tag, struct ...
  function deallocate_AuthPacket (line 333) | void deallocate_AuthPacket(struct AuthPacket*v){
  function serialize_ReplyHeader (line 337) | int serialize_ReplyHeader(struct oarchive *out, const char *tag, struct ...
  function deserialize_ReplyHeader (line 346) | int deserialize_ReplyHeader(struct iarchive *in, const char *tag, struct...
  function deallocate_ReplyHeader (line 355) | void deallocate_ReplyHeader(struct ReplyHeader*v){
  function serialize_GetDataRequest (line 357) | int serialize_GetDataRequest(struct oarchive *out, const char *tag, stru...
  function deserialize_GetDataRequest (line 365) | int deserialize_GetDataRequest(struct iarchive *in, const char *tag, str...
  function deallocate_GetDataRequest (line 373) | void deallocate_GetDataRequest(struct GetDataRequest*v){
  function serialize_SetDataRequest (line 376) | int serialize_SetDataRequest(struct oarchive *out, const char *tag, stru...
  function deserialize_SetDataRequest (line 385) | int deserialize_SetDataRequest(struct iarchive *in, const char *tag, str...
  function deallocate_SetDataRequest (line 394) | void deallocate_SetDataRequest(struct SetDataRequest*v){
  function serialize_SetDataResponse (line 398) | int serialize_SetDataResponse(struct oarchive *out, const char *tag, str...
  function deserialize_SetDataResponse (line 405) | int deserialize_SetDataResponse(struct iarchive *in, const char *tag, st...
  function deallocate_SetDataResponse (line 412) | void deallocate_SetDataResponse(struct SetDataResponse*v){
  function serialize_GetSASLRequest (line 415) | int serialize_GetSASLRequest(struct oarchive *out, const char *tag, stru...
  function deserialize_GetSASLRequest (line 422) | int deserialize_GetSASLRequest(struct iarchive *in, const char *tag, str...
  function deallocate_GetSASLRequest (line 429) | void deallocate_GetSASLRequest(struct GetSASLRequest*v){
  function serialize_SetSASLRequest (line 432) | int serialize_SetSASLRequest(struct oarchive *out, const char *tag, stru...
  function deserialize_SetSASLRequest (line 439) | int deserialize_SetSASLRequest(struct iarchive *in, const char *tag, str...
  function deallocate_SetSASLRequest (line 446) | void deallocate_SetSASLRequest(struct SetSASLRequest*v){
  function serialize_SetSASLResponse (line 449) | int serialize_SetSASLResponse(struct oarchive *out, const char *tag, str...
  function deserialize_SetSASLResponse (line 456) | int deserialize_SetSASLResponse(struct iarchive *in, const char *tag, st...
  function deallocate_SetSASLResponse (line 463) | void deallocate_SetSASLResponse(struct SetSASLResponse*v){
  function allocate_ACL_vector (line 466) | int allocate_ACL_vector(struct ACL_vector *v, int32_t len) {
  function deallocate_ACL_vector (line 476) | int deallocate_ACL_vector(struct ACL_vector *v) {
  function serialize_ACL_vector (line 487) | int serialize_ACL_vector(struct oarchive *out, const char *tag, struct A...
  function deserialize_ACL_vector (line 499) | int deserialize_ACL_vector(struct iarchive *in, const char *tag, struct ...
  function serialize_CreateRequest (line 511) | int serialize_CreateRequest(struct oarchive *out, const char *tag, struc...
  function deserialize_CreateRequest (line 521) | int deserialize_CreateRequest(struct iarchive *in, const char *tag, stru...
  function deallocate_CreateRequest (line 531) | void deallocate_CreateRequest(struct CreateRequest*v){
  function serialize_DeleteRequest (line 536) | int serialize_DeleteRequest(struct oarchive *out, const char *tag, struc...
  function deserialize_DeleteRequest (line 544) | int deserialize_DeleteRequest(struct iarchive *in, const char *tag, stru...
  function deallocate_DeleteRequest (line 552) | void deallocate_DeleteRequest(struct DeleteRequest*v){
  function serialize_GetChildrenRequest (line 555) | int serialize_GetChildrenRequest(struct oarchive *out, const char *tag, ...
  function deserialize_GetChildrenRequest (line 563) | int deserialize_GetChildrenRequest(struct iarchive *in, const char *tag,...
  function deallocate_GetChildrenRequest (line 571) | void deallocate_GetChildrenRequest(struct GetChildrenRequest*v){
  function serialize_GetChildren2Request (line 574) | int serialize_GetChildren2Request(struct oarchive *out, const char *tag,...
  function deserialize_GetChildren2Request (line 582) | int deserialize_GetChildren2Request(struct iarchive *in, const char *tag...
  function deallocate_GetChildren2Request (line 590) | void deallocate_GetChildren2Request(struct GetChildren2Request*v){
  function serialize_CheckVersionRequest (line 593) | int serialize_CheckVersionRequest(struct oarchive *out, const char *tag,...
  function deserialize_CheckVersionRequest (line 601) | int deserialize_CheckVersionRequest(struct iarchive *in, const char *tag...
  function deallocate_CheckVersionRequest (line 609) | void deallocate_CheckVersionRequest(struct CheckVersionRequest*v){
  function serialize_GetMaxChildrenRequest (line 612) | int serialize_GetMaxChildrenRequest(struct oarchive *out, const char *ta...
  function deserialize_GetMaxChildrenRequest (line 619) | int deserialize_GetMaxChildrenRequest(struct iarchive *in, const char *t...
  function deallocate_GetMaxChildrenRequest (line 626) | void deallocate_GetMaxChildrenRequest(struct GetMaxChildrenRequest*v){
  function serialize_GetMaxChildrenResponse (line 629) | int serialize_GetMaxChildrenResponse(struct oarchive *out, const char *t...
  function deserialize_GetMaxChildrenResponse (line 636) | int deserialize_GetMaxChildrenResponse(struct iarchive *in, const char *...
  function deallocate_GetMaxChildrenResponse (line 643) | void deallocate_GetMaxChildrenResponse(struct GetMaxChildrenResponse*v){
  function serialize_SetMaxChildrenRequest (line 645) | int serialize_SetMaxChildrenRequest(struct oarchive *out, const char *ta...
  function deserialize_SetMaxChildrenRequest (line 653) | int deserialize_SetMaxChildrenRequest(struct iarchive *in, const char *t...
  function deallocate_SetMaxChildrenRequest (line 661) | void deallocate_SetMaxChildrenRequest(struct SetMaxChildrenRequest*v){
  function serialize_SyncRequest (line 664) | int serialize_SyncRequest(struct oarchive *out, const char *tag, struct ...
  function deserialize_SyncRequest (line 671) | int deserialize_SyncRequest(struct iarchive *in, const char *tag, struct...
  function deallocate_SyncRequest (line 678) | void deallocate_SyncRequest(struct SyncRequest*v){
  function serialize_SyncResponse (line 681) | int serialize_SyncResponse(struct oarchive *out, const char *tag, struct...
  function deserialize_SyncResponse (line 688) | int deserialize_SyncResponse(struct iarchive *in, const char *tag, struc...
  function deallocate_SyncResponse (line 695) | void deallocate_SyncResponse(struct SyncResponse*v){
  function serialize_GetACLRequest (line 698) | int serialize_GetACLRequest(struct oarchive *out, const char *tag, struc...
  function deserialize_GetACLRequest (line 705) | int deserialize_GetACLRequest(struct iarchive *in, const char *tag, stru...
  function deallocate_GetACLRequest (line 712) | void deallocate_GetACLRequest(struct GetACLRequest*v){
  function serialize_SetACLRequest (line 715) | int serialize_SetACLRequest(struct oarchive *out, const char *tag, struc...
  function deserialize_SetACLRequest (line 724) | int deserialize_SetACLRequest(struct iarchive *in, const char *tag, stru...
  function deallocate_SetACLRequest (line 733) | void deallocate_SetACLRequest(struct SetACLRequest*v){
  function serialize_SetACLResponse (line 737) | int serialize_SetACLResponse(struct oarchive *out, const char *tag, stru...
  function deserialize_SetACLResponse (line 744) | int deserialize_SetACLResponse(struct iarchive *in, const char *tag, str...
  function deallocate_SetACLResponse (line 751) | void deallocate_SetACLResponse(struct SetACLResponse*v){
  function serialize_WatcherEvent (line 754) | int serialize_WatcherEvent(struct oarchive *out, const char *tag, struct...
  function deserialize_WatcherEvent (line 763) | int deserialize_WatcherEvent(struct iarchive *in, const char *tag, struc...
  function deallocate_WatcherEvent (line 772) | void deallocate_WatcherEvent(struct WatcherEvent*v){
  function serialize_ErrorResponse (line 775) | int serialize_ErrorResponse(struct oarchive *out, const char *tag, struc...
  function deserialize_ErrorResponse (line 782) | int deserialize_ErrorResponse(struct iarchive *in, const char *tag, stru...
  function deallocate_ErrorResponse (line 789) | void deallocate_ErrorResponse(struct ErrorResponse*v){
  function serialize_CreateResponse (line 791) | int serialize_CreateResponse(struct oarchive *out, const char *tag, stru...
  function deserialize_CreateResponse (line 798) | int deserialize_CreateResponse(struct iarchive *in, const char *tag, str...
  function deallocate_CreateResponse (line 805) | void deallocate_CreateResponse(struct CreateResponse*v){
  function serialize_ExistsRequest (line 808) | int serialize_ExistsRequest(struct oarchive *out, const char *tag, struc...
  function deserialize_ExistsRequest (line 816) | int deserialize_ExistsRequest(struct iarchive *in, const char *tag, stru...
  function deallocate_ExistsRequest (line 824) | void deallocate_ExistsRequest(struct ExistsRequest*v){
  function serialize_ExistsResponse (line 827) | int serialize_ExistsResponse(struct oarchive *out, const char *tag, stru...
  function deserialize_ExistsResponse (line 834) | int deserialize_ExistsResponse(struct iarchive *in, const char *tag, str...
  function deallocate_ExistsResponse (line 841) | void deallocate_ExistsResponse(struct ExistsResponse*v){
  function serialize_GetDataResponse (line 844) | int serialize_GetDataResponse(struct oarchive *out, const char *tag, str...
  function deserialize_GetDataResponse (line 852) | int deserialize_GetDataResponse(struct iarchive *in, const char *tag, st...
  function deallocate_GetDataResponse (line 860) | void deallocate_GetDataResponse(struct GetDataResponse*v){
  function serialize_GetChildrenResponse (line 864) | int serialize_GetChildrenResponse(struct oarchive *out, const char *tag,...
  function deserialize_GetChildrenResponse (line 871) | int deserialize_GetChildrenResponse(struct iarchive *in, const char *tag...
  function deallocate_GetChildrenResponse (line 878) | void deallocate_GetChildrenResponse(struct GetChildrenResponse*v){
  function serialize_GetChildren2Response (line 881) | int serialize_GetChildren2Response(struct oarchive *out, const char *tag...
  function deserialize_GetChildren2Response (line 889) | int deserialize_GetChildren2Response(struct iarchive *in, const char *ta...
  function deallocate_GetChildren2Response (line 897) | void deallocate_GetChildren2Response(struct GetChildren2Response*v){
  function serialize_GetACLResponse (line 901) | int serialize_GetACLResponse(struct oarchive *out, const char *tag, stru...
  function deserialize_GetACLResponse (line 909) | int deserialize_GetACLResponse(struct iarchive *in, const char *tag, str...
  function deallocate_GetACLResponse (line 917) | void deallocate_GetACLResponse(struct GetACLResponse*v){
  function serialize_LearnerInfo (line 921) | int serialize_LearnerInfo(struct oarchive *out, const char *tag, struct ...
  function deserialize_LearnerInfo (line 929) | int deserialize_LearnerInfo(struct iarchive *in, const char *tag, struct...
  function deallocate_LearnerInfo (line 937) | void deallocate_LearnerInfo(struct LearnerInfo*v){
  function allocate_Id_vector (line 939) | int allocate_Id_vector(struct Id_vector *v, int32_t len) {
  function deallocate_Id_vector (line 949) | int deallocate_Id_vector(struct Id_vector *v) {
  function serialize_Id_vector (line 960) | int serialize_Id_vector(struct oarchive *out, const char *tag, struct Id...
  function deserialize_Id_vector (line 972) | int deserialize_Id_vector(struct iarchive *in, const char *tag, struct I...
  function serialize_QuorumPacket (line 984) | int serialize_QuorumPacket(struct oarchive *out, const char *tag, struct...
  function deserialize_QuorumPacket (line 994) | int deserialize_QuorumPacket(struct iarchive *in, const char *tag, struc...
  function deallocate_QuorumPacket (line 1004) | void deallocate_QuorumPacket(struct QuorumPacket*v){
  function serialize_FileHeader (line 1008) | int serialize_FileHeader(struct oarchive *out, const char *tag, struct F...
  function deserialize_FileHeader (line 1017) | int deserialize_FileHeader(struct iarchive *in, const char *tag, struct ...
  function deallocate_FileHeader (line 1026) | void deallocate_FileHeader(struct FileHeader*v){
  function serialize_TxnHeader (line 1028) | int serialize_TxnHeader(struct oarchive *out, const char *tag, struct Tx...
  function deserialize_TxnHeader (line 1039) | int deserialize_TxnHeader(struct iarchive *in, const char *tag, struct T...
  function deallocate_TxnHeader (line 1050) | void deallocate_TxnHeader(struct TxnHeader*v){
  function serialize_CreateTxnV0 (line 1052) | int serialize_CreateTxnV0(struct oarchive *out, const char *tag, struct ...
  function deserialize_CreateTxnV0 (line 1062) | int deserialize_CreateTxnV0(struct iarchive *in, const char *tag, struct...
  function deallocate_CreateTxnV0 (line 1072) | void deallocate_CreateTxnV0(struct CreateTxnV0*v){
  function serialize_CreateTxn (line 1077) | int serialize_CreateTxn(struct oarchive *out, const char *tag, struct Cr...
  function deserialize_CreateTxn (line 1088) | int deserialize_CreateTxn(struct iarchive *in, const char *tag, struct C...
  function deallocate_CreateTxn (line 1099) | void deallocate_CreateTxn(struct CreateTxn*v){
  function serialize_DeleteTxn (line 1104) | int serialize_DeleteTxn(struct oarchive *out, const char *tag, struct De...
  function deserialize_DeleteTxn (line 1111) | int deserialize_DeleteTxn(struct iarchive *in, const char *tag, struct D...
  function deallocate_DeleteTxn (line 1118) | void deallocate_DeleteTxn(struct DeleteTxn*v){
  function serialize_SetDataTxn (line 1121) | int serialize_SetDataTxn(struct oarchive *out, const char *tag, struct S...
  function deserialize_SetDataTxn (line 1130) | int deserialize_SetDataTxn(struct iarchive *in, const char *tag, struct ...
  function deallocate_SetDataTxn (line 1139) | void deallocate_SetDataTxn(struct SetDataTxn*v){
  function serialize_CheckVersionTxn (line 1143) | int serialize_CheckVersionTxn(struct oarchive *out, const char *tag, str...
  function deserialize_CheckVersionTxn (line 1151) | int deserialize_CheckVersionTxn(struct iarchive *in, const char *tag, st...
  function deallocate_CheckVersionTxn (line 1159) | void deallocate_CheckVersionTxn(struct CheckVersionTxn*v){
  function serialize_SetACLTxn (line 1162) | int serialize_SetACLTxn(struct oarchive *out, const char *tag, struct Se...
  function deserialize_SetACLTxn (line 1171) | int deserialize_SetACLTxn(struct iarchive *in, const char *tag, struct S...
  function deallocate_SetACLTxn (line 1180) | void deallocate_SetACLTxn(struct SetACLTxn*v){
  function serialize_SetMaxChildrenTxn (line 1184) | int serialize_SetMaxChildrenTxn(struct oarchive *out, const char *tag, s...
  function deserialize_SetMaxChildrenTxn (line 1192) | int deserialize_SetMaxChildrenTxn(struct iarchive *in, const char *tag, ...
  function deallocate_SetMaxChildrenTxn (line 1200) | void deallocate_SetMaxChildrenTxn(struct SetMaxChildrenTxn*v){
  function serialize_CreateSessionTxn (line 1203) | int serialize_CreateSessionTxn(struct oarchive *out, const char *tag, st...
  function deserialize_CreateSessionTxn (line 1210) | int deserialize_CreateSessionTxn(struct iarchive *in, const char *tag, s...
  function deallocate_CreateSessionTxn (line 1217) | void deallocate_CreateSessionTxn(struct CreateSessionTxn*v){
  function serialize_ErrorTxn (line 1219) | int serialize_ErrorTxn(struct oarchive *out, const char *tag, struct Err...
  function deserialize_ErrorTxn (line 1226) | int deserialize_ErrorTxn(struct iarchive *in, const char *tag, struct Er...
  function deallocate_ErrorTxn (line 1233) | void deallocate_ErrorTxn(struct ErrorTxn*v){
  function serialize_Txn (line 1235) | int serialize_Txn(struct oarchive *out, const char *tag, struct Txn *v){
  function deserialize_Txn (line 1243) | int deserialize_Txn(struct iarchive *in, const char *tag, struct Txn*v){
  function deallocate_Txn (line 1251) | void deallocate_Txn(struct Txn*v){
  function allocate_Txn_vector (line 1254) | int allocate_Txn_vector(struct Txn_vector *v, int32_t len) {
  function deallocate_Txn_vector (line 1264) | int deallocate_Txn_vector(struct Txn_vector *v) {
  function serialize_Txn_vector (line 1275) | int serialize_Txn_vector(struct oarchive *out, const char *tag, struct T...
  function deserialize_Txn_vector (line 1287) | int deserialize_Txn_vector(struct iarchive *in, const char *tag, struct ...
  function serialize_MultiTxn (line 1299) | int serialize_MultiTxn(struct oarchive *out, const char *tag, struct Mul...
  function deserialize_MultiTxn (line 1306) | int deserialize_MultiTxn(struct iarchive *in, const char *tag, struct Mu...
  function deallocate_MultiTxn (line 1313) | void deallocate_MultiTxn(struct MultiTxn*v){

FILE: QSentinel/zookeeper/zookeeper.jute.h
  type Id (line 27) | struct Id {
  type oarchive (line 31) | struct oarchive
  type Id (line 31) | struct Id
  type iarchive (line 32) | struct iarchive
  type Id (line 32) | struct Id
  type Id (line 33) | struct Id
  type ACL (line 34) | struct ACL {
  type oarchive (line 38) | struct oarchive
  type ACL (line 38) | struct ACL
  type iarchive (line 39) | struct iarchive
  type ACL (line 39) | struct ACL
  type ACL (line 40) | struct ACL
  type Stat (line 41) | struct Stat {
  type oarchive (line 54) | struct oarchive
  type Stat (line 54) | struct Stat
  type iarchive (line 55) | struct iarchive
  type Stat (line 55) | struct Stat
  type Stat (line 56) | struct Stat
  type StatPersisted (line 57) | struct StatPersisted {
  type oarchive (line 68) | struct oarchive
  type StatPersisted (line 68) | struct StatPersisted
  type iarchive (line 69) | struct iarchive
  type StatPersisted (line 69) | struct StatPersisted
  type StatPersisted (line 70) | struct StatPersisted
  type StatPersistedV1 (line 71) | struct StatPersistedV1 {
  type oarchive (line 81) | struct oarchive
  type StatPersistedV1 (line 81) | struct StatPersistedV1
  type iarchive (line 82) | struct iarchive
  type StatPersistedV1 (line 82) | struct StatPersistedV1
  type StatPersistedV1 (line 83) | struct StatPersistedV1
  type ConnectRequest (line 84) | struct ConnectRequest {
  type oarchive (line 91) | struct oarchive
  type ConnectRequest (line 91) | struct ConnectRequest
  type iarchive (line 92) | struct iarchive
  type ConnectRequest (line 92) | struct ConnectRequest
  type ConnectRequest (line 93) | struct ConnectRequest
  type ConnectResponse (line 94) | struct ConnectResponse {
  type oarchive (line 100) | struct oarchive
  type ConnectResponse (line 100) | struct ConnectResponse
  type iarchive (line 101) | struct iarchive
  type ConnectResponse (line 101) | struct ConnectResponse
  type ConnectResponse (line 102) | struct ConnectResponse
  type String_vector (line 103) | struct String_vector {
  type oarchive (line 108) | struct oarchive
  type String_vector (line 108) | struct String_vector
  type iarchive (line 109) | struct iarchive
  type String_vector (line 109) | struct String_vector
  type String_vector (line 110) | struct String_vector
  type String_vector (line 111) | struct String_vector
  type SetWatches (line 112) | struct SetWatches {
  type oarchive (line 118) | struct oarchive
  type SetWatches (line 118) | struct SetWatches
  type iarchive (line 119) | struct iarchive
  type SetWatches (line 119) | struct SetWatches
  type SetWatches (line 120) | struct SetWatches
  type RequestHeader (line 121) | struct RequestHeader {
  type oarchive (line 125) | struct oarchive
  type RequestHeader (line 125) | struct RequestHeader
  type iarchive (line 126) | struct iarchive
  type RequestHeader (line 126) | struct RequestHeader
  type RequestHeader (line 127) | struct RequestHeader
  type MultiHeader (line 128) | struct MultiHeader {
  type oarchive (line 133) | struct oarchive
  type MultiHeader (line 133) | struct MultiHeader
  type iarchive (line 134) | struct iarchive
  type MultiHeader (line 134) | struct MultiHeader
  type MultiHeader (line 135) | struct MultiHeader
  type AuthPacket (line 136) | struct AuthPacket {
  type oarchive (line 141) | struct oarchive
  type AuthPacket (line 141) | struct AuthPacket
  type iarchive (line 142) | struct iarchive
  type AuthPacket (line 142) | struct AuthPacket
  type AuthPacket (line 143) | struct AuthPacket
  type ReplyHeader (line 144) | struct ReplyHeader {
  type oarchive (line 149) | struct oarchive
  type ReplyHeader (line 149) | struct ReplyHeader
  type iarchive (line 150) | struct iarchive
  type ReplyHeader (line 150) | struct ReplyHeader
  type ReplyHeader (line 151) | struct ReplyHeader
  type GetDataRequest (line 152) | struct GetDataRequest {
  type oarchive (line 156) | struct oarchive
  type GetDataRequest (line 156) | struct GetDataRequest
  type iarchive (line 157) | struct iarchive
  type GetDataRequest (line 157) | struct GetDataRequest
  type GetDataRequest (line 158) | struct GetDataRequest
  type SetDataRequest (line 159) | struct SetDataRequest {
  type oarchive (line 164) | struct oarchive
  type SetDataRequest (line 164) | struct SetDataRequest
  type iarchive (line 165) | struct iarchive
  type SetDataRequest (line 165) | struct SetDataRequest
  type SetDataRequest (line 166) | struct SetDataRequest
  type SetDataResponse (line 167) | struct SetDataResponse {
  type oarchive (line 170) | struct oarchive
  type SetDataResponse (line 170) | struct SetDataResponse
  type iarchive (line 171) | struct iarchive
  type SetDataResponse (line 171) | struct SetDataResponse
  type SetDataResponse (line 172) | struct SetDataResponse
  type GetSASLRequest (line 173) | struct GetSASLRequest {
  type oarchive (line 176) | struct oarchive
  type GetSASLRequest (line 176) | struct GetSASLRequest
  type iarchive (line 177) | struct iarchive
  type GetSASLRequest (line 177) | struct GetSASLRequest
  type GetSASLRequest (line 178) | struct GetSASLRequest
  type SetSASLRequest (line 179) | struct SetSASLRequest {
  type oarchive (line 182) | struct oarchive
  type SetSASLRequest (line 182) | struct SetSASLRequest
  type iarchive (line 183) | struct iarchive
  type SetSASLRequest (line 183) | struct SetSASLRequest
  type SetSASLRequest (line 184) | struct SetSASLRequest
  type SetSASLResponse (line 185) | struct SetSASLResponse {
  type oarchive (line 188) | struct oarchive
  type SetSASLResponse (line 188) | struct SetSASLResponse
  type iarchive (line 189) | struct iarchive
  type SetSASLResponse (line 189) | struct SetSASLResponse
  type SetSASLResponse (line 190) | struct SetSASLResponse
  type ACL_vector (line 191) | struct ACL_vector {
  type oarchive (line 196) | struct oarchive
  type ACL_vector (line 196) | struct ACL_vector
  type iarchive (line 197) | struct iarchive
  type ACL_vector (line 197) | struct ACL_vector
  type ACL_vector (line 198) | struct ACL_vector
  type ACL_vector (line 199) | struct ACL_vector
  type CreateRequest (line 200) | struct CreateRequest {
  type oarchive (line 206) | struct oarchive
  type CreateRequest (line 206) | struct CreateRequest
  type iarchive (line 207) | struct iarchive
  type CreateRequest (line 207) | struct CreateRequest
  type CreateRequest (line 208) | struct CreateRequest
  type DeleteRequest (line 209) | struct DeleteRequest {
  type oarchive (line 213) | struct oarchive
  type DeleteRequest (line 213) | struct DeleteRequest
  type iarchive (line 214) | struct iarchive
  type DeleteRequest (line 214) | struct DeleteRequest
  type DeleteRequest (line 215) | struct DeleteRequest
  type GetChildrenRequest (line 216) | struct GetChildrenRequest {
  type oarchive (line 220) | struct oarchive
  type GetChildrenRequest (line 220) | struct GetChildrenRequest
  type iarchive (line 221) | struct iarchive
  type GetChildrenRequest (line 221) | struct GetChildrenRequest
  type GetChildrenRequest (line 222) | struct GetChildrenRequest
  type GetChildren2Request (line 223) | struct GetChildren2Request {
  type oarchive (line 227) | struct oarchive
  type GetChildren2Request (line 227) | struct GetChildren2Request
  type iarchive (line 228) | struct iarchive
  type GetChildren2Request (line 228) | struct GetChildren2Request
  type GetChildren2Request (line 229) | struct GetChildren2Request
  type CheckVersionRequest (line 230) | struct CheckVersionRequest {
  type oarchive (line 234) | struct oarchive
  type CheckVersionRequest (line 234) | struct CheckVersionRequest
  type iarchive (line 235) | struct iarchive
  type CheckVersionRequest (line 235) | struct CheckVersionRequest
  type CheckVersionRequest (line 236) | struct CheckVersionRequest
  type GetMaxChildrenRequest (line 237) | struct GetMaxChildrenRequest {
  type oarchive (line 240) | struct oarchive
  type GetMaxChildrenRequest (line 240) | struct GetMaxChildrenRequest
  type iarchive (line 241) | struct iarchive
  type GetMaxChildrenRequest (line 241) | struct GetMaxChildrenRequest
  type GetMaxChildrenRequest (line 242) | struct GetMaxChildrenRequest
  type GetMaxChildrenResponse (line 243) | struct GetMaxChildrenResponse {
  type oarchive (line 246) | struct oarchive
  type GetMaxChildrenResponse (line 246) | struct GetMaxChildrenResponse
  type iarchive (line 247) | struct iarchive
  type GetMaxChildrenResponse (line 247) | struct GetMaxChildrenResponse
  type GetMaxChildrenResponse (line 248) | struct GetMaxChildrenResponse
  type SetMaxChildrenRequest (line 249) | struct SetMaxChildrenRequest {
  type oarchive (line 253) | struct oarchive
  type SetMaxChildrenRequest (line 253) | struct SetMaxChildrenRequest
  type iarchive (line 254) | struct iarchive
  type SetMaxChildrenRequest (line 254) | struct SetMaxChildrenRequest
  type SetMaxChildrenRequest (line 255) | struct SetMaxChildrenRequest
  type SyncRequest (line 256) | struct SyncRequest {
  type oarchive (line 259) | struct oarchive
  type SyncRequest (line 259) | struct SyncRequest
  type iarchive (line 260) | struct iarchive
  type SyncRequest (line 260) | struct SyncRequest
  type SyncRequest (line 261) | struct SyncRequest
  type SyncResponse (line 262) | struct SyncResponse {
  type oarchive (line 265) | struct oarchive
  type SyncResponse (line 265) | struct SyncResponse
  type iarchive (line 266) | struct iarchive
  type SyncResponse (line 266) | struct SyncResponse
  type SyncResponse (line 267) | struct SyncResponse
  type GetACLRequest (line 268) | struct GetACLRequest {
  type oarchive (line 271) | struct oarchive
  type GetACLRequest (line 271) | struct GetACLRequest
  type iarchive (line 272) | struct iarchive
  type GetACLRequest (line 272) | struct GetACLRequest
  type GetACLRequest (line 273) | struct GetACLRequest
  type SetACLRequest (line 274) | struct SetACLRequest {
  type oarchive (line 279) | struct oarchive
  type SetACLRequest (line 279) | struct SetACLRequest
  type iarchive (line 280) | struct iarchive
  type SetACLRequest (line 280) | struct SetACLRequest
  type SetACLRequest (line 281) | struct SetACLRequest
  type SetACLResponse (line 282) | struct SetACLResponse {
  type oarchive (line 285) | struct oarchive
  type SetACLResponse (line 285) | struct SetACLResponse
  type iarchive (line 286) | struct iarchive
  type SetACLResponse (line 286) | struct SetACLResponse
  type SetACLResponse (line 287) | struct SetACLResponse
  type WatcherEvent (line 288) | struct WatcherEvent {
  type oarchive (line 293) | struct oarchive
  type WatcherEvent (line 293) | struct WatcherEvent
  type iarchive (line 294) | struct iarchive
  type WatcherEvent (line 294) | struct WatcherEvent
  type WatcherEvent (line 295) | struct WatcherEvent
  type ErrorResponse (line 296) | struct ErrorResponse {
  type oarchive (line 299) | struct oarchive
  type ErrorResponse (line 299) | struct ErrorResponse
  type iarchive (line 300) | struct iarchive
  type ErrorResponse (line 300) | struct ErrorResponse
  type ErrorResponse (line 301) | struct ErrorResponse
  type CreateResponse (line 302) | struct CreateResponse {
  type oarchive (line 305) | struct oarchive
  type CreateResponse (line 305) | struct CreateResponse
  type iarchive (line 306) | struct iarchive
  type CreateResponse (line 306) | struct CreateResponse
  type CreateResponse (line 307) | struct CreateResponse
  type ExistsRequest (line 308) | struct ExistsRequest {
  type oarchive (line 312) | struct oarchive
  type ExistsRequest (line 312) | struct ExistsRequest
  type iarchive (line 313) | struct iarchive
  type ExistsRequest (line 313) | struct ExistsRequest
  type ExistsRequest (line 314) | struct ExistsRequest
  type ExistsResponse (line 315) | struct ExistsResponse {
  type oarchive (line 318) | struct oarchive
  type ExistsResponse (line 318) | struct ExistsResponse
  type iarchive (line 319) | struct iarchive
  type ExistsResponse (line 319) | struct ExistsResponse
  type ExistsResponse (line 320) | struct ExistsResponse
  type GetDataResponse (line 321) | struct GetDataResponse {
  type oarchive (line 325) | struct oarchive
  type GetDataResponse (line 325) | struct GetDataResponse
  type iarchive (line 326) | struct iarchive
  type GetDataResponse (line 326) | struct GetDataResponse
  type GetDataResponse (line 327) | struct GetDataResponse
  type GetChildrenResponse (line 328) | struct GetChildrenResponse {
  type oarchive (line 331) | struct oarchive
  type GetChildrenResponse (line 331) | struct GetChildrenResponse
  type iarchive (line 332) | struct iarchive
  type GetChildrenResponse (line 332) | struct GetChildrenResponse
  type GetChildrenResponse (line 333) | struct GetChildrenResponse
  type GetChildren2Response (line 334) | struct GetChildren2Response {
  type oarchive (line 338) | struct oarchive
  type GetChildren2Response (line 338) | struct GetChildren2Response
  type iarchive (line 339) | struct iarchive
  type GetChildren2Response (line 339) | struct GetChildren2Response
  type GetChildren2Response (line 340) | struct GetChildren2Response
  type GetACLResponse (line 341) | struct GetACLResponse {
  type oarchive (line 345) | struct oarchive
  type GetACLResponse (line 345) | struct GetACLResponse
  type iarchive (line 346) | struct iarchive
  type GetACLResponse (line 346) | struct GetACLResponse
  type GetACLResponse (line 347) | struct GetACLResponse
  type LearnerInfo (line 348) | struct LearnerInfo {
  type oarchive (line 352) | struct oarchive
  type LearnerInfo (line 352) | struct LearnerInfo
  type iarchive (line 353) | struct iarchive
  type LearnerInfo (line 353) | struct LearnerInfo
  type LearnerInfo (line 354) | struct LearnerInfo
  type Id_vector (line 355) | struct Id_vector {
  type oarchive (line 360) | struct oarchive
  type Id_vector (line 360) | struct Id_vector
  type iarchive (line 361) | struct iarchive
  type Id_vector (line 361) | struct Id_vector
  type Id_vector (line 362) | struct Id_vector
  type Id_vector (line 363) | struct Id_vector
  type QuorumPacket (line 364) | struct QuorumPacket {
  type oarchive (line 370) | struct oarchive
  type QuorumPacket (line 370) | struct QuorumPacket
  type iarchive (line 371) | struct iarchive
  type QuorumPacket (line 371) | struct QuorumPacket
  type QuorumPacket (line 372) | struct QuorumPacket
  type FileHeader (line 373) | struct FileHeader {
  type oarchive (line 378) | struct oarchive
  type FileHeader (line 378) | struct FileHeader
  type iarchive (line 379) | struct iarchive
  type FileHeader (line 379) | struct FileHeader
  type FileHeader (line 380) | struct FileHeader
  type TxnHeader (line 381) | struct TxnHeader {
  type oarchive (line 388) | struct oarchive
  type TxnHeader (line 388) | struct TxnHeader
  type iarchive (line 389) | struct iarchive
  type TxnHeader (line 389) | struct TxnHeader
  type TxnHeader (line 390) | struct TxnHeader
  type CreateTxnV0 (line 391) | struct CreateTxnV0 {
  type oarchive (line 397) | struct oarchive
  type CreateTxnV0 (line 397) | struct CreateTxnV0
  type iarchive (line 398) | struct iarchive
  type CreateTxnV0 (line 398) | struct CreateTxnV0
  type CreateTxnV0 (line 399) | struct CreateTxnV0
  type CreateTxn (line 400) | struct CreateTxn {
  type oarchive (line 407) | struct oarchive
  type CreateTxn (line 407) | struct CreateTxn
  type iarchive (line 408) | struct iarchive
  type CreateTxn (line 408) | struct CreateTxn
  type CreateTxn (line 409) | struct CreateTxn
  type DeleteTxn (line 410) | struct DeleteTxn {
  type oarchive (line 413) | struct oarchive
  type DeleteTxn (line 413) | struct DeleteTxn
  type iarchive (line 414) | struct iarchive
  type DeleteTxn (line 414) | struct DeleteTxn
  type DeleteTxn (line 415) | struct DeleteTxn
  type SetDataTxn (line 416) | struct SetDataTxn {
  type oarchive (line 421) | struct oarchive
  type SetDataTxn (line 421) | struct SetDataTxn
  type iarchive (line 422) | struct iarchive
  type SetDataTxn (line 422) | struct SetDataTxn
  type SetDataTxn (line 423) | struct SetDataTxn
  type CheckVersionTxn (line 424) | struct CheckVersionTxn {
  type oarchive (line 428) | struct oarchive
  type CheckVersionTxn (line 428) | struct CheckVersionTxn
  type iarchive (line 429) | struct iarchive
  type CheckVersionTxn (line 429) | struct CheckVersionTxn
  type CheckVersionTxn (line 430) | struct CheckVersionTxn
  type SetACLTxn (line 431) | struct SetACLTxn {
  type oarchive (line 436) | struct oarchive
  type SetACLTxn (line 436) | struct SetACLTxn
  type iarchive (line 437) | struct iarchive
  type SetACLTxn (line 437) | struct SetACLTxn
  type SetACLTxn (line 438) | struct SetACLTxn
  type SetMaxChildrenTxn (line 439) | struct SetMaxChildrenTxn {
  type oarchive (line 443) | struct oarchive
  type SetMaxChildrenTxn (line 443) | struct SetMaxChildrenTxn
  type iarchive (line 444) | struct iarchive
  type SetMaxChildrenTxn (line 444) | struct SetMaxChildrenTxn
  type SetMaxChildrenTxn (line 445) | struct SetMaxChildrenTxn
  type CreateSessionTxn (line 446) | struct CreateSessionTxn {
  type oarchive (line 449) | struct oarchive
  type CreateSessionTxn (line 449) | struct CreateSessionTxn
  type iarchive (line 450) | struct iarchive
  type CreateSessionTxn (line 450) | struct CreateSessionTxn
  type CreateSessionTxn (line 451) | struct CreateSessionTxn
  type ErrorTxn (line 452) | struct ErrorTxn {
  type oarchive (line 455) | struct oarchive
  type ErrorTxn (line 455) | struct ErrorTxn
  type iarchive (line 456) | struct iarchive
  type ErrorTxn (line 456) | struct ErrorTxn
  type ErrorTxn (line 457) | struct ErrorTxn
  type Txn (line 458) | struct Txn {
  type oarchive (line 462) | struct oarchive
  type Txn (line 462) | struct Txn
  type iarchive (line 463) | struct iarchive
  type Txn (line 463) | struct Txn
  type Txn (line 464) | struct Txn
  type Txn_vector (line 465) | struct Txn_vector {
  type oarchive (line 470) | struct oarchive
  type Txn_vector (line 470) | struct Txn_vector
  type iarchive (line 471) | struct iarchive
  type Txn_vector (line 471) | struct Txn_vector
  type Txn_vector (line 472) | struct Txn_vector
  type Txn_vector (line 473) | struct Txn_vector
  type MultiTxn (line 474) | struct MultiTxn {
  type oarchive (line 477) | struct oarchive
  type MultiTxn (line 477) | struct MultiTxn
  type iarchive (line 478) | struct iarchive
  type MultiTxn (line 478) | struct MultiTxn
  type MultiTxn (line 479) | struct MultiTxn

FILE: QedisCore/QAOF.cc
  type qedis (line 11) | namespace qedis
    function QAOFThreadController (line 43) | QAOFThreadController& QAOFThreadController::Instance()
    function SaveExpire (line 180) | static void SaveExpire(const QString& key, uint64_t absMs, OutputMemor...
    function RewriteProcess (line 190) | static void RewriteProcess()
    function QError (line 226) | QError bgrewriteaof(const std::vector<QString>& , UnboundedBuffer* reply)
    function SaveStringObject (line 259) | static void SaveStringObject(const QString& key, const QObject& obj, O...
    function SaveListObject (line 269) | static void SaveListObject(const QString& key, const QObject& obj, Out...
    function SaveSetObject (line 285) | static void SaveSetObject(const QString& key, const QObject& obj, Outp...
    function SaveZSetObject (line 301) | static void  SaveZSetObject(const QString& key, const QObject& obj, Ou...
    function SaveHashObject (line 324) | static void SaveHashObject(const QString& key, const QObject& obj, Out...
    function SaveObject (line 342) | static void SaveObject(const QString& key, const QObject& obj, OutputM...

FILE: QedisCore/QAOF.h
  function namespace (line 11) | namespace qedis

FILE: QedisCore/QClient.cc
  type qedis (line 10) | namespace qedis
    function PacketLength (line 18) | PacketLength QClient::_ProcessInlineCmd(const char* buf,
    function ProcessMaster (line 55) | static int ProcessMaster(const char* start, const char* end)
    function PacketLength (line 141) | PacketLength QClient::_HandlePacket(const char* start, std::size_t bytes)
    function QClient (line 287) | QClient*  QClient::Current()

FILE: QedisCore/QClient.h
  function namespace (line 13) | namespace ConnectionTag
  function namespace (line 18) | namespace qedis

FILE: QedisCore/QCommand.cc
  type qedis (line 6) | namespace qedis
    function QCommandInfo (line 196) | const QCommandInfo* QCommandTable::GetCommandInfo(const QString& cmd)
    function QCommandInfo (line 227) | const QCommandInfo* QCommandTable::DelCommand(const QString& cmd)
    function QError (line 248) | QError QCommandTable::ExecuteCmd(const std::vector<QString>& params, c...
    function QError (line 271) | QError QCommandTable::ExecuteCmd(const std::vector<QString>& params, U...
    function QError (line 305) | QError cmdlist(const std::vector<QString>& params, UnboundedBuffer* re...

FILE: QedisCore/QCommand.h
  function namespace (line 10) | namespace qedis

FILE: QedisCore/QCommon.cc
  type qedis (line 9) | namespace qedis
    type QErrorInfo (line 12) | struct QErrorInfo
    function Double2Str (line 38) | int Double2Str(char* ptr, std::size_t nBytes, double val)
    function TryStr2Long (line 43) | bool TryStr2Long(const char* ptr, size_t nBytes, long& val)
    function Strtol (line 101) | bool Strtol(const char* ptr, size_t nBytes, long* outVal)
    function Strtoll (line 117) | bool Strtoll(const char* ptr, size_t nBytes, long long* outVal)
    function Strtof (line 133) | bool Strtof(const char* ptr, size_t nBytes, float* outVal)
    function Strtod (line 149) | bool Strtod(const char* ptr, size_t nBytes, double* outVal)
    function FormatInt (line 180) | size_t  FormatInt(long value, UnboundedBuffer* reply)
    function FormatSingle (line 195) | size_t  FormatSingle(const char* str, size_t len, UnboundedBuffer* reply)
    function FormatSingle (line 207) | size_t  FormatSingle(const QString& str, UnboundedBuffer* reply)
    function FormatBulk (line 212) | size_t  FormatBulk(const char* str, size_t len, UnboundedBuffer* reply)
    function FormatBulk (line 234) | size_t  FormatBulk(const QString& str, UnboundedBuffer* reply)
    function PreFormatMultiBulk (line 239) | size_t  PreFormatMultiBulk(size_t nBulk, UnboundedBuffer* reply)
    function FormatMultiBulk (line 254) | std::size_t FormatMultiBulk(const std::vector<QString> vs, UnboundedBu...
    function FormatEmptyBulk (line 263) | std::size_t FormatEmptyBulk(UnboundedBuffer* reply)
    function ReplyError (line 268) | void ReplyError(QError err, UnboundedBuffer* reply)
    function FormatNull (line 278) | size_t FormatNull(UnboundedBuffer* reply)
    function FormatNullArray (line 290) | size_t  FormatNullArray(UnboundedBuffer* reply)
    function FormatOK (line 301) | size_t FormatOK(UnboundedBuffer* reply)
    function Format1 (line 312) | size_t Format1(UnboundedBuffer* reply)
    function Format0 (line 325) | size_t Format0(UnboundedBuffer* reply)
    function QParseResult (line 338) | QParseResult GetIntUntilCRLF(const char*& ptr, std::size_t nBytes, int...
    function SplitString (line 384) | std::vector<QString>  SplitString(const QString& str, char seperator)

FILE: QedisCore/QCommon.h
  function namespace (line 17) | namespace qedis
  function QParseResult (line 215) | enum class QParseResult : int8_t

FILE: QedisCore/QConfig.cc
  type qedis (line 7) | namespace qedis
    function EraseQuotes (line 10) | static void EraseQuotes(QString& str)
    function LoadQedisConfig (line 71) | bool  LoadQedisConfig(const char* cfgFile, QConfig& cfg)

FILE: QedisCore/QConfig.h
  function namespace (line 8) | namespace qedis

FILE: QedisCore/QDB.cc
  type qedis (line 19) | namespace qedis
    function QObject (line 648) | QObject QDBLoader::LoadSpecialStringObject(size_t  specialVal)
    function QString (line 689) | QString QDBLoader::LoadString(size_t strLen)
    function QString (line 698) | QString QDBLoader::LoadLZFString()
    function QString (line 730) | QString QDBLoader::LoadKey()
    function QObject (line 736) | QObject QDBLoader::LoadObject(int8_t type)
    function QString (line 804) | QString QDBLoader::_LoadGenericString()
    function QObject (line 820) | QObject QDBLoader::_LoadList()
    function QObject (line 852) | QObject QDBLoader::_LoadSet()
    function QObject (line 884) | QObject QDBLoader::_LoadHash()
    function QObject (line 929) | QObject QDBLoader::_LoadSSet()
    type ZipListElement (line 1006) | struct ZipListElement
      method QString (line 1013) | QString ToString() const
      method QString (line 1025) | QString LongToString() const
    function QObject (line 1038) | QObject QDBLoader::_LoadZipList(int8_t type)
    function QObject (line 1044) | QObject QDBLoader::_LoadZipList(const QString& zl, int8_t type)
    function QObject (line 1133) | QObject QDBLoader::_LoadIntset()
    function QObject (line 1161) | QObject QDBLoader::_LoadQuickList()
    function DumpObject (line 1226) | std::string DumpObject(const QObject& val)
    function QObject (line 1257) | QObject RestoreObject(const char* data, size_t len)
    function QError (line 1291) | QError dump(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 1306) | QError restore(const std::vector<QString>& params, UnboundedBuffer* re...

FILE: QedisCore/QDB.h
  function namespace (line 7) | namespace qedis

FILE: QedisCore/QDumpInterface.h
  function namespace (line 7) | namespace qedis

FILE: QedisCore/QGlobRegex.cc
  type qedis (line 5) | namespace qedis
    function NotGlobRegex (line 8) | bool NotGlobRegex(const char* pattern, std::size_t plen)

FILE: QedisCore/QGlobRegex.h
  function class (line 12) | class QGlobRegex

FILE: QedisCore/QHash.cc
  type qedis (line 5) | namespace qedis
    function QObject (line 8) | QObject QObject::CreateHash()
    function _set_hash_force (line 35) | QHash::iterator _set_hash_force(QHash& hash, const QString& key, const...
    function _set_hash_if_notexist (line 46) | bool _set_hash_if_notexist(QHash& hash, const QString& key, const QStr...
    function QError (line 51) | QError hset(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 62) | QError hmset(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 80) | QError hget(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 96) | QError hmget(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 115) | QError hgetall(const std::vector<QString>& params, UnboundedBuffer* re...
    function QError (line 131) | QError hkeys(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 146) | QError hvals(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 161) | QError  hdel(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 188) | QError hexists(const std::vector<QString>& params, UnboundedBuffer* re...
    function QError (line 203) | QError hlen(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 212) | QError hincrby(const std::vector<QString>& params, UnboundedBuffer* re...
    function QError (line 248) | QError hincrbyfloat(const std::vector<QString>& params, UnboundedBuffe...
    function QError (line 284) | QError hsetnx(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 297) | QError hstrlen(const std::vector<QString>& params, UnboundedBuffer* re...
    function HScanKey (line 317) | size_t HScanKey(const QHash& hash, size_t cursor, size_t count, std::v...

FILE: QedisCore/QHash.h
  function namespace (line 9) | namespace qedis

FILE: QedisCore/QHelper.cc
  type qedis (line 20) | namespace qedis
    function dictGenHashFunction (line 26) | unsigned int dictGenHashFunction(const void* key, int len) {
    function BitCount (line 77) | std::size_t BitCount(const uint8_t*  buf, std::size_t len)
    function getRandomHexChars (line 104) | void getRandomHexChars(char *p, unsigned int len)
    function getMemoryInfo (line 181) | std::vector<size_t> getMemoryInfo()
    function getMemoryInfo (line 253) | size_t getMemoryInfo(MemoryInfoType type)
    function getMemoryInfo (line 317) | std::vector<size_t> getMemoryInfo()
    function getMemoryInfo (line 339) | size_t getMemoryInfo(MemoryInfoType type)

FILE: QedisCore/QHelper.h
  function namespace (line 8) | namespace qedis

FILE: QedisCore/QKeyCommand.cc
  type qedis (line 6) | namespace qedis
    function QError (line 9) | QError type(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 43) | QError exists(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 53) | QError del(const std::vector<QString>& params, UnboundedBuffer* reply)
    function _SetExpireByMs (line 71) | static int _SetExpireByMs(const QString& key, uint64_t absTimeout)
    function QError (line 85) | QError expire(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 96) | QError pexpire(const std::vector<QString>& params, UnboundedBuffer* re...
    function QError (line 107) | QError expireat(const std::vector<QString>& params, UnboundedBuffer* r...
    function QError (line 118) | QError pexpireat(const std::vector<QString>& params, UnboundedBuffer* ...
    function _ttl (line 130) | static int64_t _ttl(const QString& key)
    function QError (line 149) | QError ttl(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 160) | QError pttl(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 170) | QError persist(const std::vector<QString>& params, UnboundedBuffer* re...
    function QError (line 180) | QError move(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 218) | QError keys(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 238) | QError randomkey(const std::vector<QString>& params, UnboundedBuffer* ...
    function QError (line 250) | static QError RenameKey(const QString& oldKey, const QString& newKey, ...
    function QError (line 279) | QError rename(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 287) | QError renamenx(const std::vector<QString>& params, UnboundedBuffer* r...
    function QError (line 300) | static QError ParseScanOption(const std::vector<QString>& params, int ...
    function QError (line 333) | QError scan(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 394) | QError hscan(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 470) | QError sscan(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 544) | QError sort(const std::vector<QString>& params, UnboundedBuffer* reply)

FILE: QedisCore/QLeveldb.cc
  type qedis (line 7) | namespace qedis
    function QObject (line 38) | QObject QLeveldb::Get(const QString& key)
    function QObject (line 198) | QObject QLeveldb::_DecodeObject(const char* data, size_t len, int64_t&...
    function QString (line 266) | QString QLeveldb::_DecodeString(const char* data, size_t len)
    function QObject (line 277) | QObject QLeveldb::_DecodeHash(const char* data, size_t len)
    function QObject (line 301) | QObject QLeveldb::_DecodeList(const char* data, size_t len)
    function QObject (line 322) | QObject QLeveldb::_DecodeSet(const char* data, size_t len)
    function QObject (line 343) | QObject QLeveldb::_DecodeSSet(const char* data, size_t len)

FILE: QedisCore/QLeveldb.h
  function namespace (line 7) | namespace leveldb
  function namespace (line 12) | namespace qedis

FILE: QedisCore/QList.cc
  type qedis (line 10) | namespace qedis
    function QObject (line 13) | QObject QObject::CreateList()
    function QError (line 21) | static QError push(const vector<QString>& params, UnboundedBuffer* rep...
    function QError (line 72) | static QError GenericPop(const QString& key, ListPosition pos, QString...
    function QError (line 104) | QError lpush(const vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 109) | QError rpush(const vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 114) | QError lpushx(const vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 119) | QError rpushx(const vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 124) | QError lpop(const vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 142) | QError rpop(const vector<QString>& params, UnboundedBuffer* reply)
    function _BlockClient (line 160) | static bool _BlockClient( QClient* client, const QString& key, uint64_...
    function QError (line 173) | static QError  _GenericBlockedPop(vector<QString>::const_iterator keyB...
    function QError (line 237) | QError blpop(const vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 254) | QError  brpop(const vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 271) | QError  lindex(const vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 320) | QError lset(const vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 371) | QError llen(const vector<QString>& params, UnboundedBuffer* reply)
    function Index2Iterator (line 390) | static void Index2Iterator(long start, long end,
    function GetRange (line 428) | static size_t GetRange(long start, long end,
    function QError (line 455) | QError  ltrim(const vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 490) | QError lrange(const vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 528) | QError linsert(const vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 567) | QError  lrem(const vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 634) | QError rpoplpush(const vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 667) | QError brpoplpush(const vector<QString>& params, UnboundedBuffer* reply)

FILE: QedisCore/QList.h
  function ListPosition (line 10) | enum class ListPosition

FILE: QedisCore/QMigration.cc
  type qedis (line 6) | namespace qedis
    function ProcessItem (line 9) | static void ProcessItem(MigrationItem& item, QMigrateClient* conn)
    function QMigrationManager (line 65) | QMigrationManager& QMigrationManager::Instance()
    function PacketLength (line 235) | PacketLength QMigrateClient::_HandlePacket(const char* msg, std::size_...
    function QError (line 273) | QError migrate(const std::vector<QString>& params, UnboundedBuffer* re...

FILE: QedisCore/QMigration.h
  function namespace (line 7) | namespace ConnectionTag
  function MigrateState (line 15) | enum class MigrateState

FILE: QedisCore/QModule.cc
  type qedis (line 8) | namespace qedis
    function QString (line 20) | const QString& QModule::Name() const
    function QModuleManager (line 69) | QModuleManager& QModuleManager::Instance()
    function QModule (line 76) | QModule* QModuleManager::Load(const char* so, bool lazy) throw(std::lo...
  function QModule (line 124) | QModule* QModuleManager::GetModule(const char* so)
  function QError (line 147) | QError module(const std::vector<QString>& params, UnboundedBuffer* reply)

FILE: QedisCore/QModule.h
  function class (line 13) | class ModuleExist : public std::logic_error
  function class (line 21) | class ModuleNotExist : public std::logic_error
  function class (line 29) | class ModuleNoLoad : public std::logic_error
  function class (line 37) | class ModuleNoUnLoad : public std::logic_error
  function class (line 46) | class QModule

FILE: QedisCore/QMulti.cc
  type qedis (line 6) | namespace qedis
    function QMulti (line 9) | QMulti&    QMulti::Instance()
    function QError (line 125) | QError  watch(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 142) | QError  unwatch(const std::vector<QString>& params, UnboundedBuffer* r...
    function QError (line 150) | QError  multi(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 162) | QError  exec(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 178) | QError  discard(const std::vector<QString>& params, UnboundedBuffer* r...

FILE: QedisCore/QMulti.h
  function namespace (line 9) | namespace qedis

FILE: QedisCore/QProtoParser.cc
  type qedis (line 16) | namespace qedis
    function QParseResult (line 30) | QParseResult QProtoParser::ParseRequest(const char*& ptr, const char* ...
    function QParseResult (line 46) | QParseResult QProtoParser::_ParseMulti(const char*& ptr, const char* e...
    function QParseResult (line 59) | QParseResult QProtoParser::_ParseStrlist(const char*& ptr, const char*...
    function QParseResult (line 82) | QParseResult QProtoParser::_ParseStr(const char*& ptr, const char* end...
    function QParseResult (line 106) | QParseResult QProtoParser::_ParseStrval(const char*& ptr, const char* ...
    function QParseResult (line 124) | QParseResult QProtoParser::_ParseStrlen(const char*& ptr, const char* ...

FILE: QedisCore/QProtoParser.h
  function namespace (line 7) | namespace qedis

FILE: QedisCore/QPubsub.cc
  type qedis (line 7) | namespace qedis
    function QPubsub (line 10) | QPubsub& QPubsub::Instance()
    function QError (line 279) | QError  subscribe(const std::vector<QString>& params, UnboundedBuffer*...
    function QError (line 302) | QError  psubscribe(const std::vector<QString>& params, UnboundedBuffer...
    function QError (line 326) | QError  unsubscribe(const std::vector<QString>& params, UnboundedBuffe...
    function QError (line 367) | QError  punsubscribe(const std::vector<QString>& params, UnboundedBuff...
    function QError (line 408) | QError  publish(const std::vector<QString>& params, UnboundedBuffer* r...
    function QError (line 417) | QError  pubsub(const std::vector<QString>& params, UnboundedBuffer* re...

FILE: QedisCore/QPubsub.h
  function namespace (line 10) | namespace qedis

FILE: QedisCore/QReplication.cc
  type qedis (line 17) | namespace qedis
    function QReplication (line 20) | QReplication& QReplication::Instance()
    function QReplState (line 379) | QReplState QReplication::GetMasterState() const
    function SocketAddr (line 384) | SocketAddr QReplication::GetMasterAddr() const
    function QError (line 408) | QError replconf(const std::vector<QString>& params, UnboundedBuffer* r...
    function QError (line 536) | QError  slaveof(const std::vector<QString>& params, UnboundedBuffer* r...
    function QError (line 559) | QError  sync(const std::vector<QString>& params, UnboundedBuffer* reply)

FILE: QedisCore/QReplication.h
  type QSlaveState (line 14) | enum QSlaveState
  type QReplState (line 34) | enum QReplState

FILE: QedisCore/QServerCommand.cc
  type qedis (line 17) | namespace qedis
    function QError (line 20) | QError select(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 42) | QError dbsize(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 48) | QError flushdb(const std::vector<QString>& params, UnboundedBuffer* re...
    function QError (line 58) | QError flushall(const std::vector<QString>& params, UnboundedBuffer* r...
  function QError (line 80) | QError bgsave(const std::vector<QString>& params, UnboundedBuffer* reply)
  function QError (line 113) | QError save(const std::vector<QString>& params, UnboundedBuffer* reply)
  function QError (line 132) | QError lastsave(const std::vector<QString>& params, UnboundedBuffer* reply)
  function QError (line 138) | QError client(const std::vector<QString>& params, UnboundedBuffer* reply)
  function Suicide (line 181) | static int Suicide()
  function QError (line 189) | QError debug(const std::vector<QString>& params, UnboundedBuffer* reply)
  function QError (line 227) | QError shutdown(const std::vector<QString>& params, UnboundedBuffer* reply)
  function QError (line 240) | QError ping(const std::vector<QString>& params, UnboundedBuffer* reply)
  function QError (line 246) | QError echo(const std::vector<QString>& params, UnboundedBuffer* reply)
  function OnMemoryInfoCollect (line 252) | void OnMemoryInfoCollect(UnboundedBuffer& res)
  function OnServerInfoCollect (line 284) | void OnServerInfoCollect(UnboundedBuffer& res)
  function OnClientInfoCollect (line 310) | void OnClientInfoCollect(UnboundedBuffer& res)
  function QError (line 328) | QError info(const std::vector<QString>& params, UnboundedBuffer* reply)
  function QError (line 340) | QError monitor(const std::vector<QString>& params, UnboundedBuffer* reply)
  function QError (line 348) | QError auth(const std::vector<QString>& params, UnboundedBuffer* reply)
  function QError (line 363) | QError slowlog(const std::vector<QString>& params, UnboundedBuffer* reply)
  type ConfigType (line 418) | enum ConfigType {
  type ConfigInfo (line 425) | struct ConfigInfo
  function GetConfig (line 459) | static std::vector<QString> GetConfig(const QString& option)
  function QError (line 524) | static QError SetConfig(const QString& option, const QString& value)
  function QError (line 577) | QError config(const std::vector<QString>& params, UnboundedBuffer* reply)

FILE: QedisCore/QSet.cc
  type qedis (line 6) | namespace qedis
    function QObject (line 9) | QObject QObject::CreateSet()
    function RandomMember (line 39) | static bool RandomMember(const QSet& set, QString& res)
    function QError (line 52) | QError spop(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 82) | QError srandmember(const std::vector<QString>& params, UnboundedBuffer...
    function QError (line 100) | QError sadd(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 116) | QError  scard(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 127) | QError srem(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 146) | QError sismember(const std::vector<QString>& params, UnboundedBuffer* ...
    function QError (line 157) | QError smembers(const std::vector<QString>& params, UnboundedBuffer* r...
    function QError (line 169) | QError smove(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QSet (line 198) | QSet& QSet_diff(const QSet& l, const QSet& r, QSet& result)
    function QSet (line 211) | QSet& QSet_inter(const QSet& l, const QSet& r, QSet& result)
    function QSet (line 225) | QSet& QSet_union(const QSet& l, const QSet& r, QSet& result)
    type SetOperation (line 240) | enum SetOperation
    function _set_operation (line 247) | static void  _set_operation(const std::vector<QString>& params,
    function QError (line 291) | QError  sdiffstore(const std::vector<QString>& params, UnboundedBuffer...
    function QError (line 303) | QError sdiff(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 316) | QError sinter(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 328) | QError  sinterstore(const std::vector<QString>& params, UnboundedBuffe...
    function QError (line 341) | QError  sunion(const std::vector<QString>& params, UnboundedBuffer* re...
    function QError (line 353) | QError  sunionstore(const std::vector<QString>& params, UnboundedBuffe...
    function SScanKey (line 365) | size_t SScanKey(const QSet& qset, size_t cursor, size_t count, std::ve...

FILE: QedisCore/QSet.h
  function namespace (line 7) | namespace qedis

FILE: QedisCore/QSlaveClient.cc
  type qedis (line 6) | namespace qedis
    function PacketLength (line 29) | PacketLength QSlaveClient::_HandlePacket(const char* msg, std::size_t ...

FILE: QedisCore/QSlaveClient.h
  function namespace (line 6) | namespace qedis

FILE: QedisCore/QSlowLog.cc
  type qedis (line 8) | namespace qedis
    function QSlowLog (line 11) | QSlowLog& QSlowLog::Instance()

FILE: QedisCore/QSlowLog.h
  function namespace (line 11) | namespace qedis

FILE: QedisCore/QSortedSet.cc
  type qedis (line 6) | namespace qedis
    function QObject (line 180) | QObject QObject::CreateSSet()
    function QError (line 207) | QError zadd(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 240) | QError  zcard(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 250) | QError  zrank(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 265) | QError zrevrank(const std::vector<QString>& params, UnboundedBuffer* r...
    function QError (line 280) | QError zrem(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 296) | QError  zincrby(const std::vector<QString>& params, UnboundedBuffer* r...
    function QError (line 319) | QError zscore(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 334) | static QError GenericRange(const std::vector<QString>& params, Unbound...
    function QError (line 403) | QError zrange(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 409) | QError  zrevrange(const std::vector<QString>& params, UnboundedBuffer*...
    function QError (line 415) | static QError GenericScoreRange(const std::vector<QString>& params, Un...
    function QError (line 483) | QError  zrangebyscore(const std::vector<QString>& params, UnboundedBuf...
    function QError (line 488) | QError  zrevrangebyscore(const std::vector<QString>& params, Unbounded...
    function QError (line 493) | static QError GenericRemRange(const std::vector<QString>& params, Unbo...
    function QError (line 538) | QError zremrangebyrank(const std::vector<QString>& params, UnboundedBu...
    function QError (line 543) | QError zremrangebyscore(const std::vector<QString>& params, UnboundedB...

FILE: QedisCore/QSortedSet.h
  function namespace (line 11) | namespace qedis

FILE: QedisCore/QStore.cc
  type qedis (line 12) | namespace qedis
    function QObject (line 77) | QObject& QObject::operator= (QObject&& obj)
    function QStore (line 409) | QStore& QStore::Instance()
    function QObject (line 459) | const QObject* QStore::GetObject(const QString& key) const
    function QType (line 511) | QType  QStore::KeyType(const QString& key) const
    function RandomMember (line 520) | static bool RandomMember(const QDB& hash, QString& res, QObject** val)
    function QString (line 534) | QString QStore::RandomKey(QObject** val) const
    function QError (line 558) | QError  QStore::GetValue(const QString& key, QObject*& value, bool touch)
    function QError (line 566) | QError  QStore::GetValueByType(const QString& key, QObject*& value, QT...
    function QError (line 571) | QError  QStore::GetValueByTypeNoTouch(const QString& key, QObject*& va...
    function QError (line 576) | QError  QStore::_GetValueByType(const QString& key, QObject*& value, Q...
    function QObject (line 609) | QObject* QStore::SetValue(const QString& key, QObject&& value)
    function EvictItems (line 711) | static void EvictItems()
    function EstimateIdleTime (line 766) | uint32_t EstimateIdleTime(uint32_t lru)
    function Propogate (line 883) | void Propogate(const std::vector<QString>& params)
    function Propogate (line 911) | void Propogate(int dbno, const std::vector<QString>& params)

FILE: QedisCore/QStore.h
  function namespace (line 16) | namespace qedis
  function class (line 82) | class QStore

FILE: QedisCore/QString.cc
  type qedis (line 6) | namespace qedis
    function QObject (line 9) | QObject QObject::CreateString(const QString& value)
    function QObject (line 29) | QObject QObject::CreateString(long val)
    function DeleteString (line 40) | static void DeleteString(QString* s)
    function NotDeleteString (line 45) | static void NotDeleteString(QString* )
    function GetDecodedString (line 49) | std::unique_ptr<QString, void (*)(QString* )>
    function SetValue (line 72) | static bool SetValue(const QString& key, const QString& value, bool ex...
    function QError (line 87) | QError set(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 94) | QError setnx(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 104) | QError mset(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 122) | QError msetnx(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 150) | QError setex(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 167) | QError psetex(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 184) | QError setrange(const std::vector<QString>& params, UnboundedBuffer* r...
    function AddReply (line 225) | static void AddReply(QObject* value, UnboundedBuffer* reply)
    function QError (line 231) | QError get(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 249) | QError mget(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 265) | QError getrange(const std::vector<QString>& params, UnboundedBuffer* r...
    function QError (line 298) | QError  getset(const std::vector<QString>& params, UnboundedBuffer* re...
    function QError (line 325) | QError  append(const std::vector<QString>& params, UnboundedBuffer* re...
    function QError (line 353) | QError bitcount(const std::vector<QString>& params, UnboundedBuffer* r...
    function QError (line 398) | QError getbit(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 436) | QError setbit(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 488) | static QError ChangeFloatValue(const QString& key, float delta, Unboun...
    function QError (line 521) | QError incrbyfloat(const std::vector<QString>& params, UnboundedBuffer...
    function QError (line 533) | static QError ChangeIntValue(const QString& key, long delta, Unbounded...
    function QError (line 562) | QError incr(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 566) | QError decr(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 571) | QError incrby(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 583) | QError decrby(const std::vector<QString>& params, UnboundedBuffer* reply)
    function QError (line 595) | QError strlen(const std::vector<QString>& params, UnboundedBuffer* reply)
    type BitOp (line 610) | enum BitOp
    function QString (line 618) | static QString StringBitOp(const std::vector<const QString* >& keys, B...
    function QError (line 681) | QError  bitop(const std::vector<QString>& params, UnboundedBuffer* reply)

FILE: QedisCore/QString.h
  function namespace (line 7) | namespace qedis

FILE: QedisCore/crc64.c
  function crc64 (line 173) | uint64_t crc64(uint64_t crc, const unsigned char *s, uint64_t l) {
  function main (line 186) | int main(void) {

FILE: QedisCore/redisIntset.c
  function _intsetValueEncoding (line 49) | static uint8_t _intsetValueEncoding(int64_t v) {
  function _intsetGetEncoded (line 59) | static int64_t _intsetGetEncoded(intset *is, int pos, uint8_t enc) {
  function _intsetGet (line 80) | static int64_t _intsetGet(intset *is, int pos) {
  function _intsetSet (line 85) | static void _intsetSet(intset *is, int pos, int64_t value) {
  function intset (line 101) | intset *intsetNew(void) {
  function intset (line 109) | static intset *intsetResize(intset *is, uint32_t len) {
  function intsetSearch (line 119) | static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
  function intset (line 161) | static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
  function intsetMoveTail (line 186) | static void intsetMoveTail(intset *is, uint32_t from, uint32_t to) {
  function intset (line 208) | intset *intsetAdd(intset *is, int64_t value, uint8_t *success) {
  function intset (line 238) | intset *intsetRemove(intset *is, int64_t value, int *success) {
  function intsetFind (line 258) | uint8_t intsetFind(intset *is, int64_t value) {
  function intsetRandom (line 264) | int64_t intsetRandom(intset *is) {
  function intsetGet (line 270) | uint8_t intsetGet(intset *is, uint32_t pos, int64_t *value) {
  function intsetLen (line 279) | uint32_t intsetLen(intset *is) {
  function intsetBlobLen (line 284) | size_t intsetBlobLen(intset *is) {
  function intsetRepr (line 291) | void intsetRepr(intset *is) {
  function error (line 299) | void error(char *err) {
  function ok (line 304) | void ok(void) {
  function usec (line 308) | long long usec(void) {
  function _assert (line 315) | void _assert(char *estr, char *file, int line) {
  function intset (line 320) | intset *createSet(int bits, int size) {
  function checkConsistency (line 336) | void checkConsistency(intset *is) {
  function main (line 355) | int main(int argc, char **argv) {

FILE: QedisCore/redisIntset.h
  type intset (line 35) | typedef struct intset {

FILE: QedisCore/redisZipList.c
  type zlentry (line 158) | typedef struct zlentry {
  function zipIntSize (line 174) | static unsigned int zipIntSize(unsigned char encoding) {
  function zipEncodeLength (line 189) | static unsigned int zipEncodeLength(unsigned char *p, unsigned char enco...
  function zipPrevEncodeLength (line 253) | static unsigned int zipPrevEncodeLength(unsigned char *p, unsigned int l...
  function zipPrevEncodeLengthForceLarge (line 271) | static void zipPrevEncodeLengthForceLarge(unsigned char *p, unsigned int...
  function zipPrevLenByteDiff (line 302) | static int zipPrevLenByteDiff(unsigned char *p, unsigned int len) {
  function zipRawEntryLength (line 309) | static unsigned int zipRawEntryLength(unsigned char *p) {
  function Strtoll (line 316) | int Strtoll(const char* ptr, size_t nBytes, long long* outVal)
  function zipTryEncoding (line 330) | static int zipTryEncoding(unsigned char *entry, unsigned int entrylen, l...
  function zipSaveInteger (line 357) | static void zipSaveInteger(unsigned char *p, int64_t value, unsigned cha...
  function zipLoadInteger (line 387) | static int64_t zipLoadInteger(unsigned char *p, unsigned char encoding) {
  function zlentry (line 419) | static zlentry zipEntry(unsigned char *p) {
  function ziplistGet (line 758) | unsigned int ziplistGet(unsigned char *p, unsigned char **sstr, unsigned...
  function ziplistCompare (line 804) | unsigned int ziplistCompare(unsigned char *p, unsigned char *sstr, unsig...
  function ziplistLen (line 891) | unsigned int ziplistLen(unsigned char *zl) {
  function ziplistBlobLen (line 909) | size_t ziplistBlobLen(unsigned char *zl) {
  function ziplistRepr (line 913) | void ziplistRepr(unsigned char *zl) {
  function usec (line 1001) | long long usec(void) {
  function stress (line 1007) | void stress(int pos, int num, int maxsize, int dnum) {
  function pop (line 1030) | void pop(unsigned char *zl, int where) {
  function randstring (line 1055) | int randstring(char *target, unsigned int min, unsigned int max) {
  function verify (line 1080) | void verify(unsigned char *zl, zlentry *e) {
  function main (line 1096) | int main(int argc, char **argv) {

FILE: QedisSvr/Qedis.cc
  function Usage (line 45) | static void Usage()
  function QdbCron (line 184) | static void QdbCron()
  function LoadDbFromDisk (line 217) | static void LoadDbFromDisk()
  function OnConnectClusterFail (line 240) | static void OnConnectClusterFail(const std::vector<SocketAddr>& addrs, s...
  function CheckChild (line 390) | static void CheckChild()
  function main (line 446) | int main(int ac, char* av[])

FILE: QedisSvr/Qedis.h
  function class (line 13) | class Qedis : public Server

FILE: UnitTest/QGlobRegex_unittest.cc
  function TEST_CASE (line 6) | TEST_CASE(regex_star)
  function TEST_CASE (line 20) | TEST_CASE(regex_question)
  function TEST_CASE (line 28) | TEST_CASE(regex_bracket)
  function TEST_CASE (line 61) | TEST_CASE(regex_star_brackets)
  function TEST_CASE (line 71) | TEST_CASE(regex_search)
  function TEST_CASE (line 81) | TEST_CASE(regex_strange)

FILE: UnitTest/UnitTest.cc
  type Color (line 4) | enum Color
  function SetColor (line 16) | void SetColor(Color c)
  function UnitTestBase (line 38) | UnitTestBase& UnitTestBase::SetInfo(const std::string& exprInfo, bool pa...
  function UnitTestManager (line 77) | UnitTestManager& UnitTestManager::Instance()
  function main (line 127) | int main()

FILE: UnitTest/UnitTest.h
  function class (line 8) | class UnitTestBase
  function class (line 60) | class MsgHelper
  function class (line 97) | class UnitTestManager

FILE: cluster/ananas/future/Future.h
  function namespace (line 13) | namespace ananas
  type FutureWrongState (line 367) | struct FutureWrongState {}
  type FutureWrongState (line 389) | struct FutureWrongState {}
  type FutureWrongState (line 449) | struct FutureWrongState {}
  function SetCallback (line 481) | void SetCallback(std::function<void (Try<T>&& )>&& func)
  function SetOnTimeout (line 486) | void SetOnTimeout(std::function<void (internal::TimeoutCallback&& )>&& f...
  function OnTimeout (line 503) | void OnTimeout(std::chrono::milliseconds duration,
  function Future (line 549) | inline Future<void> MakeReadyFuture()
  type CollectAllContext (line 593) | struct CollectAllContext
  function ctx (line 607) | auto ctx = std::make_shared<CollectAllContext>(std::distance(first, last));
  type CollectAnyContext (line 637) | struct CollectAnyContext
  type CollectNContext (line 677) | struct CollectNContext

FILE: cluster/ananas/future/Helper.h
  function namespace (line 27) | namespace ananas

FILE: cluster/ananas/future/Try.h
  function namespace (line 29) | namespace ananas
  type UninitializedTry (line 181) | struct UninitializedTry {}
  function State (line 208) | enum class State

FILE: cluster/ananas/net/Acceptor.cc
  type ananas (line 10) | namespace ananas
    type internal (line 12) | namespace internal
      type sockaddr (line 61) | struct sockaddr
      type sockaddr (line 171) | struct sockaddr

FILE: cluster/ananas/net/Acceptor.h
  function namespace (line 8) | namespace ananas

FILE: cluster/ananas/net/AnanasDebug.cc
  type ananas (line 3) | namespace ananas
    type internal (line 6) | namespace internal
      function InitDebugLog (line 12) | void InitDebugLog(unsigned int level)

FILE: cluster/ananas/net/AnanasDebug.h
  function namespace (line 7) | namespace ananas

FILE: cluster/ananas/net/AnanasLogo.h
  function namespace (line 4) | namespace ananas

FILE: cluster/ananas/net/Buffer.cc
  type ananas (line 7) | namespace ananas
    function RoundUp2Power (line 10) | inline static std::size_t RoundUp2Power(std::size_t size)
    function Buffer (line 184) | Buffer& Buffer::operator= (Buffer&& other)
    function Buffer (line 189) | Buffer& Buffer::_MoveFrom(Buffer&& other)

FILE: cluster/ananas/net/Buffer.h
  function namespace (line 9) | namespace ananas
  function Empty (line 72) | struct BufferVector

FILE: cluster/ananas/net/Connection.cc
  type ananas (line 12) | namespace ananas
    type iovec (line 113) | struct iovec
  function WriteV (line 363) | int WriteV(int sock, const std::vector<iovec>& buffers)
  function ConsumeBufferVectors (line 409) | void ConsumeBufferVectors(BufferVector& buffers, size_t toSkippedBytes)
  function CollectBuffer (line 436) | void CollectBuffer(const std::vector<iovec>& buffers, size_t skipped, Bu...

FILE: cluster/ananas/net/Connection.h
  function namespace (line 14) | namespace internal
  type class (line 20) | enum class
  function class (line 27) | class Connection : public internal::EventSource

FILE: cluster/ananas/net/Connector.cc
  type ananas (line 10) | namespace ananas
    type internal (line 12) | namespace internal
      type sockaddr (line 72) | struct sockaddr

FILE: cluster/ananas/net/Connector.h
  function namespace (line 11) | namespace internal

FILE: cluster/ananas/net/DatagramSocket.cc
  type ananas (line 8) | namespace ananas
    type sockaddr (line 47) | struct sockaddr
    type sockaddr (line 88) | struct sockaddr
    type sockaddr (line 122) | struct sockaddr

FILE: cluster/ananas/net/DatagramSocket.h
  function namespace (line 10) | namespace ananas

FILE: cluster/ananas/net/Epoller.cc
  type ananas (line 10) | namespace ananas
    type internal (line 12) | namespace internal
      type Epoll (line 15) | namespace Epoll
        function AddSocket (line 19) | bool AddSocket(int epfd, int socket, uint32_t events, void* ptr)
        function DelSocket (line 36) | bool DelSocket(int epfd, int socket)
        function ModSocket (line 45) | bool ModSocket(int epfd, int socket, uint32_t events, void* ptr)

FILE: cluster/ananas/net/Epoller.h
  function namespace (line 10) | namespace ananas

FILE: cluster/ananas/net/EventLoop.cc
  function SignalHandler (line 26) | static void SignalHandler(int num)
  function InitSignal (line 33) | static void InitSignal()
  type ananas (line 52) | namespace ananas

FILE: cluster/ananas/net/EventLoop.h
  function namespace (line 15) | namespace ananas

FILE: cluster/ananas/net/Kqueue.cc
  type ananas (line 9) | namespace ananas
    type internal (line 11) | namespace internal
      type kevent (line 29) | struct kevent
      type kevent (line 50) | struct kevent
      type timespec (line 90) | struct timespec
      type timespec (line 91) | struct timespec

FILE: cluster/ananas/net/Kqueue.h
  function namespace (line 10) | namespace ananas

FILE: cluster/ananas/net/Poller.h
  function namespace (line 7) | namespace ananas

FILE: cluster/ananas/net/Socket.cc
  type ananas (line 11) | namespace ananas
    function CreateUDPSocket (line 20) | int CreateUDPSocket()
    function CreateTCPSocket (line 25) | int CreateTCPSocket()
    function CreateSocketPair (line 30) | bool CreateSocketPair(int& readSock, int& writeSock)
    function CloseSocket (line 43) | void CloseSocket(int& sock)
    function SetNonBlock (line 52) | void SetNonBlock(int sock, bool nonblock)
    function SetNodelay (line 63) | void SetNodelay(int sock, bool enable)
    function SetSndBuf (line 69) | void SetSndBuf(int sock, socklen_t winsize)
    function SetRcvBuf (line 74) | void SetRcvBuf(int sock, socklen_t winsize)
    function SetReuseAddr (line 79) | void SetReuseAddr(int sock)
    function GetLocalAddr (line 85) | bool GetLocalAddr(int sock, SocketAddr& addr)
    function GetPeerAddr (line 102) | bool GetPeerAddr(int sock, SocketAddr& addr)
    function in_addr_t (line 118) | in_addr_t GetLocalAddrInfo()
    function rlim_t (line 156) | rlim_t GetMaxOpenFd()
    function SetMaxOpenFd (line 166) | bool SetMaxOpenFd(rlim_t maxfdPlus1)
    function ConvertIp (line 184) | std::string ConvertIp(const char* ip)

FILE: cluster/ananas/net/Socket.h
  function namespace (line 11) | namespace ananas
  function Init (line 48) | void Init(const sockaddr_in& addr)
  function Init (line 53) | void Init(uint32_t netip, uint16_t netport)
  function Init (line 60) | void Init(const char* ip, uint16_t hostport)

FILE: cluster/ananas/net/ThreadPool.cc
  type ananas (line 3) | namespace ananas
    function ThreadPool (line 24) | ThreadPool& ThreadPool::Instance()

FILE: cluster/ananas/net/ThreadPool.h
  function namespace (line 13) | namespace ananas

FILE: cluster/ananas/net/TimeUtil.cc
  type ananas (line 4) | namespace ananas

FILE: cluster/ananas/net/TimeUtil.h
  function namespace (line 10) | namespace ananas

FILE: cluster/ananas/net/Timer.cc
  type ananas (line 5) | namespace ananas
    type internal (line 7) | namespace internal
      function DurationMs (line 71) | DurationMs TimerManager::NearestTimer() const
      function TimerId (line 128) | TimerId TimerManager::Timer::Id() const

FILE: cluster/ananas/net/Timer.h
  function namespace (line 26) | namespace internal

FILE: cluster/ananas/net/Typedefs.h
  function namespace (line 6) | namespace ananas

FILE: cluster/ananas/net/log/Logger.cc
  type ananas (line 14) | namespace ananas
    type LogColor (line 20) | enum LogColor
    function MakeDir (line 40) | static bool MakeDir(const char* dir)
    type LogLevel (line 139) | enum LogLevel
    function Logger (line 279) | Logger&  Logger::operator<< (const char* msg)
    function Logger (line 294) | Logger&  Logger::operator<< (const unsigned char* msg)
    function Logger (line 299) | Logger&  Logger::operator<< (const std::string& msg)
    function Logger (line 304) | Logger&  Logger::operator<< (void* ptr)
    function Logger (line 320) | Logger&  Logger::operator<< (unsigned char a)
    function Logger (line 335) | Logger&  Logger::operator<< (char a)
    function Logger (line 349) | Logger&  Logger::operator<< (unsigned short a)
    function Logger (line 363) | Logger&  Logger::operator<< (short a)
    function Logger (line 377) | Logger&  Logger::operator<< (unsigned int a)
    function Logger (line 391) | Logger&  Logger::operator<< (int a)
    function Logger (line 405) | Logger&  Logger::operator<< (unsigned long a)
    function Logger (line 419) | Logger&  Logger::operator<< (long a)
    function Logger (line 433) | Logger&  Logger::operator<< (unsigned long long a)
    function Logger (line 447) | Logger&  Logger::operator<< (long long a)
    function Logger (line 461) | Logger&  Logger::operator<< (double a)
    function LogManager (line 603) | LogManager& LogManager::Instance()
    function Logger (line 729) | Logger& LogHelper::operator=(Logger& log)

FILE: cluster/ananas/net/log/Logger.h
  type LogLevel (line 21) | enum LogLevel
  type LogDest (line 31) | enum LogDest
  function namespace (line 38) | namespace ananas

FILE: cluster/ananas/net/log/MmapFile.cc
  type ananas (line 13) | namespace ananas
    type internal (line 15) | namespace internal
      type stat (line 68) | struct stat

FILE: cluster/ananas/net/log/MmapFile.h
  function namespace (line 6) | namespace ananas

FILE: cluster/ananas/util/Delegate.h
  function namespace (line 8) | namespace ananas

FILE: cluster/ananas/util/Scheduler.h
  function namespace (line 4) | namespace ananas

FILE: cluster/ananas/util/Util.h
  function namespace (line 9) | namespace ananas

FILE: cluster/cluster_conn/ClusterConn.h
  function namespace (line 4) | namespace qedis

FILE: cluster/cluster_conn/zookeeper/ZkResponse.h
  type CreateRsp (line 22) | struct CreateRsp
  function CreateRsp (line 27) | inline
  type ChildrenRsp (line 35) | struct ChildrenRsp
  function ChildrenRsp (line 42) | inline
  type DataRsp (line 57) | struct DataRsp
  function DataRsp (line 64) | inline
  type buffer (line 83) | struct buffer
  type buffer (line 88) | struct buffer

FILE: cluster/cluster_conn/zookeeper/ZookeeperContext.cc
  function deserialize_prime_response (line 14) | static void deserialize_prime_response(struct prime_struct *req, char* b...
  function serialize_prime_connect (line 40) | static void serialize_prime_connect(struct connect_req *req, char* buffer)
  type qedis (line 69) | namespace qedis
    type ReplyHeader (line 118) | struct ReplyHeader
    type iarchive (line 119) | struct iarchive
    type connect_req (line 315) | struct connect_req
    type ananas::SliceVector (line 328) | struct ananas::SliceVector
    type oarchive (line 340) | struct oarchive
    type RequestHeader (line 341) | struct RequestHeader
    type ACL (line 349) | struct ACL
    type ACL_vector (line 350) | struct ACL_vector
    type oarchive (line 357) | struct oarchive
    type RequestHeader (line 358) | struct RequestHeader
    type CreateRequest (line 366) | struct CreateRequest
    type oarchive (line 389) | struct oarchive
    type RequestHeader (line 391) | struct RequestHeader
    type GetChildren2Request (line 392) | struct GetChildren2Request
    type oarchive (line 416) | struct oarchive
    type RequestHeader (line 418) | struct RequestHeader
    type GetDataRequest (line 419) | struct GetDataRequest
    type Request (line 444) | struct Request
    type oarchive (line 455) | struct oarchive
    type ananas::SliceVector (line 459) | struct ananas::SliceVector

FILE: cluster/cluster_conn/zookeeper/ZookeeperContext.h
  type oarchive (line 10) | struct oarchive
  type iarchive (line 11) | struct iarchive
  function namespace (line 13) | namespace ananas
  type oarchive (line 56) | struct oarchive
  function _GetXid (line 60) | int _GetXid() const;

FILE: cluster/cluster_conn/zookeeper/proto.h
  type connect_req (line 51) | struct connect_req {
  type prime_struct (line 62) | struct prime_struct {
  type ZOO_ERRORS (line 71) | enum ZOO_ERRORS {

FILE: cluster/cluster_conn/zookeeper/recordio.c
  function deallocate_String (line 26) | void deallocate_String(char **s)
  function deallocate_Buffer (line 33) | void deallocate_Buffer(struct buffer *b)
  type buff_struct (line 40) | struct buff_struct {
  function resize_buffer (line 46) | static int resize_buffer(struct buff_struct *s, int newlen)
  function oa_start_record (line 61) | int oa_start_record(struct oarchive *oa, const char *tag)
  function oa_end_record (line 65) | int oa_end_record(struct oarchive *oa, const char *tag)
  function oa_serialize_int (line 69) | int oa_serialize_int(struct oarchive *oa, const char *tag, const int32_t...
  function htonll (line 82) | int64_t htonll(int64_t v)
  function oa_serialize_long (line 99) | int oa_serialize_long(struct oarchive *oa, const char *tag, const int64_...
  function oa_start_vector (line 111) | int oa_start_vector(struct oarchive *oa, const char *tag, const int32_t ...
  function oa_end_vector (line 115) | int oa_end_vector(struct oarchive *oa, const char *tag)
  function oa_serialize_bool (line 119) | int oa_serialize_bool(struct oarchive *oa, const char *name, const int32...
  function oa_serialize_buffer (line 133) | int oa_serialize_buffer(struct oarchive *oa, const char *name,
  function oa_serialize_string (line 159) | int oa_serialize_string(struct oarchive *oa, const char *name, char **s)
  function ia_start_record (line 181) | int ia_start_record(struct iarchive *ia, const char *tag)
  function ia_end_record (line 185) | int ia_end_record(struct iarchive *ia, const char *tag)
  function ia_deserialize_int (line 189) | int ia_deserialize_int(struct iarchive *ia, const char *tag, int32_t *co...
  function ia_deserialize_long (line 201) | int ia_deserialize_long(struct iarchive *ia, const char *tag, int64_t *c...
  function ia_start_vector (line 214) | int ia_start_vector(struct iarchive *ia, const char *tag, int32_t *count)
  function ia_end_vector (line 218) | int ia_end_vector(struct iarchive *ia, const char *tag)
  function ia_deserialize_bool (line 222) | int ia_deserialize_bool(struct iarchive *ia, const char *name, int32_t *v)
  function ia_deserialize_buffer (line 235) | int ia_deserialize_buffer(struct iarchive *ia, const char *name,
  function ia_deserialize_string (line 258) | int ia_deserialize_string(struct iarchive *ia, const char *name, char **s)
  type iarchive (line 281) | struct iarchive
  type oarchive (line 289) | struct oarchive
  type iarchive (line 297) | struct iarchive
  type iarchive (line 299) | struct iarchive
  type buff_struct (line 300) | struct buff_struct
  type buff_struct (line 300) | struct buff_struct
  type oarchive (line 314) | struct oarchive
  type oarchive (line 316) | struct oarchive
  type buff_struct (line 317) | struct buff_struct
  type buff_struct (line 317) | struct buff_struct
  function close_buffer_iarchive (line 331) | void close_buffer_iarchive(struct iarchive **ia)
  function close_buffer_oarchive (line 338) | void close_buffer_oarchive(struct oarchive **oa, int free_buffer)
  type oarchive (line 351) | struct oarchive
  type buff_struct (line 353) | struct buff_struct
  function get_buffer_len (line 356) | int get_buffer_len(struct oarchive *oa)

FILE: cluster/cluster_conn/zookeeper/recordio.h
  type buffer (line 28) | struct buffer {
  type buffer (line 34) | struct buffer
  type iarchive (line 36) | struct iarchive {
  type oarchive (line 49) | struct oarchive {
  type oarchive (line 64) | struct oarchive
  type oarchive (line 65) | struct oarchive
  type iarchive (line 66) | struct iarchive
  type iarchive (line 67) | struct iarchive
  type oarchive (line 68) | struct oarchive
  type oarchive (line 69) | struct oarchive

FILE: cluster/cluster_conn/zookeeper/zookeeper.jute.c
  function serialize_Id (line 22) | int serialize_Id(struct oarchive *out, const char *tag, struct Id *v){
  function deserialize_Id (line 30) | int deserialize_Id(struct iarchive *in, const char *tag, struct Id*v){
  function deallocate_Id (line 38) | void deallocate_Id(struct Id*v){
  function serialize_ACL (line 42) | int serialize_ACL(struct oarchive *out, const char *tag, struct ACL *v){
  function deserialize_ACL (line 50) | int deserialize_ACL(struct iarchive *in, const char *tag, struct ACL*v){
  function deallocate_ACL (line 58) | void deallocate_ACL(struct ACL*v){
  function serialize_Stat (line 61) | int serialize_Stat(struct oarchive *out, const char *tag, struct Stat *v){
  function deserialize_Stat (line 78) | int deserialize_Stat(struct iarchive *in, const char *tag, struct Stat*v){
  function deallocate_Stat (line 95) | void deallocate_Stat(struct Stat*v){
  function serialize_StatPersisted (line 97) | int serialize_StatPersisted(struct oarchive *out, const char *tag, struc...
  function deserialize_StatPersisted (line 112) | int deserialize_StatPersisted(struct iarchive *in, const char *tag, stru...
  function deallocate_StatPersisted (line 127) | void deallocate_StatPersisted(struct StatPersisted*v){
  function serialize_StatPersistedV1 (line 129) | int serialize_StatPersistedV1(struct oarchive *out, const char *tag, str...
  function deserialize_StatPersistedV1 (line 143) | int deserialize_StatPersistedV1(struct iarchive *in, const char *tag, st...
  function deallocate_StatPersistedV1 (line 157) | void deallocate_StatPersistedV1(struct StatPersistedV1*v){
  function serialize_ConnectRequest (line 159) | int serialize_ConnectRequest(struct oarchive *out, const char *tag, stru...
  function deserialize_ConnectRequest (line 170) | int deserialize_ConnectRequest(struct iarchive *in, const char *tag, str...
  function deallocate_ConnectRequest (line 181) | void deallocate_ConnectRequest(struct ConnectRequest*v){
  function serialize_ConnectResponse (line 184) | int serialize_ConnectResponse(struct oarchive *out, const char *tag, str...
  function deserialize_ConnectResponse (line 194) | int deserialize_ConnectResponse(struct iarchive *in, const char *tag, st...
  function deallocate_ConnectResponse (line 204) | void deallocate_ConnectResponse(struct ConnectResponse*v){
  function allocate_String_vector (line 207) | int allocate_String_vector(struct String_vector *v, int32_t len) {
  function deallocate_String_vector (line 217) | int deallocate_String_vector(struct String_vector *v) {
  function serialize_String_vector (line 228) | int serialize_String_vector(struct oarchive *out, const char *tag, struc...
  function deserialize_String_vector (line 240) | int deserialize_String_vector(struct iarchive *in, const char *tag, stru...
  function serialize_SetWatches (line 252) | int serialize_SetWatches(struct oarchive *out, const char *tag, struct S...
  function deserialize_SetWatches (line 262) | int deserialize_SetWatches(struct iarchive *in, const char *tag, struct ...
  function deallocate_SetWatches (line 272) | void deallocate_SetWatches(struct SetWatches*v){
  function serialize_RequestHeader (line 277) | int serialize_RequestHeader(struct oarchive *out, const char *tag, struc...
  function deserialize_RequestHeader (line 285) | int deserialize_RequestHeader(struct iarchive *in, const char *tag, stru...
  function deallocate_RequestHeader (line 293) | void deallocate_RequestHeader(struct RequestHeader*v){
  function serialize_MultiHeader (line 295) | int serialize_MultiHeader(struct oarchive *out, const char *tag, struct ...
  function deserialize_MultiHeader (line 304) | int deserialize_MultiHeader(struct iarchive *in, const char *tag, struct...
  function deallocate_MultiHeader (line 313) | void deallocate_MultiHeader(struct MultiHeader*v){
  function serialize_AuthPacket (line 315) | int serialize_AuthPacket(struct oarchive *out, const char *tag, struct A...
  function deserialize_AuthPacket (line 324) | int deserialize_AuthPacket(struct iarchive *in, const char *tag, struct ...
  function deallocate_AuthPacket (line 333) | void deallocate_AuthPacket(struct AuthPacket*v){
  function serialize_ReplyHeader (line 337) | int serialize_ReplyHeader(struct oarchive *out, const char *tag, struct ...
  function deserialize_ReplyHeader (line 346) | int deserialize_ReplyHeader(struct iarchive *in, const char *tag, struct...
  function deallocate_ReplyHeader (line 355) | void deallocate_ReplyHeader(struct ReplyHeader*v){
  function serialize_GetDataRequest (line 357) | int serialize_GetDataRequest(struct oarchive *out, const char *tag, stru...
  function deserialize_GetDataRequest (line 365) | int deserialize_GetDataRequest(struct iarchive *in, const char *tag, str...
  function deallocate_GetDataRequest (line 373) | void deallocate_GetDataRequest(struct GetDataRequest*v){
  function serialize_SetDataRequest (line 376) | int serialize_SetDataRequest(struct oarchive *out, const char *tag, stru...
  function deserialize_SetDataRequest (line 385) | int deserialize_SetDataRequest(struct iarchive *in, const char *tag, str...
  function deallocate_SetDataRequest (line 394) | void deallocate_SetDataRequest(struct SetDataRequest*v){
  function serialize_SetDataResponse (line 398) | int serialize_SetDataResponse(struct oarchive *out, const char *tag, str...
  function deserialize_SetDataResponse (line 405) | int deserialize_SetDataResponse(struct iarchive *in, const char *tag, st...
  function deallocate_SetDataResponse (line 412) | void deallocate_SetDataResponse(struct SetDataResponse*v){
  function serialize_GetSASLRequest (line 415) | int serialize_GetSASLRequest(struct oarchive *out, const char *tag, stru...
  function deserialize_GetSASLRequest (line 422) | int deserialize_GetSASLRequest(struct iarchive *in, const char *tag, str...
  function deallocate_GetSASLRequest (line 429) | void deallocate_GetSASLRequest(struct GetSASLRequest*v){
  function serialize_SetSASLRequest (line 432) | int serialize_SetSASLRequest(struct oarchive *out, const char *tag, stru...
  function deserialize_SetSASLRequest (line 439) | int deserialize_SetSASLRequest(struct iarchive *in, const char *tag, str...
  function deallocate_SetSASLRequest (line 446) | void deallocate_SetSASLRequest(struct SetSASLRequest*v){
  function serialize_SetSASLResponse (line 449) | int serialize_SetSASLResponse(struct oarchive *out, const char *tag, str...
  function deserialize_SetSASLResponse (line 456) | int deserialize_SetSASLResponse(struct iarchive *in, const char *tag, st...
  function deallocate_SetSASLResponse (line 463) | void deallocate_SetSASLResponse(struct SetSASLResponse*v){
  function allocate_ACL_vector (line 466) | int allocate_ACL_vector(struct ACL_vector *v, int32_t len) {
  function deallocate_ACL_vector (line 476) | int deallocate_ACL_vector(struct ACL_vector *v) {
  function serialize_ACL_vector (line 487) | int serialize_ACL_vector(struct oarchive *out, const char *tag, struct A...
  function deserialize_ACL_vector (line 499) | int deserialize_ACL_vector(struct iarchive *in, const char *tag, struct ...
  function serialize_CreateRequest (line 511) | int serialize_CreateRequest(struct oarchive *out, const char *tag, struc...
  function deserialize_CreateRequest (line 521) | int deserialize_CreateRequest(struct iarchive *in, const char *tag, stru...
  function deallocate_CreateRequest (line 531) | void deallocate_CreateRequest(struct CreateRequest*v){
  function serialize_DeleteRequest (line 536) | int serialize_DeleteRequest(struct oarchive *out, const char *tag, struc...
  function deserialize_DeleteRequest (line 544) | int deserialize_DeleteRequest(struct iarchive *in, const char *tag, stru...
  function deallocate_DeleteRequest (line 552) | void deallocate_DeleteRequest(struct DeleteRequest*v){
  function serialize_GetChildrenRequest (line 555) | int serialize_GetChildrenRequest(struct oarchive *out, const char *tag, ...
  function deserialize_GetChildrenRequest (line 563) | int deserialize_GetChildrenRequest(struct iarchive *in, const char *tag,...
  function deallocate_GetChildrenRequest (line 571) | void deallocate_GetChildrenRequest(struct GetChildrenRequest*v){
  function serialize_GetChildren2Request (line 574) | int serialize_GetChildren2Request(struct oarchive *out, const char *tag,...
  function deserialize_GetChildren2Request (line 582) | int deserialize_GetChildren2Request(struct iarchive *in, const char *tag...
  function deallocate_GetChildren2Request (line 590) | void deallocate_GetChildren2Request(struct GetChildren2Request*v){
  function serialize_CheckVersionRequest (line 593) | int serialize_CheckVersionRequest(struct oarchive *out, const char *tag,...
  function deserialize_CheckVersionRequest (line 601) | int deserialize_CheckVersionRequest(struct iarchive *in, const char *tag...
  function deallocate_CheckVersionRequest (line 609) | void deallocate_CheckVersionRequest(struct CheckVersionRequest*v){
  function serialize_GetMaxChildrenRequest (line 612) | int serialize_GetMaxChildrenRequest(struct oarchive *out, const char *ta...
  function deserialize_GetMaxChildrenRequest (line 619) | int deserialize_GetMaxChildrenRequest(struct iarchive *in, const char *t...
  function deallocate_GetMaxChildrenRequest (line 626) | void deallocate_GetMaxChildrenRequest(struct GetMaxChildrenRequest*v){
  function serialize_GetMaxChildrenResponse (line 629) | int serialize_GetMaxChildrenResponse(struct oarchive *out, const char *t...
  function deserialize_GetMaxChildrenResponse (line 636) | int deserialize_GetMaxChildrenResponse(struct iarchive *in, const char *...
  function deallocate_GetMaxChildrenResponse (line 643) | void deallocate_GetMaxChildrenResponse(struct GetMaxChildrenResponse*v){
  function serialize_SetMaxChildrenRequest (line 645) | int serialize_SetMaxChildrenRequest(struct oarchive *out, const char *ta...
  function deserialize_SetMaxChildrenRequest (line 653) | int deserialize_SetMaxChildrenRequest(struct iarchive *in, const char *t...
  function deallocate_SetMaxChildrenRequest (line 661) | void deallocate_SetMaxChildrenRequest(struct SetMaxChildrenRequest*v){
  function serialize_SyncRequest (line 664) | int serialize_SyncRequest(struct oarchive *out, const char *tag, struct ...
  function deserialize_SyncRequest (line 671) | int deserialize_SyncRequest(struct iarchive *in, const char *tag, struct...
  function deallocate_SyncRequest (line 678) | void deallocate_SyncRequest(struct SyncRequest*v){
  function serialize_SyncResponse (line 681) | int serialize_SyncResponse(struct oarchive *out, const char *tag, struct...
  function deserialize_SyncResponse (line 688) | int deserialize_SyncResponse(struct iarchive *in, const char *tag, struc...
  function deallocate_SyncResponse (line 695) | void deallocate_SyncResponse(struct SyncResponse*v){
  function serialize_GetACLRequest (line 698) | int serialize_GetACLRequest(struct oarchive *out, const char *tag, struc...
  function deserialize_GetACLRequest (line 705) | int deserialize_GetACLRequest(struct iarchive *in, const char *tag, stru...
  function deallocate_GetACLRequest (line 712) | void deallocate_GetACLRequest(struct GetACLRequest*v){
  function serialize_SetACLRequest (line 715) | int serialize_SetACLRequest(struct oarchive *out, const char *tag, struc...
  function deserialize_SetACLRequest (line 724) | int deserialize_SetACLRequest(struct iarchive *in, const char *tag, stru...
  function deallocate_SetACLRequest (line 733) | void deallocate_SetACLRequest(struct SetACLRequest*v){
  function serialize_SetACLResponse (line 737) | int serialize_SetACLResponse(struct oarchive *out, const char *tag, stru...
  function deserialize_SetACLResponse (line 744) | int deserialize_SetACLResponse(struct iarchive *in, const char *tag, str...
  function deallocate_SetACLResponse (line 751) | void deallocate_SetACLResponse(struct SetACLResponse*v){
  function serialize_WatcherEvent (line 754) | int serialize_WatcherEvent(struct oarchive *out, const char *tag, struct...
  function deserialize_WatcherEvent (line 763) | int deserialize_WatcherEvent(struct iarchive *in, const char *tag, struc...
  function deallocate_WatcherEvent (line 772) | void deallocate_WatcherEvent(struct WatcherEvent*v){
  function serialize_ErrorResponse (line 775) | int serialize_ErrorResponse(struct oarchive *out, const char *tag, struc...
  function deserialize_ErrorResponse (line 782) | int deserialize_ErrorResponse(struct iarchive *in, const char *tag, stru...
  function deallocate_ErrorResponse (line 789) | void deallocate_ErrorResponse(struct ErrorResponse*v){
  function serialize_CreateResponse (line 791) | int serialize_CreateResponse(struct oarchive *out, const char *tag, stru...
  function deserialize_CreateResponse (line 798) | int deserialize_CreateResponse(struct iarchive *in, const char *tag, str...
  function deallocate_CreateResponse (line 805) | void deallocate_CreateResponse(struct CreateResponse*v){
  function serialize_ExistsRequest (line 808) | int serialize_ExistsRequest(struct oarchive *out, const char *tag, struc...
  function deserialize_ExistsRequest (line 816) | int deserialize_ExistsRequest(struct iarchive *in, const char *tag, stru...
  function deallocate_ExistsRequest (line 824) | void deallocate_ExistsRequest(struct ExistsRequest*v){
  function serialize_ExistsResponse (line 827) | int serialize_ExistsResponse(struct oarchive *out, const char *tag, stru...
  function deserialize_ExistsResponse (line 834) | int deserialize_ExistsResponse(struct iarchive *in, const char *tag, str...
  function deallocate_ExistsResponse (line 841) | void deallocate_ExistsResponse(struct ExistsResponse*v){
  function serialize_GetDataResponse (line 844) | int serialize_GetDataResponse(struct oarchive *out, const char *tag, str...
  function deserialize_GetDataResponse (line 852) | int deserialize_GetDataResponse(struct iarchive *in, const char *tag, st...
  function deallocate_GetDataResponse (line 860) | void deallocate_GetDataResponse(struct GetDataResponse*v){
  function serialize_GetChildrenResponse (line 864) | int serialize_GetChildrenResponse(struct oarchive *out, const char *tag,...
  function deserialize_GetChildrenResponse (line 871) | int deserialize_GetChildrenResponse(struct iarchive *in, const char *tag...
  function deallocate_GetChildrenResponse (line 878) | void deallocate_GetChildrenResponse(struct GetChildrenResponse*v){
  function serialize_GetChildren2Response (line 881) | int serialize_GetChildren2Response(struct oarchive *out, const char *tag...
  function deserialize_GetChildren2Response (line 889) | int deserialize_GetChildren2Response(struct iarchive *in, const char *ta...
  function deallocate_GetChildren2Response (line 897) | void deallocate_GetChildren2Response(struct GetChildren2Response*v){
  function serialize_GetACLResponse (line 901) | int serialize_GetACLResponse(struct oarchive *out, const char *tag, stru...
  function deserialize_GetACLResponse (line 909) | int deserialize_GetACLResponse(struct iarchive *in, const char *tag, str...
  function deallocate_GetACLResponse (line 917) | void deallocate_GetACLResponse(struct GetACLResponse*v){
  function serialize_LearnerInfo (line 921) | int serialize_LearnerInfo(struct oarchive *out, const char *tag, struct ...
  function deserialize_LearnerInfo (line 929) | int deserialize_LearnerInfo(struct iarchive *in, const char *tag, struct...
  function deallocate_LearnerInfo (line 937) | void deallocate_LearnerInfo(struct LearnerInfo*v){
  function allocate_Id_vector (line 939) | int allocate_Id_vector(struct Id_vector *v, int32_t len) {
  function deallocate_Id_vector (line 949) | int deallocate_Id_vector(struct Id_vector *v) {
  function serialize_Id_vector (line 960) | int serialize_Id_vector(struct oarchive *out, const char *tag, struct Id...
  function deserialize_Id_vector (line 972) | int deserialize_Id_vector(struct iarchive *in, const char *tag, struct I...
  function serialize_QuorumPacket (line 984) | int serialize_QuorumPacket(struct oarchive *out, const char *tag, struct...
  function deserialize_QuorumPacket (line 994) | int deserialize_QuorumPacket(struct iarchive *in, const char *tag, struc...
  function deallocate_QuorumPacket (line 1004) | void deallocate_QuorumPacket(struct QuorumPacket*v){
  function serialize_FileHeader (line 1008) | int serialize_FileHeader(struct oarchive *out, const char *tag, struct F...
  function deserialize_FileHeader (line 1017) | int deserialize_FileHeader(struct iarchive *in, const char *tag, struct ...
  function deallocate_FileHeader (line 1026) | void deallocate_FileHeader(struct FileHeader*v){
  function serialize_TxnHeader (line 1028) | int serialize_TxnHeader(struct oarchive *out, const char *tag, struct Tx...
  function deserialize_TxnHeader (line 1039) | int deserialize_TxnHeader(struct iarchive *in, const char *tag, struct T...
  function deallocate_TxnHeader (line 1050) | void deallocate_TxnHeader(struct TxnHeader*v){
  function serialize_CreateTxnV0 (line 1052) | int serialize_CreateTxnV0(struct oarchive *out, const char *tag, struct ...
  function deserialize_CreateTxnV0 (line 1062) | int deserialize_CreateTxnV0(struct iarchive *in, const char *tag, struct...
  function deallocate_CreateTxnV0 (line 1072) | void deallocate_CreateTxnV0(struct CreateTxnV0*v){
  function serialize_CreateTxn (line 1077) | int serialize_CreateTxn(struct oarchive *out, const char *tag, struct Cr...
  function deserialize_CreateTxn (line 1088) | int deserialize_CreateTxn(struct iarchive *in, const char *tag, struct C...
  function deallocate_CreateTxn (line 1099) | void deallocate_CreateTxn(struct CreateTxn*v){
  function serialize_DeleteTxn (line 1104) | int serialize_DeleteTxn(struct oarchive *out, const char *tag, struct De...
  function deserialize_DeleteTxn (line 1111) | int deserialize_DeleteTxn(struct iarchive *in, const char *tag, struct D...
  function deallocate_DeleteTxn (line 1118) | void deallocate_DeleteTxn(struct DeleteTxn*v){
  function serialize_SetDataTxn (line 1121) | int serialize_SetDataTxn(struct oarchive *out, const char *tag, struct S...
  function deserialize_SetDataTxn (line 1130) | int deserialize_SetDataTxn(struct iarchive *in, const char *tag, struct ...
  function deallocate_SetDataTxn (line 1139) | void deallocate_SetDataTxn(struct SetDataTxn*v){
  function serialize_CheckVersionTxn (line 1143) | int serialize_CheckVersionTxn(struct oarchive *out, const char *tag, str...
  function deserialize_CheckVersionTxn (line 1151) | int deserialize_CheckVersionTxn(struct iarchive *in, const char *tag, st...
  function deallocate_CheckVersionTxn (line 1159) | void deallocate_CheckVersionTxn(struct CheckVersionTxn*v){
  function serialize_SetACLTxn (line 1162) | int serialize_SetACLTxn(struct oarchive *out, const char *tag, struct Se...
  function deserialize_SetACLTxn (line 1171) | int deserialize_SetACLTxn(struct iarchive *in, const char *tag, struct S...
  function deallocate_SetACLTxn (line 1180) | void deallocate_SetACLTxn(struct SetACLTxn*v){
  function serialize_SetMaxChildrenTxn (line 1184) | int serialize_SetMaxChildrenTxn(struct oarchive *out, const char *tag, s...
  function deserialize_SetMaxChildrenTxn (line 1192) | int deserialize_SetMaxChildrenTxn(struct iarchive *in, const char *tag, ...
  function deallocate_SetMaxChildrenTxn (line 1200) | void deallocate_SetMaxChildrenTxn(struct SetMaxChildrenTxn*v){
  function serialize_CreateSessionTxn (line 1203) | int serialize_CreateSessionTxn(struct oarchive *out, const char *tag, st...
  function deserialize_CreateSessionTxn (line 1210) | int deserialize_CreateSessionTxn(struct iarchive *in, const char *tag, s...
  function deallocate_CreateSessionTxn (line 1217) | void deallocate_CreateSessionTxn(struct CreateSessionTxn*v){
  function serialize_ErrorTxn (line 1219) | int serialize_ErrorTxn(struct oarchive *out, const char *tag, struct Err...
  function deserialize_ErrorTxn (line 1226) | int deserialize_ErrorTxn(struct iarchive *in, const char *tag, struct Er...
  function deallocate_ErrorTxn (line 1233) | void deallocate_ErrorTxn(struct ErrorTxn*v){
  function serialize_Txn (line 1235) | int serialize_Txn(struct oarchive *out, const char *tag, struct Txn *v){
  function deserialize_Txn (line 1243) | int deserialize_Txn(struct iarchive *in, const char *tag, struct Txn*v){
  function deallocate_Txn (line 1251) | void deallocate_Txn(struct Txn*v){
  function allocate_Txn_vector (line 1254) | int allocate_Txn_vector(struct Txn_vector *v, int32_t len) {
  function deallocate_Txn_vector (line 1264) | int deallocate_Txn_vector(struct Txn_vector *v) {
  function serialize_Txn_vector (line 1275) | int serialize_Txn_vector(struct oarchive *out, const char *tag, struct T...
  function deserialize_Txn_vector (line 1287) | int deserialize_Txn_vector(struct iarchive *in, const char *tag, struct ...
  function serialize_MultiTxn (line 1299) | int serialize_MultiTxn(struct oarchive *out, const char *tag, struct Mul...
  function deserialize_MultiTxn (line 1306) | int deserialize_MultiTxn(struct iarchive *in, const char *tag, struct Mu...
  function deallocate_MultiTxn (line 1313) | void deallocate_MultiTxn(struct MultiTxn*v){

FILE: cluster/cluster_conn/zookeeper/zookeeper.jute.h
  type Id (line 27) | struct Id {
  type oarchive (line 31) | struct oarchive
  type Id (line 31) | struct Id
  type iarchive (line 32) | struct iarchive
  type Id (line 32) | struct Id
  type Id (line 33) | struct Id
  type ACL (line 34) | struct ACL {
  type oarchive (line 38) | struct oarchive
  type ACL (line 38) | struct ACL
  type iarchive (line 39) | struct iarchive
  type ACL (line 39) | struct ACL
  type ACL (line 40) | struct ACL
  type Stat (line 41) | struct Stat {
  type oarchive (line 54) | struct oarchive
  type Stat (line 54) | struct Stat
  type iarchive (line 55) | struct iarchive
  type Stat (line 55) | struct Stat
  type Stat (line 56) | struct Stat
  type StatPersisted (line 57) | struct StatPersisted {
  type oarchive (line 68) | struct oarchive
  type StatPersisted (line 68) | struct StatPersisted
  type iarchive (line 69) | struct iarchive
  type StatPersisted (line 69) | struct StatPersisted
  type StatPersisted (line 70) | struct StatPersisted
  type StatPersistedV1 (line 71) | struct StatPersistedV1 {
  type oarchive (line 81) | struct oarchive
  type StatPersistedV1 (line 81) | struct StatPersistedV1
  type iarchive (line 82) | struct iarchive
  type StatPersistedV1 (line 82) | struct StatPersistedV1
  type StatPersistedV1 (line 83) | struct StatPersistedV1
  type ConnectRequest (line 84) | struct ConnectRequest {
  type oarchive (line 91) | struct oarchive
  type ConnectRequest (line 91) | struct ConnectRequest
  type iarchive (line 92) | struct iarchive
  type ConnectRequest (line 92) | struct ConnectRequest
  type ConnectRequest (line 93) | struct ConnectRequest
  type ConnectResponse (line 94) | struct ConnectResponse {
  type oarchive (line 100) | struct oarchive
  type ConnectResponse (line 100) | struct ConnectResponse
  type iarchive (line 101) | struct iarchive
  type ConnectResponse (line 101) | struct ConnectResponse
  type ConnectResponse (line 102) | struct ConnectResponse
  type String_vector (line 103) | struct String_vector {
  type oarchive (line 108) | struct oarchive
  type String_vector (line 108) | struct String_vector
  type iarchive (line 109) | struct iarchive
  type String_vector (line 109) | struct String_vector
  type String_vector (line 110) | struct String_vector
  type String_vector (line 111) | struct String_vector
  type SetWatches (line 112) | struct SetWatches {
  type oarchive (line 118) | struct oarchive
  type SetWatches (line 118) | struct SetWatches
  type iarchive (line 119) | struct iarchive
  type SetWatches (line 119) | struct SetWatches
  type SetWatches (line 120) | struct SetWatches
  type RequestHeader (line 121) | struct RequestHeader {
  type oarchive (line 125) | struct oarchive
  type RequestHeader (line 125) | struct RequestHeader
  type iarchive (line 126) | struct iarchive
  type RequestHeader (line 126) | struct RequestHeader
  type RequestHeader (line 127) | struct RequestHeader
  type MultiHeader (line 128) | struct MultiHeader {
  type oarchive (line 133) | struct oarchive
  type MultiHeader (line 133) | struct MultiHeader
  type iarchive (line 134) | struct iarchive
  type MultiHeader (line 134) | struct MultiHeader
  type MultiHeader (line 135) | struct MultiHeader
  type AuthPacket (line 136) | struct AuthPacket {
  type oarchive (line 141) | struct oarchive
  type AuthPacket (line 141) | struct AuthPacket
  type iarchive (line 142) | struct iarchive
  type AuthPacket (line 142) | struct AuthPacket
  type AuthPacket (line 143) | struct AuthPacket
  type ReplyHeader (line 144) | struct ReplyHeader {
  type oarchive (line 149) | struct oarchive
  type ReplyHeader (line 149) | struct ReplyHeader
  type iarchive (line 150) | struct iarchive
  type ReplyHeader (line 150) | struct ReplyHeader
  type ReplyHeader (line 151) | struct ReplyHeader
  type GetDataRequest (line 152) | struct GetDataRequest {
  type oarchive (line 156) | struct oarchive
  type GetDataRequest (line 156) | struct GetDataRequest
  type iarchive (line 157) | struct iarchive
  type GetDataRequest (line 157) | struct GetDataRequest
  type GetDataRequest (line 158) | struct GetDataRequest
  type SetDataRequest (line 159) | struct SetDataRequest {
  type oarchive (line 164) | struct oarchive
  type SetDataRequest (line 164) | struct SetDataRequest
  type iarchive (line 165) | struct iarchive
  type SetDataRequest (line 165) | struct SetDataRequest
  type SetDataRequest (line 166) | struct SetDataRequest
  type SetDataResponse (line 167) | struct SetDataResponse {
  type oarchive (line 170) | struct oarchive
  type SetDataResponse (line 170) | struct SetDataResponse
  type iarchive (line 171) | struct iarchive
  type SetDataResponse (line 171) | struct SetDataResponse
  type SetDataResponse (line 172) | struct SetDataResponse
  type GetSASLRequest (line 173) | struct GetSASLRequest {
  type oarchive (line 176) | struct oarchive
  type GetSASLRequest (line 176) | struct GetSASLRequest
  type iarchive (line 177) | struct iarchive
  type GetSASLRequest (line 177) | struct GetSASLRequest
  type GetSASLRequest (line 178) | struct GetSASLRequest
  type SetSASLRequest (line 179) | struct SetSASLRequest {
  type oarchive (line 182) | struct oarchive
  type SetSASLRequest (line 182) | struct SetSASLRequest
  type iarchive (line 183) | struct iarchive
  type SetSASLRequest (line 183) | struct SetSASLRequest
  type SetSASLRequest (line 184) | struct SetSASLRequest
  type SetSASLResponse (line 185) | struct SetSASLResponse {
  type oarchive (line 188) | struct oarchive
  type SetSASLResponse (line 188) | struct SetSASLResponse
  type iarchive (line 189) | struct iarchive
  type SetSASLResponse (line 189) | struct SetSASLResponse
  type SetSASLResponse (line 190) | struct SetSASLResponse
  type ACL_vector (line 191) | struct ACL_vector {
  type oarchive (line 196) | struct oarchive
  type ACL_vector (line 196) | struct ACL_vector
  type iarchive (line 197) | struct iarchive
  type ACL_vector (line 197) | struct ACL_vector
  type ACL_vector (line 198) | struct ACL_vector
  type ACL_vector (line 199) | struct ACL_vector
  type CreateRequest (line 200) | struct CreateRequest {
  type oarchive (line 206) | struct oarchive
  type CreateRequest (line 206) | struct CreateRequest
  type iarchive (line 207) | struct iarchive
  type CreateRequest (line 207) | struct CreateRequest
  type CreateRequest (line 208) | struct CreateRequest
  type DeleteRequest (line 209) | struct DeleteRequest {
  type oarchive (line 213) | struct oarchive
  type DeleteRequest (line 213) | struct DeleteRequest
  type iarchive (line 214) | struct iarchive
  type DeleteRequest (line 214) | struct DeleteRequest
  type DeleteRequest (line 215) | struct DeleteRequest
  type GetChildrenRequest (line 216) | struct GetChildrenRequest {
  type oarchive (line 220) | struct oarchive
  type GetChildrenRequest (line 220) | struct GetChildrenRequest
  type iarchive (line 221) | struct iarchive
  type GetChildrenRequest (line 221) | struct GetChildrenRequest
  type GetChildrenRequest (line 222) | struct GetChildrenRequest
  type GetChildren2Request (line 223) | struct GetChildren2Request {
  type oarchive (line 227) | struct oarchive
  type GetChildren2Request (line 227) | struct GetChildren2Request
  type iarchive (line 228) | struct iarchive
  type GetChildren2Request (line 228) | struct GetChildren2Request
  type GetChildren2Request (line 229) | struct GetChildren2Request
  type CheckVersionRequest (line 230) | struct CheckVersionRequest {
  type oarchive (line 234) | struct oarchive
  type CheckVersionRequest (line 234) | struct CheckVersionRequest
  type iarchive (line 235) | struct iarchive
  type CheckVersionRequest (line 235) | struct CheckVersionRequest
  type CheckVersionRequest (line 236) | struct CheckVersionRequest
  type GetMaxChildrenRequest (line 237) | struct GetMaxChildrenRequest {
  type oarchive (line 240) | struct oarchive
  type GetMaxChildrenRequest (line 240) | struct GetMaxChildrenRequest
  type iarchive (line 241) | struct iarchive
  type GetMaxChildrenRequest (line 241) | struct GetMaxChildrenRequest
  type GetMaxChildrenRequest (line 242) | struct GetMaxChildrenRequest
  type GetMaxChildrenResponse (line 243) | struct GetMaxChildrenResponse {
  type oarchive (line 246) | struct oarchive
  type GetMaxChildrenResponse (line 246) | struct GetMaxChildrenResponse
  type iarchive (line 247) | struct iarchive
  type GetMaxChildrenResponse (line 247) | struct GetMaxChildrenResponse
  type GetMaxChildrenResponse (line 248) | struct GetMaxChildrenResponse
  type SetMaxChildrenRequest (line 249) | struct SetMaxChildrenRequest {
  type oarchive (line 253) | struct oarchive
  type SetMaxChildrenRequest (line 253) | struct SetMaxChildrenRequest
  type iarchive (line 254) | struct iarchive
  type SetMaxChildrenRequest (line 254) | struct SetMaxChildrenRequest
  type SetMaxChildrenRequest (line 255) | struct SetMaxChildrenRequest
  type SyncRequest (line 256) | struct SyncRequest {
  type oarchive (line 259) | struct oarchive
  type SyncRequest (line 259) | struct SyncRequest
  type iarchive (line 260) | struct iarchive
  type SyncRequest (line 260) | struct SyncRequest
  type SyncRequest (line 261) | struct SyncRequest
  type SyncResponse (line 262) | struct SyncResponse {
  type oarchive (line 265) | struct oarchive
  type SyncResponse (line 265) | struct SyncResponse
  type iarchive (line 266) | struct iarchive
  type SyncResponse (line 266) | struct SyncResponse
  type SyncResponse (line 267) | struct SyncResponse
  type GetACLRequest (line 268) | struct GetACLRequest {
  type oarchive (line 271) | struct oarchive
  type GetACLRequest (line 271) | struct GetACLRequest
  type iarchive (line 272) | struct iarchive
  type GetACLRequest (line 272) | struct GetACLRequest
  type GetACLRequest (line 273) | struct GetACLRequest
  type SetACLRequest (line 274) | struct SetACLRequest {
  type oarchive (line 279) | struct oarchive
  type SetACLRequest (line 279) | struct SetACLRequest
  type iarchive (line 280) | struct iarchive
  type SetACLRequest (line 280) | struct SetACLRequest
  type SetACLRequest (line 281) | struct SetACLRequest
  type SetACLResponse (line 282) | struct SetACLResponse {
  type oarchive (line 285) | struct oarchive
  type SetACLResponse (line 285) | struct SetACLResponse
  type iarchive (line 286) | struct iarchive
  type SetACLResponse (line 286) | struct SetACLResponse
  type SetACLResponse (line 287) | struct SetACLResponse
  type WatcherEvent (line 288) | struct WatcherEvent {
  type oarchive (line 293) | struct oarchive
  type WatcherEvent (line 293) | struct WatcherEvent
  type iarchive (line 294) | struct iarchive
  type WatcherEvent (line 294) | struct WatcherEvent
  type WatcherEvent (line 295) | struct WatcherEvent
  type ErrorResponse (line 296) | struct ErrorResponse {
  type oarchive (line 299) | struct oarchive
  type ErrorResponse (line 299) | struct ErrorResponse
  type iarchive (line 300) | struct iarchive
  type ErrorResponse (line 300) | struct ErrorResponse
  type ErrorResponse (line 301) | struct ErrorResponse
  type CreateResponse (line 302) | struct CreateResponse {
  type oarchive (line 305) | struct oarchive
  type CreateResponse (line 305) | struct CreateResponse
  type iarchive (line 306) | struct iarchive
  type CreateResponse (line 306) | struct CreateResponse
  type CreateResponse (line 307) | struct CreateResponse
  type ExistsRequest (line 308) | struct ExistsRequest {
  type oarchive (line 312) | struct oarchive
  type ExistsRequest (line 312) | struct ExistsRequest
  type iarchive (line 313) | struct iarchive
  type ExistsRequest (line 313) | struct ExistsRequest
  type ExistsRequest (line 314) | struct ExistsRequest
  type ExistsResponse (line 315) | struct ExistsResponse {
  type oarchive (line 318) | struct oarchive
  type ExistsResponse (line 318) | struct ExistsResponse
  type iarchive (line 319) | struct iarchive
  type ExistsResponse (line 319) | struct ExistsResponse
  type ExistsResponse (line 320) | struct ExistsResponse
  type GetDataResponse (line 321) | struct GetDataResponse {
  type oarchive (line 325) | struct oarchive
  type GetDataResponse (line 325) | struct GetDataResponse
  type iarchive (line 326) | struct iarchive
  type GetDataResponse (line 326) | struct GetDataResponse
  type GetDataResponse (line 327) | struct GetDataResponse
  type GetChildrenResponse (line 328) | struct GetChildrenResponse {
  type oarchive (line 331) | struct oarchive
  type GetChildrenResponse (line 331) | struct GetChildrenResponse
  type iarchive (line 332) | struct iarchive
  type GetChildrenResponse (line 332) | struct GetChildrenResponse
  type GetChildrenResponse (line 333) | struct GetChildrenResponse
  type GetChildren2Response (line 334) | struct GetChildren2Response {
  type oarchive (line 338) | struct oarchive
  type GetChildren2Response (line 338) | struct GetChildren2Response
  type iarchive (line 339) | struct iarchive
  type GetChildren2Response (line 339) | struct GetChildren2Response
  type GetChildren2Response (line 340) | struct GetChildren2Response
  type GetACLResponse (line 341) | struct GetACLResponse {
  type oarchive (line 345) | struct oarchive
  type GetACLResponse (line 345) | struct GetACLResponse
  type iarchive (line 346) | struct iarchive
  type GetACLResponse (line 346) | struct GetACLResponse
  type GetACLResponse (line 347) | struct GetACLResponse
  type LearnerInfo (line 348) | struct LearnerInfo {
  type oarchive (line 352) | struct oarchive
  type LearnerInfo (line 352) | struct LearnerInfo
  type iarchive (line 353) | struct iarchive
  type LearnerInfo (line 353) | struct LearnerInfo
  type LearnerInfo (line 354) | struct LearnerInfo
  type Id_vector (line 355) | struct Id_vector {
  type oarchive (line 360) | struct oarchive
  type Id_vector (line 360) | struct Id_vector
  type iarchive (line 361) | struct iarchive
  type Id_vector (line 361) | struct Id_vector
  type Id_vector (line 362) | struct Id_vector
  type Id_vector (line 363) | struct Id_vector
  type QuorumPacket (line 364) | struct QuorumPacket {
  type oarchive (line 370) | struct oarchive
  type QuorumPacket (line 370) | struct QuorumPacket
  type iarchive (line 371) | struct iarchive
  type QuorumPacket (line 371) | struct QuorumPacket
  type QuorumPacket (line 372) | struct QuorumPacket
  type FileHeader (line 373) | struct FileHeader {
  type oarchive (line 378) | struct oarchive
  type FileHeader (line 378) | struct FileHeader
  type iarchive (line 379) | struct iarchive
  type FileHeader (line 379) | struct FileHeader
  type FileHeader (line 380) | struct FileHeader
  type TxnHeader (line 381) | struct TxnHeader {
  type oarchive (line 388) | struct oarchive
  type TxnHeader (line 388) | struct TxnHeader
  type iarchive (line 389) | struct iarchive
  type TxnHeader (line 389) | struct TxnHeader
  type TxnHeader (line 390) | struct TxnHeader
  type CreateTxnV0 (line 391) | struct CreateTxnV0 {
  type oarchive (line 397) | struct oarchive
  type CreateTxnV0 (line 397) | struct CreateTxnV0
  type iarchive (line 398) | struct iarchive
  type CreateTxnV0 (line 398) | struct CreateTxnV0
  type CreateTxnV0 (line 399) | struct CreateTxnV0
  type CreateTxn (line 400) | struct CreateTxn {
  type oarchive (line 407) | struct oarchive
  type CreateTxn (line 407) | struct CreateTxn
  type iarchive (line 408) | struct iarchive
  type CreateTxn (line 408) | struct CreateTxn
  type CreateTxn (line 409) | struct CreateTxn
  type DeleteTxn (line 410) | struct DeleteTxn {
  type oarchive (line 413) | struct oarchive
  type DeleteTxn (line 413) | struct DeleteTxn
  type iarchive (line 414) | struct iarchive
  type DeleteTxn (line 414) | struct DeleteTxn
  type DeleteTxn (line 415) | struct DeleteTxn
  type SetDataTxn (line 416) | struct SetDataTxn {
  type oarchive (line 421) | struct oarchive
  type SetDataTxn (line 421) | struct SetDataTxn
  type iarchive (line 422) | struct iarchive
  type SetDataTxn (line 422) | struct SetDataTxn
  type SetDataTxn (line 423) | struct SetDataTxn
  type CheckVersionTxn (line 424) | struct CheckVersionTxn {
  type oarchive (line 428) | struct oarchive
  type CheckVersionTxn (line 428) | struct CheckVersionTxn
  type iarchive (line 429) | struct iarchive
  type CheckVersionTxn (line 429) | struct CheckVersionTxn
  type CheckVersionTxn (line 430) | struct CheckVersionTxn
  type SetACLTxn (line 431) | struct SetACLTxn {
  type oarchive (line 436) | struct oarchive
  type SetACLTxn (line 436) | struct SetACLTxn
  type iarchive (line 437) | struct iarchive
  type SetACLTxn (line 437) | struct SetACLTxn
  type SetACLTxn (line 438) | struct SetACLTxn
  type SetMaxChildrenTxn (line 439) | struct SetMaxChildrenTxn {
  type oarchive (line 443) | struct oarchive
  type SetMaxChildrenTxn (line 443) | struct SetMaxChildrenTxn
  type iarchive (line 444) | struct iarchive
  type SetMaxChildrenTxn (line 444) | struct SetMaxChildrenTxn
  type SetMaxChildrenTxn (line 445) | struct SetMaxChildrenTxn
  type CreateSessionTxn (line 446) | struct CreateSessionTxn {
  type oarchive (line 449) | struct oarchive
  type CreateSessionTxn (line 449) | struct CreateSessionTxn
  type iarchive (line 450) | struct iarchive
  type CreateSessionTxn (line 450) | struct CreateSessionTxn
  type CreateSessionTxn (line 451) | struct CreateSessionTxn
  type ErrorTxn (line 452) | struct ErrorTxn {
  type oarchive (line 455) | struct oarchive
  type ErrorTxn (line 455) | struct ErrorTxn
  type iarchive (line 456) | struct iarchive
  type ErrorTxn (line 456) | struct ErrorTxn
  type ErrorTxn (line 457) | struct ErrorTxn
  type Txn (line 458) | struct Txn {
  type oarchive (line 462) | struct oarchive
  type Txn (line 462) | struct Txn
  type iarchive (line 463) | struct iarchive
  type Txn (line 463) | struct Txn
  type Txn (line 464) | struct Txn
  type Txn_vector (line 465) | struct Txn_vector {
  type oarchive (line 470) | struct oarchive
  type Txn_vector (line 470) | struct Txn_vector
  type iarchive (line 471) | struct iarchive
  type Txn_vector (line 471) | struct Txn_vector
  type Txn_vector (line 472) | struct Txn_vector
  type Txn_vector (line 473) | struct Txn_vector
  type MultiTxn (line 474) | struct MultiTxn {
  type oarchive (line 477) | struct oarchive
  type MultiTxn (line 477) | struct MultiTxn
  type iarchive (line 478) | struct iarchive
  type MultiTxn (line 478) | struct MultiTxn
  type MultiTxn (line 479) | struct MultiTxn

FILE: cluster/qedis_proxy/ClientConn.cc
  function ProcessInlineCmd (line 15) | static

FILE: cluster/qedis_proxy/ClientConn.h
  function class (line 12) | class ClientConn final

FILE: cluster/qedis_proxy/ClientManager.cc
  function ClientManager (line 9) | ClientManager& ClientManager::Instance()

FILE: cluster/qedis_proxy/ClientManager.h
  function namespace (line 8) | namespace ananas
  function class (line 14) | class ClientManager

FILE: cluster/qedis_proxy/ClusterManager.cc
  function ClusterManager (line 15) | ClusterManager& ClusterManager::Instance()

FILE: cluster/qedis_proxy/ClusterManager.h
  function namespace (line 8) | namespace ananas
  function class (line 15) | class ClusterManager

FILE: cluster/qedis_proxy/Command.cc
  function CommandInfo (line 121) | const CommandInfo* CommandTable::GetCommandInfo(const std::string& cmd)
  type QedisErrorInfo (line 132) | struct QedisErrorInfo
  function ping (line 142) | std::string ping(const std::vector<std::string>& params)
  function info (line 147) | std::string info(const std::vector<std::string>& params)

FILE: cluster/qedis_proxy/Command.h
  type CommandAttr (line 8) | enum CommandAttr
  type CommandInfo (line 22) | struct CommandInfo
  function class (line 40) | class CommandTable
  type QedisError (line 51) | enum QedisError
  type QedisErrorInfo (line 64) | struct QedisErrorInfo

FILE: cluster/qedis_proxy/ConfigParser.cc
  function SkipBlank (line 12) | static size_t  SkipBlank(const char* data, size_t len, size_t off)
  function main (line 123) | int main()

FILE: cluster/qedis_proxy/ConfigParser.h
  function class (line 12) | class ConfigParser
  function T (line 47) | T ConfigParser::_ToType(const std::string& data) const
  function T (line 69) | T ConfigParser::GetData(const char* key, const T& default_) const

FILE: cluster/qedis_proxy/Protocol.cc
  function ParseResult (line 32) | static
  function ParseResult (line 89) | ParseResult ServerProtocol::ParseRequest(const char*& ptr, const char* end)
  function ParseResult (line 108) | ParseResult ServerProtocol::_ParseMulti(const char*& ptr, const char* en...
  function ParseResult (line 121) | ParseResult ServerProtocol::_ParseStrlist(const char*& ptr, const char* ...
  function ParseResult (line 142) | ParseResult ServerProtocol::_ParseStr(const char*& ptr, const char* end,...
  function ParseResult (line 169) | ParseResult ServerProtocol::_ParseStrval(const char*& ptr, const char* e...
  function ParseResult (line 189) | ParseResult ServerProtocol::_ParseStrlen(const char*& ptr, const char* e...
  function ParseResult (line 212) | ParseResult ClientProtocol::Parse(const char*& ptr, const char* end)
  function ParseResult (line 310) | ParseResult ClientProtocol::_ParseStr(const char*& ptr, const char* end)
  function ParseResult (line 329) | ParseResult ClientProtocol::_ParseStrval(const char*& ptr, const char* end)
  function ParseResult (line 346) | ParseResult ClientProtocol::_ParseStrlen(const char*& ptr, const char* e...
  function ParseResult (line 363) | ParseResult ClientProtocol::_ParseMulti(const char*& ptr, const char* end)
  function main (line 396) | int main()

FILE: cluster/qedis_proxy/Protocol.h
  function ParseResult (line 7) | enum class ParseResult : int8_t
  type class (line 45) | enum class
  function class (line 55) | class ClientProtocol

FILE: cluster/qedis_proxy/ProxyConfig.cc
  type qedis (line 7) | namespace qedis
    function EraseQuotes (line 10) | static void EraseQuotes(std::string& str)
    function LoadProxyConfig (line 35) | bool LoadProxyConfig(const char* cfgFile, ProxyConfig& cfg)

FILE: cluster/qedis_proxy/ProxyConfig.h
  function namespace (line 8) | namespace qedis

FILE: cluster/qedis_proxy/QedisConn.cc
  function BuildRequest (line 10) | static

FILE: cluster/qedis_proxy/QedisConn.h
  function string (line 22) | string BuildQedisRequest(H&& head, T&&... tails)
  function class (line 28) | class QedisConn final

FILE: cluster/qedis_proxy/QedisManager.cc
  function QedisManager (line 9) | QedisManager& QedisManager::Instance()

FILE: cluster/qedis_proxy/QedisManager.h
  function namespace (line 13) | namespace ananas
  function class (line 20) | class QedisManager

FILE: cluster/qedis_proxy/ZookeeperConn.cc
  function GetSetID (line 93) | static int GetSetID(const std::string& path)
  function GetNodeAddr (line 149) | static std::string GetNodeAddr(const std::string& path)

FILE: cluster/qedis_proxy/ZookeeperConn.h
  function namespace (line 8) | namespace ananas

FILE: cluster/qedis_proxy/main.cc
  function main (line 13) | int main(int ac, char* av[])
Condensed preview — 217 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,238K chars).
[
  {
    "path": ".gitignore",
    "chars": 34,
    "preview": "# MAC OS\n.DS_Store\n\n#\nbuild/\nbin/\n"
  },
  {
    "path": ".travis.yml",
    "chars": 215,
    "preview": "sudo: false\nlanguage: cpp\ncompiler:\n  - clang\nscript: make\nbranches:\n  only:\n    - master\nnotifications:\n  recipients:\n "
  },
  {
    "path": "CMakeCommon",
    "chars": 654,
    "preview": "CMAKE_MINIMUM_REQUIRED(VERSION 2.6)\n\nIF(${CMAKE_SYSTEM_NAME} MATCHES \"Linux\")\n    SET(CMAKE_CXX_FLAGS_DEBUG  \"-g -Wall -"
  },
  {
    "path": "CMakeLists.txt",
    "chars": 345,
    "preview": "CMAKE_MINIMUM_REQUIRED(VERSION 2.6)\n\nPROJECT(QEDIS)\n\nSUBDIRS(QBase)\nSUBDIRS(QedisCore)\nSUBDIRS(QedisSvr)\nSUBDIRS(Modules"
  },
  {
    "path": "LICENSE",
    "chars": 1067,
    "preview": "MIT License\n\nCopyright (c) 2017 Bert Young\n\nPermission is hereby granted, free of charge, to any person obtaining a copy"
  },
  {
    "path": "Makefile",
    "chars": 562,
    "preview": "all:\n\t@if [ ! -d \"leveldb\" ]; then echo \"leveldb not present. Fetching leveldb-1.18 from internet...\"; curl -s -L -O htt"
  },
  {
    "path": "Modules/CMakeLists.txt",
    "chars": 579,
    "preview": "INCLUDE(${PROJECT_SOURCE_DIR}/CMakeCommon)\n\nAUX_SOURCE_DIRECTORY(. QEDIS_MODULE_SRC)\n\nLINK_DIRECTORIES(../../leveldb)\n\nS"
  },
  {
    "path": "Modules/QHashModule.cc",
    "chars": 781,
    "preview": "#include \"QHashModule.h\"\n#include \"QHash.h\"\n#include \"QStore.h\"\n#include \"QGlobRegex.h\"\n\nusing namespace qedis;\n\nQError "
  },
  {
    "path": "Modules/QHashModule.h",
    "chars": 444,
    "preview": "#ifndef BERT_QHASHMODULE_H\n#define BERT_QHASHMODULE_H\n\n#include <vector>\n#include \"QString.h\"\n#include \"QCommon.h\"\n\nname"
  },
  {
    "path": "Modules/QListModule.cc",
    "chars": 1155,
    "preview": "#include \"QListModule.h\"\n#include \"QList.h\"\n#include \"QStore.h\"\n#include <algorithm>\n\nusing namespace qedis;\n\n\nQError ld"
  },
  {
    "path": "Modules/QListModule.h",
    "chars": 341,
    "preview": "#ifndef BERT_QLISTMODULE_H\n#define BERT_QLISTMODULE_H\n\n#include <vector>\n#include \"QString.h\"\n#include \"QCommon.h\"\n\nname"
  },
  {
    "path": "Modules/QModuleInit.cc",
    "chars": 1757,
    "preview": "#include \"QModuleInit.h\"\n#include \"QCommand.h\"\n#include <algorithm>\n\nextern \"C\"\nqedis::QError ldel(const std::vector<qed"
  },
  {
    "path": "Modules/QModuleInit.h",
    "chars": 142,
    "preview": "#ifndef BERT_QMODULEINIT_H\n#define BERT_QMODULEINIT_H\n\nextern \"C\"\nbool QedisModule_OnLoad();\n\nextern \"C\"\nvoid QedisModul"
  },
  {
    "path": "Modules/QSetModule.cc",
    "chars": 803,
    "preview": "#include \"QSetModule.h\"\n#include \"QSet.h\"\n#include \"QStore.h\"\n#include \"QGlobRegex.h\"\n\nusing namespace qedis;\n\nQError sk"
  },
  {
    "path": "Modules/QSetModule.h",
    "chars": 381,
    "preview": "#ifndef BERT_QSETMODULE_H\n#define BERT_QSETMODULE_H\n\n#include <vector>\n#include \"QString.h\"\n#include \"QCommon.h\"\n\nnamesp"
  },
  {
    "path": "QBase/AsyncBuffer.cc",
    "chars": 2554,
    "preview": "#include <assert.h>\n\n#if defined(__APPLE__)\n#include <unistd.h>\n#endif\n\n#include \"AsyncBuffer.h\"\n\nusing std::size_t;\n\nAs"
  },
  {
    "path": "QBase/AsyncBuffer.h",
    "chars": 711,
    "preview": "#ifndef BERT_ASYNCBUFFER_H\n#define BERT_ASYNCBUFFER_H\n\n#include <mutex>\n#include <atomic>\n\n#include \"Buffer.h\"\n#include "
  },
  {
    "path": "QBase/Buffer.h",
    "chars": 12712,
    "preview": "\n#ifndef BERT_BUFFER_H\n#define BERT_BUFFER_H\n\n#include <cassert>\n#include <cstring>\n#include <vector>\n#include <string>\n"
  },
  {
    "path": "QBase/CMakeLists.txt",
    "chars": 451,
    "preview": "CMAKE_MINIMUM_REQUIRED(VERSION 2.6)\n\nINCLUDE(${PROJECT_SOURCE_DIR}/CMakeCommon)\n\nAUX_SOURCE_DIRECTORY(. SDK_SRC)\nAUX_SOU"
  },
  {
    "path": "QBase/ClientSocket.cc",
    "chars": 2958,
    "preview": "\n#include <errno.h>\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <cstdlib>\n#include <cstring>\n#include <casse"
  },
  {
    "path": "QBase/ClientSocket.h",
    "chars": 601,
    "preview": "\n#ifndef BERT_CLIENTSOCKET_H\n#define BERT_CLIENTSOCKET_H\n\n#include <functional>\n#include \"Socket.h\"\n\n// Abstraction for "
  },
  {
    "path": "QBase/ConfigParser.cc",
    "chars": 2659,
    "preview": "#include <vector>\n#include \"ConfigParser.h\"\n#include \"Log/MemoryFile.h\"\n\nstatic const int  SPACE     = ' ';\nstatic const"
  },
  {
    "path": "QBase/ConfigParser.h",
    "chars": 1586,
    "preview": "#ifndef BERT_CONFIGPARSER_H\n#define BERT_CONFIGPARSER_H\n\n#include <map>\n#include <string>\n#include <sstream>\n\n#ifdef CON"
  },
  {
    "path": "QBase/Delegate.h",
    "chars": 2114,
    "preview": "#include <functional>\n#include <list>\n\n\ntemplate <typename T>\nclass Delegate;\n\ntemplate <typename... Args>\nclass Delegat"
  },
  {
    "path": "QBase/EPoller.cc",
    "chars": 3051,
    "preview": "\n#if defined(__gnu_linux__)\n\n#include \"EPoller.h\"\n#include \"Log/Logger.h\"\n\n#include <errno.h>\n#include <unistd.h>\n\nnames"
  },
  {
    "path": "QBase/EPoller.h",
    "chars": 521,
    "preview": "#ifndef BERT_EPOLLER_H\n#define BERT_EPOLLER_H\n\n#if defined(__gnu_linux__)\n\n#include <sys/epoll.h>\n#include <vector>\n#inc"
  },
  {
    "path": "QBase/Kqueue.cc",
    "chars": 2774,
    "preview": "#if defined(__APPLE__)\n\n#include \"Kqueue.h\"\n#include \"Log/Logger.h\"\n\n#include <sys/event.h>\n#include <errno.h>\n#include "
  },
  {
    "path": "QBase/Kqueue.h",
    "chars": 491,
    "preview": "#ifndef BERT_KQUEUE_H\n#define BERT_KQUEUE_H\n\n#if defined(__APPLE__)\n\n#include \"Poller.h\"\n#include <vector>\n\nclass Kqueue"
  },
  {
    "path": "QBase/ListenSocket.cc",
    "chars": 2890,
    "preview": "\n#include <errno.h>\n#include <sys/socket.h>\n#include <cstdlib>\n#include <cstring>\n#include <cassert>\n#include \"Server.h\""
  },
  {
    "path": "QBase/ListenSocket.h",
    "chars": 549,
    "preview": "\n#ifndef BERT_LISTENSOCKET_H\n#define BERT_LISTENSOCKET_H\n\n#include \"Socket.h\"\n\nnamespace Internal\n{\n\nclass ListenSocket "
  },
  {
    "path": "QBase/Log/Logger.cc",
    "chars": 12873,
    "preview": "\n#include <iostream>\n#include <cstdlib>\n#include <cstdio>\n#include <cstring>\n#include <cstdarg>\n#include <errno.h>\n#incl"
  },
  {
    "path": "QBase/Log/Logger.h",
    "chars": 4597,
    "preview": "#ifndef BERT_LOGGER_H\n#define BERT_LOGGER_H\n\n#include <string>\n#include <set>\n#include <memory>\n\n#include \"../Threads/Th"
  },
  {
    "path": "QBase/Log/MemoryFile.cc",
    "chars": 5406,
    "preview": "#include <errno.h>\n#include <fcntl.h>\n#include <assert.h>\n#include <string.h>\n#include <sys/mman.h>\n#include <sys/stat.h"
  },
  {
    "path": "QBase/Log/MemoryFile.h",
    "chars": 1691,
    "preview": "#ifndef BERT_MEMORYFILE_H\n#define BERT_MEMORYFILE_H\n\n#include <string>\n#include <stdexcept>\n\nclass InputMemoryFile\n{\npub"
  },
  {
    "path": "QBase/NetThreadPool.cc",
    "chars": 6566,
    "preview": "\n#include \"NetThreadPool.h\"\n#include \"StreamSocket.h\"\n#include \"Log/Logger.h\"\n#include \"Timer.h\"\n\n#if defined(__gnu_linu"
  },
  {
    "path": "QBase/NetThreadPool.h",
    "chars": 2020,
    "preview": "#ifndef BERT_NETTHREADPOOL_H\n#define BERT_NETTHREADPOOL_H\n\n#include <deque>\n#include <vector>\n#include <unistd.h>\n#inclu"
  },
  {
    "path": "QBase/Poller.h",
    "chars": 726,
    "preview": "#ifndef BERT_POLLER_H\n#define BERT_POLLER_H\n\n#include <vector>\n\nenum EventType\n{\n    EventTypeRead  = 0x1,\n    EventType"
  },
  {
    "path": "QBase/README.md",
    "chars": 121,
    "preview": "# QBase\n\nQBase最初是C++03代码,由于历史原因,再加上它也极其稳定,我不打算替换了。\n\n感兴趣的可以看我的另外一个最新后台开发基础库[ananas](https://github.com/loveyacper/ananas)"
  },
  {
    "path": "QBase/Server.cc",
    "chars": 4366,
    "preview": "#include <signal.h>\n#include <ctime>\n#include <cstdlib>\n#include <cstring>\n#include <sys/resource.h>\n#include \"Server.h\""
  },
  {
    "path": "QBase/Server.h",
    "chars": 1788,
    "preview": "\n#ifndef BERT_SERVER_H\n#define BERT_SERVER_H\n\n#include <set>\n#include <functional>\n#include \"TaskManager.h\"\n\nstruct Sock"
  },
  {
    "path": "QBase/Socket.cc",
    "chars": 3488,
    "preview": "\n#include <cassert>\n\n#include <errno.h>\n#include <fcntl.h>\n#include <sys/socket.h>\n#include <netinet/tcp.h>\n#include <sy"
  },
  {
    "path": "QBase/Socket.h",
    "chars": 5204,
    "preview": "\n#ifndef BERT_SOCKET_H\n#define BERT_SOCKET_H\n\n#include <arpa/inet.h>\n#include <string.h>\n#include <string>\n#include <mem"
  },
  {
    "path": "QBase/StreamSocket.cc",
    "chars": 4963,
    "preview": "#include <errno.h>\n#include <unistd.h>\n#include <fcntl.h>\n#include <netinet/tcp.h>\n\n#include \"StreamSocket.h\"\n#include \""
  },
  {
    "path": "QBase/StreamSocket.h",
    "chars": 1667,
    "preview": "\n#ifndef BERT_STREAMSOCKET_H\n#define BERT_STREAMSOCKET_H\n\n#include \"AsyncBuffer.h\"\n#include \"Socket.h\"\n#include <sys/typ"
  },
  {
    "path": "QBase/TaskManager.cc",
    "chars": 2383,
    "preview": "#include <cassert>\n#include \"TaskManager.h\"\n#include \"StreamSocket.h\"\n#include \"Log/Logger.h\"\n\nnamespace Internal\n{\n\nTas"
  },
  {
    "path": "QBase/TaskManager.h",
    "chars": 977,
    "preview": "#ifndef BERT_TASKMANAGER_H\n#define BERT_TASKMANAGER_H\n\n#include <vector>\n#include <map>\n#include <mutex>\n#include <memor"
  },
  {
    "path": "QBase/Threads/ThreadPool.cc",
    "chars": 2396,
    "preview": "#include \"ThreadPool.h\"\n\n__thread bool ThreadPool::working_ = true;\n\nThreadPool::ThreadPool() : waiters_(0), shutdown_(f"
  },
  {
    "path": "QBase/Threads/ThreadPool.h",
    "chars": 1979,
    "preview": "#ifndef BERT_THREADPOOL_H\n#define BERT_THREADPOOL_H\n\n#include <deque>\n#include <functional>\n#include <thread>\n#include <"
  },
  {
    "path": "QBase/Timer.cc",
    "chars": 9102,
    "preview": "#include <cstdlib>\n#include <cstdio>\n#include <cassert>\n#include <cstring>\n#include \"Timer.h\"\n\nuint64_t Now()\n{\n    stru"
  },
  {
    "path": "QBase/Timer.h",
    "chars": 3204,
    "preview": "\n#ifndef BERT_TIMER_H\n#define BERT_TIMER_H\n\n#include <vector>\n#include <set>\n#include <ctime>\n#include <sys/time.h>\n#inc"
  },
  {
    "path": "QBase/UnboundedBuffer.cc",
    "chars": 3650,
    "preview": "\n#include \"UnboundedBuffer.h\"\n#include <iostream>\n#include <limits>\n#include <cassert>\n\nnamespace qedis\n{\n\nconst std::si"
  },
  {
    "path": "QBase/UnboundedBuffer.h",
    "chars": 1345,
    "preview": "\n#ifndef BERT_UNBOUNDEDBUFFER_H\n#define BERT_UNBOUNDEDBUFFER_H\n\n#include <cstring>\n#include <vector>\n\nnamespace qedis\n{\n"
  },
  {
    "path": "QBase/lzf/lzf.h",
    "chars": 4413,
    "preview": "/*\n * Copyright (c) 2000-2008 Marc Alexander Lehmann <schmorp@schmorp.de>\n * \n * Redistribution and use in source and bi"
  },
  {
    "path": "QBase/lzf/lzfP.h",
    "chars": 5154,
    "preview": "/*\n * Copyright (c) 2000-2007 Marc Alexander Lehmann <schmorp@schmorp.de>\n * \n * Redistribution and use in source and bi"
  },
  {
    "path": "QBase/lzf/lzf_c.c",
    "chars": 8891,
    "preview": "/*\n * Copyright (c) 2000-2008 Marc Alexander Lehmann <schmorp@schmorp.de>\n * \n * Redistribution and use in source and bi"
  },
  {
    "path": "QBase/lzf/lzf_d.c",
    "chars": 4320,
    "preview": "/*\n * Copyright (c) 2000-2007 Marc Alexander Lehmann <schmorp@schmorp.de>\n * \n * Redistribution and use in source and bi"
  },
  {
    "path": "QSentinel/CMakeLists.txt",
    "chars": 569,
    "preview": "CMAKE_MINIMUM_REQUIRED(VERSION 2.6)\n\nINCLUDE(${PROJECT_SOURCE_DIR}/CMakeCommon)\n\nLINK_DIRECTORIES(../../leveldb)\n\nAUX_SO"
  },
  {
    "path": "QSentinel/QClusterClient.cc",
    "chars": 1976,
    "preview": "#if QEDIS_CLUSTER\n\n#include \"Log/Logger.h\"\n#include \"Server.h\"\n\n#include \"QConfig.h\"\n#include \"QCommand.h\"\n#include \"QCl"
  },
  {
    "path": "QSentinel/QClusterClient.h",
    "chars": 589,
    "preview": "#ifndef BERT_QCLUSTERCLIENT_H\n#define BERT_QCLUSTERCLIENT_H\n\n#if QEDIS_CLUSTER\n\n#include \"StreamSocket.h\"\n#include \"QClu"
  },
  {
    "path": "QSentinel/QClusterInterface.h",
    "chars": 975,
    "preview": "#ifndef BERT_CLUSTERINTERFACE_H\n#define BERT_CLUSTERINTERFACE_H\n\n#if QEDIS_CLUSTER\n\n#include <vector>\n#include <string>\n"
  },
  {
    "path": "QSentinel/README.md",
    "chars": 954,
    "preview": "# Qedis高可用集群\n\n利用Zookeeper实现的Qedis高可用集群,功能类似redis-sentinel。在此基础上可实现sacle-out集群。\n\n## 环境需求\n* C++11、CMake\n* zookeeper\n* Linu"
  },
  {
    "path": "QSentinel/zookeeper/ZookeeperConn.cc",
    "chars": 18044,
    "preview": "#if QEDIS_CLUSTER\n\n#include <unistd.h>\n#include \"ZookeeperConn.h\"\n#include \"Log/Logger.h\"\n#include \"QCommon.h\"\n\n#include"
  },
  {
    "path": "QSentinel/zookeeper/ZookeeperConn.h",
    "chars": 2078,
    "preview": "#ifndef BERT_ZOOKEEPERCONN_H\n#define BERT_ZOOKEEPERCONN_H\n\n#include <list>\n#include <map>\n#include \"StreamSocket.h\"\n#inc"
  },
  {
    "path": "QSentinel/zookeeper/proto.h",
    "chars": 4386,
    "preview": "/**\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NO"
  },
  {
    "path": "QSentinel/zookeeper/recordio.c",
    "chars": 9749,
    "preview": "/**\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NO"
  },
  {
    "path": "QSentinel/zookeeper/recordio.h",
    "chars": 2987,
    "preview": "/**\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NO"
  },
  {
    "path": "QSentinel/zookeeper/zookeeper.jute.c",
    "chars": 52155,
    "preview": "/**\n* Licensed to the Apache Software Foundation (ASF) under one\n* or more contributor license agreements.  See the NOTI"
  },
  {
    "path": "QSentinel/zookeeper/zookeeper.jute.h",
    "chars": 19977,
    "preview": "/**\n* Licensed to the Apache Software Foundation (ASF) under one\n* or more contributor license agreements.  See the NOTI"
  },
  {
    "path": "QSentinel/zookeeper/zookeeper_version.h",
    "chars": 1055,
    "preview": "/**\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NO"
  },
  {
    "path": "Qedis.xcodeproj/project.pbxproj",
    "chars": 132579,
    "preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
  },
  {
    "path": "QedisCore/CMakeLists.txt",
    "chars": 510,
    "preview": "AUX_SOURCE_DIRECTORY(. QEDIS_SRC)\n\nINCLUDE(${PROJECT_SOURCE_DIR}/CMakeCommon)\n\nLINK_DIRECTORIES(../../leveldb)\n\nADD_LIBR"
  },
  {
    "path": "QedisCore/QAOF.cc",
    "chars": 9887,
    "preview": "\n#include \"QAOF.h\"\n#include \"Log/Logger.h\"\n#include \"Threads/ThreadPool.h\"\n#include \"QStore.h\"\n#include \"QConfig.h\"\n#inc"
  },
  {
    "path": "QedisCore/QAOF.h",
    "chars": 2891,
    "preview": "#ifndef BERT_QAOF_H\n#define BERT_QAOF_H\n\n#include <memory>\n#include <future>\n#include \"Log/MemoryFile.h\"\n#include \"Async"
  },
  {
    "path": "QedisCore/QClient.cc",
    "chars": 11438,
    "preview": "#include \"Log/Logger.h\"\n\n#include <algorithm>\n#include \"QStore.h\"\n#include \"QCommand.h\"\n#include \"QConfig.h\"\n#include \"Q"
  },
  {
    "path": "QedisCore/QClient.h",
    "chars": 3638,
    "preview": "#ifndef BERT_QCLIENT_H\n#define BERT_QCLIENT_H\n\n#include \"StreamSocket.h\"\n#include \"QCommon.h\"\n\n#include \"QReplication.h\""
  },
  {
    "path": "QedisCore/QCommand.cc",
    "chars": 11949,
    "preview": "#include \"QCommand.h\"\n#include \"QReplication.h\"\n\nusing std::size_t;\n\nnamespace qedis\n{\n\nconst QCommandInfo QCommandTable"
  },
  {
    "path": "QedisCore/QCommand.h",
    "chars": 5221,
    "preview": "#ifndef BERT_QCOMMAND_H\n#define BERT_QCOMMAND_H\n\n#include <vector>\n#include <map>\n#include \"QCommon.h\"\n#include \"QString"
  },
  {
    "path": "QedisCore/QCommon.cc",
    "chars": 9813,
    "preview": "#include \"QCommon.h\"\n#include \"UnboundedBuffer.h\"\n#include <limits>\n#include <stdlib.h>\n#include <errno.h>\n#include <alg"
  },
  {
    "path": "QedisCore/QCommon.h",
    "chars": 6364,
    "preview": "#ifndef BERT_QCOMMON_H\n#define BERT_QCOMMON_H\n\n#include <cstddef>\n#include <stdio.h>\n#include <vector>\n#include <algorit"
  },
  {
    "path": "QedisCore/QConfig.cc",
    "chars": 6753,
    "preview": "#include <vector>\n#include <iostream>\n\n#include \"QConfig.h\"\n#include \"ConfigParser.h\"\n\nnamespace qedis\n{\n\nstatic void Er"
  },
  {
    "path": "QedisCore/QConfig.h",
    "chars": 1966,
    "preview": "#ifndef BERT_QCONFIG_H\n#define BERT_QCONFIG_H\n\n#include <map>\n#include <vector>\n#include \"QString.h\"\n\nnamespace qedis\n{\n"
  },
  {
    "path": "QedisCore/QDB.cc",
    "chars": 31764,
    "preview": "\n#include \"QDB.h\"\n#include \"Log/Logger.h\"\n#include <sstream>\n#include <unistd.h>\n#include <math.h>\n#include <arpa/inet.h"
  },
  {
    "path": "QedisCore/QDB.h",
    "chars": 1815,
    "preview": "#ifndef BERT_QDB_H\n#define BERT_QDB_H\n\n#include \"Log/MemoryFile.h\"\n#include \"QStore.h\"\n\nnamespace qedis\n{\n\nclass QDBSave"
  },
  {
    "path": "QedisCore/QDumpInterface.h",
    "chars": 644,
    "preview": "#ifndef BERT_QDUMPINTERFACE_H\n#define BERT_QDUMPINTERFACE_H\n\n#include <stdint.h>\n#include \"QString.h\"\n\nnamespace qedis\n{"
  },
  {
    "path": "QedisCore/QGlobRegex.cc",
    "chars": 4620,
    "preview": "#include <cassert>\n#include <set>\n#include \"QGlobRegex.h\"\n\nnamespace qedis\n{\n\nbool NotGlobRegex(const char* pattern, std"
  },
  {
    "path": "QedisCore/QGlobRegex.h",
    "chars": 1686,
    "preview": "#ifndef BERT_QGLOBREGEX_H\n#define BERT_QGLOBREGEX_H\n\n#include <string.h>\n#include \"QString.h\"\n\nnamespace qedis\n{\n\nbool N"
  },
  {
    "path": "QedisCore/QHash.cc",
    "chars": 7412,
    "preview": "#include \"QHash.h\"\n#include \"QStore.h\"\n#include <cassert>\n\nnamespace qedis\n{\n\nQObject QObject::CreateHash()\n{\n    QObjec"
  },
  {
    "path": "QedisCore/QHash.h",
    "chars": 325,
    "preview": "#ifndef BERT_QHASH_H\n#define BERT_QHASH_H\n\n#include \"QString.h\"\n#include \"QHelper.h\"\n\n#include <unordered_map>\n\nnamespac"
  },
  {
    "path": "QedisCore/QHelper.cc",
    "chars": 10031,
    "preview": "#include <unistd.h>\n#include <sys/time.h>\n#include <string.h>\n#include <fstream>\n\n#include \"QHelper.h\"\n\n#if defined(__gn"
  },
  {
    "path": "QedisCore/QHelper.h",
    "chars": 3048,
    "preview": "#ifndef BERT_HELPER_H\n#define BERT_HELPER_H\n\n#include \"QString.h\"\n#include <vector> \n#include <cstdlib> \n\nnamespace qedi"
  },
  {
    "path": "QedisCore/QKeyCommand.cc",
    "chars": 14794,
    "preview": "#include \"QStore.h\"\n#include \"Log/Logger.h\"\n#include \"QGlobRegex.h\"\n#include <cassert>\n\nnamespace qedis\n{\n\nQError type(c"
  },
  {
    "path": "QedisCore/QLeveldb.cc",
    "chars": 8497,
    "preview": "\n#include \"QLeveldb.h\"\n#include \"leveldb/db.h\"\n#include \"Log/Logger.h\"\n#include \"UnboundedBuffer.h\"\n\nnamespace qedis\n{\n\n"
  },
  {
    "path": "QedisCore/QLeveldb.h",
    "chars": 1425,
    "preview": "#ifndef BERT_QLEVELDB_H\n#define BERT_QLEVELDB_H\n\n#include \"QDumpInterface.h\"\n#include \"QStore.h\"\n\nnamespace leveldb\n{\ncl"
  },
  {
    "path": "QedisCore/QList.cc",
    "chars": 16570,
    "preview": "#include \"QList.h\"\n#include \"QStore.h\"\n#include \"QClient.h\"\n#include \"Log/Logger.h\"\n#include <algorithm>\n#include <casse"
  },
  {
    "path": "QedisCore/QList.h",
    "chars": 195,
    "preview": "#ifndef BERT_QLIST_H\n#define BERT_QLIST_H\n\n#include \"QString.h\"\n#include <list>\n\nnamespace qedis\n{\n\nenum class ListPosit"
  },
  {
    "path": "QedisCore/QMigration.cc",
    "chars": 8880,
    "preview": "#include \"Server.h\"\n#include \"QMigration.h\"\n#include \"Timer.h\"\n#include \"QDB.h\"\n\nnamespace qedis\n{\n\nstatic void ProcessI"
  },
  {
    "path": "QedisCore/QMigration.h",
    "chars": 1415,
    "preview": "#ifndef BERT_QMIGRATION_H\n#define BERT_QMIGRATION_H\n\n#include <deque>\n#include \"QClient.h\"\n\nnamespace ConnectionTag\n{\nco"
  },
  {
    "path": "QedisCore/QModule.cc",
    "chars": 4654,
    "preview": "#include <sstream>\n#include <dlfcn.h>\n#include <assert.h>\n\n#include \"QCommon.h\"\n#include \"QModule.h\"\n\nnamespace qedis\n{\n"
  },
  {
    "path": "QedisCore/QModule.h",
    "chars": 1616,
    "preview": "#ifndef BERT_QMODULE_H\n#define BERT_QMODULE_H\n\n#include <stdexcept>\n#include <unordered_map>\n#include <vector>\n#include "
  },
  {
    "path": "QedisCore/QMulti.cc",
    "chars": 4696,
    "preview": "#include \"QMulti.h\"\n#include \"QClient.h\"\n#include \"QStore.h\"\n#include \"Log/Logger.h\"\n\nnamespace qedis\n{\n\nQMulti&    QMul"
  },
  {
    "path": "QedisCore/QMulti.h",
    "chars": 753,
    "preview": "#ifndef BERT_QMULTI_H\n#define BERT_QMULTI_H\n\n#include <map>\n#include <vector>\n#include <memory>\n#include \"QString.h\"\n\nna"
  },
  {
    "path": "QedisCore/QProtoParser.cc",
    "chars": 3066,
    "preview": "\n\n\n#include \"QCommon.h\"\n#include \"QProtoParser.h\"\n\n#include <assert.h>\n\n// 1 request -> multi strlist\n// 2 multi -> * nu"
  },
  {
    "path": "QedisCore/QProtoParser.h",
    "chars": 1000,
    "preview": "#ifndef BERT_QPROTOPARSER_H\n#define BERT_QPROTOPARSER_H\n\n#include <vector>\n#include \"QString.h\"\n\nnamespace qedis\n{\n\nclas"
  },
  {
    "path": "QedisCore/QPubsub.cc",
    "chars": 11382,
    "preview": "#include \"QPubsub.h\"\n#include \"QClient.h\"\n#include \"Log/Logger.h\"\n#include \"Timer.h\"\n#include \"QGlobRegex.h\"\n\nnamespace "
  },
  {
    "path": "QedisCore/QPubsub.h",
    "chars": 1568,
    "preview": "#ifndef BERT_QPUBSUB_H\n#define BERT_QPUBSUB_H\n\n#include <map>\n#include <set>\n#include <vector>\n#include \"QString.h\"\n#inc"
  },
  {
    "path": "QedisCore/QReplication.cc",
    "chars": 15544,
    "preview": "\n#include <unistd.h>\n#include <iostream> // the child process use stdout for log\n#include <sstream>\n\n#include \"Log/Logge"
  },
  {
    "path": "QedisCore/QReplication.h",
    "chars": 2601,
    "preview": "#ifndef BERT_QREPLICATION_H\n#define BERT_QREPLICATION_H\n\n#include <list>\n#include <memory>\n#include \"UnboundedBuffer.h\"\n"
  },
  {
    "path": "QedisCore/QServerCommand.cc",
    "chars": 15996,
    "preview": "#include <sys/utsname.h>\n#include <cassert>\n#include <unistd.h>\n\n#include \"QStore.h\"\n#include \"QClient.h\"\n#include \"Log/"
  },
  {
    "path": "QedisCore/QSet.cc",
    "chars": 8476,
    "preview": "#include \"QSet.h\"\n#include \"QStore.h\"\n#include \"QClient.h\"\n#include <cassert>\n\nnamespace qedis\n{\n\nQObject QObject::Creat"
  },
  {
    "path": "QedisCore/QSet.h",
    "chars": 309,
    "preview": "#ifndef BERT_QSET_H\n#define BERT_QSET_H\n\n#include \"QHelper.h\"\n#include <unordered_set>\n\nnamespace qedis\n{\n\nusing QSet = "
  },
  {
    "path": "QedisCore/QSlaveClient.cc",
    "chars": 904,
    "preview": "#include \"QSlaveClient.h\"\n#include \"QConfig.h\"\n#include \"QCommon.h\"\n#include \"Log/Logger.h\"\n\nnamespace qedis\n{\n\nvoid QSl"
  },
  {
    "path": "QedisCore/QSlaveClient.h",
    "chars": 288,
    "preview": "#ifndef BERT_QSLAVECLIENT_H\n#define BERT_QSLAVECLIENT_H\n\n#include \"StreamSocket.h\"\n\nnamespace qedis\n{\n\nclass QSlaveClien"
  },
  {
    "path": "QedisCore/QSlowLog.cc",
    "chars": 1486,
    "preview": "#include <sys/time.h>\n#include <fstream>\n#include <sstream>\n\n#include \"Log/Logger.h\"\n#include \"QSlowLog.h\"\n\nnamespace qe"
  },
  {
    "path": "QedisCore/QSlowLog.h",
    "chars": 1075,
    "preview": "#ifndef BERT_QSLOWLOG_H\n#define BERT_QSLOWLOG_H\n\n#include <vector>\n#include <deque>\n\n#include \"QString.h\"\n\nclass Logger;"
  },
  {
    "path": "QedisCore/QSortedSet.cc",
    "chars": 13243,
    "preview": "#include \"QSortedSet.h\"\n#include \"QStore.h\"\n#include \"Log/Logger.h\"\n#include <cassert>\n\nnamespace qedis\n{\n\nQSortedSet::M"
  },
  {
    "path": "QedisCore/QSortedSet.h",
    "chars": 1545,
    "preview": "#ifndef BERT_QSORTEDSET_H\n#define BERT_QSORTEDSET_H\n\n#include \"QString.h\"\n#include \"QHelper.h\"\n#include <map>\n#include <"
  },
  {
    "path": "QedisCore/QStore.cc",
    "chars": 22305,
    "preview": "#include \"QStore.h\"\n#include \"QClient.h\"\n#include \"QConfig.h\"\n#include \"QAOF.h\"\n#include \"QMulti.h\"\n#include \"Log/Logger"
  },
  {
    "path": "QedisCore/QStore.h",
    "chars": 7005,
    "preview": "#ifndef BERT_QSTORE_H\n#define BERT_QSTORE_H\n\n#include \"QCommon.h\"\n#include \"QSet.h\"\n#include \"QSortedSet.h\"\n#include \"QH"
  },
  {
    "path": "QedisCore/QString.cc",
    "chars": 17408,
    "preview": "#include \"QString.h\"\n#include \"QStore.h\"\n#include \"Log/Logger.h\"\n#include <cassert>\n\nnamespace qedis\n{\n\nQObject QObject:"
  },
  {
    "path": "QedisCore/QString.h",
    "chars": 340,
    "preview": "#ifndef BERT_QSTRING_H\n#define BERT_QSTRING_H\n\n#include <string>\n#include <memory>\n\nnamespace qedis\n{\n\nusing QString = s"
  },
  {
    "path": "QedisCore/crc64.c",
    "chars": 10628,
    "preview": "/* Redis uses the CRC64 variant with \"Jones\" coefficients and init value of 0.\n *\n * Specification of this CRC64 variant"
  },
  {
    "path": "QedisCore/redisIntset.c",
    "chars": 16153,
    "preview": "/*\n * Copyright (c) 2009-2012, Pieter Noordhuis <pcnoordhuis at gmail dot com>\n * Copyright (c) 2009-2012, Salvatore San"
  },
  {
    "path": "QedisCore/redisIntset.h",
    "chars": 2230,
    "preview": "/*\n * Copyright (c) 2009-2012, Pieter Noordhuis <pcnoordhuis at gmail dot com>\n * Copyright (c) 2009-2012, Salvatore San"
  },
  {
    "path": "QedisCore/redisZipList.c",
    "chars": 53470,
    "preview": "/* The ziplist is a specially encoded dually linked list that is designed\n * to be very memory efficient. It stores both"
  },
  {
    "path": "QedisCore/redisZipList.h",
    "chars": 2692,
    "preview": "/*\n * Copyright (c) 2009-2012, Pieter Noordhuis <pcnoordhuis at gmail dot com>\n * Copyright (c) 2009-2012, Salvatore San"
  },
  {
    "path": "QedisSvr/CMakeLists.txt",
    "chars": 624,
    "preview": "#PROJECT(QEDISSERVER)\n\nINCLUDE(${PROJECT_SOURCE_DIR}/CMakeCommon)\n\nAUX_SOURCE_DIRECTORY(. QEDISSERVER_SRC)\n\nLINK_DIRECTO"
  },
  {
    "path": "QedisSvr/Qedis.cc",
    "chars": 11725,
    "preview": "//\n//  Qedis.cc\n//\n//  Copyright (c) 2014-2018 Bert Young. All rights reserved.\n//\n\n#include <iostream>\n#include <unistd"
  },
  {
    "path": "QedisSvr/Qedis.h",
    "chars": 827,
    "preview": "//\n//  qedis.h\n//\n//  Created by Bert Young on 16-1-22.\n//  Copyright (c) 2016年 Bert Young. All rights reserved.\n//\n\n#in"
  },
  {
    "path": "QedisSvr/QedisLogo.h",
    "chars": 623,
    "preview": "#ifndef BERT_QEDISLOGO_H\n#define BERT_QEDISLOGO_H\n\nconst char* qedisLogo = \"\\n  _____     _____   _____   _   _____ \\n\"\n"
  },
  {
    "path": "README.md",
    "chars": 2163,
    "preview": "\n     _____     _____   _____   _   ______                  \n    /  _  \\   | ____| |  _  \\ | | /  ___/                  "
  },
  {
    "path": "README.zh.md",
    "chars": 1634,
    "preview": "\n     _____     _____   _____   _   ______                  \n    /  _  \\   | ____| |  _  \\ | | /  ___/                  "
  },
  {
    "path": "UnitTest/CMakeLists.txt",
    "chars": 439,
    "preview": "INCLUDE(${PROJECT_SOURCE_DIR}/CMakeCommon)\n\nAUX_SOURCE_DIRECTORY(. UNITTEST_SRC)\n\nLINK_DIRECTORIES(../../leveldb)\nLINK_D"
  },
  {
    "path": "UnitTest/QGlobRegex_unittest.cc",
    "chars": 2922,
    "preview": "#include \"UnitTest.h\"\n#include \"QGlobRegex.h\"\n\nusing namespace qedis;\n\nTEST_CASE(regex_star)\n{\n    EXPECT_TRUE(glob_matc"
  },
  {
    "path": "UnitTest/UnitTest.cc",
    "chars": 2344,
    "preview": "#include \"UnitTest.h\"\n#include <iostream>\n\nenum Color\n{\n    Color_red       =  1,\n    Color_green         ,\n    Color_ye"
  },
  {
    "path": "UnitTest/UnitTest.h",
    "chars": 2494,
    "preview": "#ifndef BERT_UNITTEST_H\n#define BERT_UNITTEST_H\n\n#include <string>\n#include <sstream>\n#include <vector>\n\nclass UnitTestB"
  },
  {
    "path": "cluster/.gitignore",
    "chars": 34,
    "preview": "# MAC OS\n.DS_Store\n\n#\nbuild/\nbin/\n"
  },
  {
    "path": "cluster/CMakeCommon",
    "chars": 684,
    "preview": "CMAKE_MINIMUM_REQUIRED(VERSION 2.6)\n\nIF(${CMAKE_SYSTEM_NAME} MATCHES \"Linux\")\n    SET(CMAKE_CXX_FLAGS_DEBUG  \"-g -Wall -"
  },
  {
    "path": "cluster/CMakeLists.txt",
    "chars": 194,
    "preview": "CMAKE_MINIMUM_REQUIRED(VERSION 2.6)\n\nPROJECT(QEDIS_CLUSTER)\n\nSUBDIRS(ananas)\n\nSET(USE_ZOOKEEPER 1)\n\nADD_DEFINITIONS(-DUS"
  },
  {
    "path": "cluster/Makefile",
    "chars": 84,
    "preview": "all:\n\tmkdir -p build && cd build && cmake .. && make\nclean:\n\tcd build && make clean\n"
  },
  {
    "path": "cluster/README.md",
    "chars": 1838,
    "preview": "# Qedis分布式集群\n\n## 环境需求\n* C++11、CMake\n* zookeeper\n* Linux 或 MAC OS\n\n## 代码目录\n\n* ananas\n\n  一个C++11编写的网络库,提供了强大的future异步编程模式."
  },
  {
    "path": "cluster/ananas/CMakeLists.txt",
    "chars": 50,
    "preview": "CMAKE_MINIMUM_REQUIRED(VERSION 2.6)\n\nSUBDIRS(net)\n"
  },
  {
    "path": "cluster/ananas/future/Future.h",
    "chars": 22352,
    "preview": "#ifndef BERT_FUTURE_H\r\n#define BERT_FUTURE_H\r\n\r\n#include <atomic>\r\n#include <mutex>\r\n#include <functional>\r\n#include <ty"
  },
  {
    "path": "cluster/ananas/future/Helper.h",
    "chars": 5068,
    "preview": "#ifndef BERT_HELPER_H\n#define BERT_HELPER_H\n\n/*\n * This file is modified from facebook folly, with my annotation\n */\n\n/*"
  },
  {
    "path": "cluster/ananas/future/Try.h",
    "chars": 9313,
    "preview": "#ifndef BERT_TRY_H\r\n#define BERT_TRY_H\r\n\r\n/*\r\n * This class is modified from facebook folly\r\n * Thanks to it for handlin"
  },
  {
    "path": "cluster/ananas/net/Acceptor.cc",
    "chars": 4000,
    "preview": "#include <errno.h>\n#include <cassert>\n#include \"EventLoop.h\"\n#include \"Connection.h\"\n#include \"Acceptor.h\"\n\n#include \"An"
  },
  {
    "path": "cluster/ananas/net/Acceptor.h",
    "chars": 942,
    "preview": "\n#ifndef BERT_ACCEPTOR_H\n#define BERT_ACCEPTOR_H\n\n#include \"Socket.h\"\n#include \"Typedefs.h\"\n\nnamespace ananas\n{\nnamespac"
  },
  {
    "path": "cluster/ananas/net/AnanasDebug.cc",
    "chars": 373,
    "preview": "#include \"AnanasDebug.h\"\n\nnamespace ananas\n{\n\nnamespace internal\n{\n\nstd::shared_ptr<Logger> g_debug;\nstd::once_flag g_lo"
  },
  {
    "path": "cluster/ananas/net/AnanasDebug.h",
    "chars": 320,
    "preview": "#ifndef BERT_ANANASDEBUG_H\n#define BERT_ANANASDEBUG_H\n\n#include <mutex>\n#include \"log/Logger.h\"\n\nnamespace ananas\n{\n\nnam"
  },
  {
    "path": "cluster/ananas/net/AnanasLogo.h",
    "chars": 301,
    "preview": "#ifndef BERT_ANANASLOGO_H\n#define BERT_ANANASLOGO_H\n\nnamespace ananas\n{\nnamespace internal\n{\n\nconst char* logo = \"\"\n\"  _"
  },
  {
    "path": "cluster/ananas/net/Buffer.cc",
    "chars": 4322,
    "preview": "\n#include \"Buffer.h\"\n#include <iostream>\n#include <limits>\n#include <cassert>\n\nnamespace ananas\n{\n\ninline static std::si"
  },
  {
    "path": "cluster/ananas/net/Buffer.h",
    "chars": 4133,
    "preview": "\n#ifndef BERT_BUFFER_H\n#define BERT_BUFFER_H\n\n#include <cstring>\n#include <memory>\n#include <list>\n\nnamespace ananas\n{\n\n"
  },
  {
    "path": "cluster/ananas/net/CMakeLists.txt",
    "chars": 624,
    "preview": "CMAKE_MINIMUM_REQUIRED(VERSION 2.8)\n\nINCLUDE(${PROJECT_SOURCE_DIR}/CMakeCommon)\n\nINCLUDE_DIRECTORIES(${PROJECT_SOURCE_DI"
  },
  {
    "path": "cluster/ananas/net/Connection.cc",
    "chars": 13322,
    "preview": "#include <cassert>\n\n#include <errno.h>\n#include <unistd.h>\n#include <sys/uio.h>\n\n#include \"EventLoop.h\"\n#include \"Connec"
  },
  {
    "path": "cluster/ananas/net/Connection.h",
    "chars": 2800,
    "preview": "\n#ifndef BERT_CONNECTION_H\n#define BERT_CONNECTION_H\n\n#include <sys/types.h>\n#include \"Socket.h\"\n#include \"Poller.h\"\n#in"
  },
  {
    "path": "cluster/ananas/net/Connector.cc",
    "chars": 4738,
    "preview": "#include <errno.h>\n\n#include <cstring>\n#include <cassert>\n#include \"EventLoop.h\"\n#include \"Connector.h\"\n#include \"Connec"
  },
  {
    "path": "cluster/ananas/net/Connector.h",
    "chars": 1166,
    "preview": "\n#ifndef BERT_CONNECTOR_H\n#define BERT_CONNECTOR_H\n\n#include \"Socket.h\"\n#include \"Timer.h\"\n#include \"Typedefs.h\"\n\nnamesp"
  },
  {
    "path": "cluster/ananas/net/DatagramSocket.cc",
    "chars": 4771,
    "preview": "#include <errno.h>\n#include <memory>\n\n#include \"DatagramSocket.h\"\n#include \"EventLoop.h\"\n#include \"AnanasDebug.h\"\n\nnames"
  },
  {
    "path": "cluster/ananas/net/DatagramSocket.h",
    "chars": 1444,
    "preview": "\n#ifndef BERT_DATAGRAMSOCKET_H\n#define BERT_DATAGRAMSOCKET_H\n\n#include <list>\n#include \"Socket.h\"\n#include \"Typedefs.h\"\n"
  },
  {
    "path": "cluster/ananas/net/Epoller.cc",
    "chars": 3084,
    "preview": "#ifdef __gnu_linux__\n\n#include \"Epoller.h\"\n\n#include <errno.h>\n#include <unistd.h>\n\n#include \"AnanasDebug.h\"\n\nnamespace "
  },
  {
    "path": "cluster/ananas/net/Epoller.h",
    "chars": 716,
    "preview": "#ifndef BERT_EPOLLER_H\n#define BERT_EPOLLER_H\n\n#ifdef __gnu_linux__\n\n#include <sys/epoll.h>\n#include <vector>\n#include \""
  },
  {
    "path": "cluster/ananas/net/EventLoop.cc",
    "chars": 8413,
    "preview": "\n#include \"EventLoop.h\"\n\n#include <cassert>\n#include <thread>\n#include <signal.h>\n\n#include \"Acceptor.h\"\n#include \"Conne"
  },
  {
    "path": "cluster/ananas/net/EventLoop.h",
    "chars": 3556,
    "preview": "\n#ifndef BERT_EVENTLOOP_H\n#define BERT_EVENTLOOP_H\n\n#include <map>\n#include <memory>\n#include <sys/resource.h>\n\n#include"
  },
  {
    "path": "cluster/ananas/net/Kqueue.cc",
    "chars": 2837,
    "preview": "#if defined(__APPLE__)\n\n#include \"Kqueue.h\"\n#include \"AnanasDebug.h\"\n\n#include <errno.h>\n#include <unistd.h>\n\nnamespace "
  },
  {
    "path": "cluster/ananas/net/Kqueue.h",
    "chars": 635,
    "preview": "#ifndef BERT_KQUEUE_H\n#define BERT_KQUEUE_H\n\n#if defined(__APPLE__)\n\n#include <vector>\n#include <sys/event.h>\n#include \""
  },
  {
    "path": "cluster/ananas/net/Poller.h",
    "chars": 1444,
    "preview": "#ifndef BERT_POLLER_H\n#define BERT_POLLER_H\n\n#include <vector>\n#include <memory>\n\nnamespace ananas\n{\nnamespace internal\n"
  },
  {
    "path": "cluster/ananas/net/Socket.cc",
    "chars": 3859,
    "preview": "#include <cassert>\n\n#include <fcntl.h>\n#include <netinet/tcp.h>\n#include <unistd.h>\n#include <sys/ioctl.h>\n#include <net"
  },
  {
    "path": "cluster/ananas/net/Socket.h",
    "chars": 2806,
    "preview": "\n#ifndef BERT_SOCKET_H\n#define BERT_SOCKET_H\n\n#include <arpa/inet.h>\n#include <sys/resource.h>\n#include <string.h>\n#incl"
  },
  {
    "path": "cluster/ananas/net/ThreadPool.cc",
    "chars": 2855,
    "preview": "#include \"ThreadPool.h\"\n\nnamespace ananas\n{\n\nthread_local bool ThreadPool::working_ = true;\nstd::thread::id ThreadPool::"
  },
  {
    "path": "cluster/ananas/net/ThreadPool.h",
    "chars": 3904,
    "preview": "#ifndef BERT_THREADPOOL_H\n#define BERT_THREADPOOL_H\n\n#include <deque>\n#include <thread>\n#include <memory>\n#include <futu"
  },
  {
    "path": "cluster/ananas/net/TimeUtil.cc",
    "chars": 1790,
    "preview": "#include <cstring>\n#include \"TimeUtil.h\"\n\nnamespace ananas\n{\n\nTime::Time() : valid_(false)\n{\n    this->Now();\n}\n\nint64_t"
  },
  {
    "path": "cluster/ananas/net/TimeUtil.h",
    "chars": 1157,
    "preview": "\n#ifndef BERT_TIMEUTIL_H\n#define BERT_TIMEUTIL_H\n\n#include <ctime>\n#include <stdint.h>\n#include <mutex>\n#include <chrono"
  },
  {
    "path": "cluster/ananas/net/Timer.cc",
    "chars": 2901,
    "preview": "#include <vector>\n#include <cassert>\n#include \"Timer.h\"\n\nnamespace ananas\n{\nnamespace internal\n{\n\nunsigned int TimerMana"
  },
  {
    "path": "cluster/ananas/net/Timer.h",
    "chars": 3446,
    "preview": "\n#ifndef BERT_TIMERMANAGER_H\n#define BERT_TIMERMANAGER_H\n\n#include <map>\n#include <chrono>\n#include <functional>\n#includ"
  },
  {
    "path": "cluster/ananas/net/Typedefs.h",
    "chars": 918,
    "preview": "#ifndef BERT_TYPEDEFS_H\n#define BERT_TYPEDEFS_H\n\n#include <functional>\n\nnamespace ananas\n{\n    typedef size_t PacketLen_"
  },
  {
    "path": "cluster/ananas/net/log/Logger.cc",
    "chars": 15447,
    "preview": "\n#include <iostream>\n#include <cassert>\n#include <cstdlib>\n#include <cstdio>\n#include <sstream>\n#include <errno.h>\n#incl"
  },
  {
    "path": "cluster/ananas/net/log/Logger.h",
    "chars": 4817,
    "preview": "#ifndef BERT_LOGGER_H\n#define BERT_LOGGER_H\n\n/*\n * A multi-thread Logger class\n */\n\n#include <string>\n#include <vector>\n"
  },
  {
    "path": "cluster/ananas/net/log/MmapFile.cc",
    "chars": 3295,
    "preview": "#include <errno.h>\n#include <fcntl.h>\n#include <assert.h>\n#include <string.h>\n#include <sys/mman.h>\n#include <sys/stat.h"
  },
  {
    "path": "cluster/ananas/net/log/MmapFile.h",
    "chars": 943,
    "preview": "#ifndef BERT_MMAPFILE_H\n#define BERT_MMAPFILE_H\n\n#include <string>\n\nnamespace ananas\n{\nnamespace internal\n{\n\nclass OMmap"
  },
  {
    "path": "cluster/ananas/net/log/README.md",
    "chars": 538,
    "preview": "# Multi-thread log\n# 多线程日志库\n\n## Requirements\n* C++11\n* Linux or MAC OS\n\n## High Performance\nO2优化,\n\n单线程写100万条日志600ms左右,多线"
  },
  {
    "path": "cluster/ananas/util/Delegate.h",
    "chars": 2151,
    "preview": "#ifndef BERT_DELEGATE_H\n#define BERT_DELEGATE_H\n\n#include <functional>\n#include <list>\n\n\nnamespace ananas\n{\n\ntemplate <t"
  },
  {
    "path": "cluster/ananas/util/Scheduler.h",
    "chars": 957,
    "preview": "#ifndef BERT_SCHEDULER_H\n#define BERT_SCHEDULER_H\n\nnamespace ananas\n{\n\nclass Scheduler\n{\npublic:\n    virtual ~Scheduler("
  },
  {
    "path": "cluster/ananas/util/Util.h",
    "chars": 1615,
    "preview": "#ifndef BERT_UTIL_H\n#define BERT_UTIL_H\n\n// Ananas tool box\n\n#include <functional>\n#include <string>\n\nnamespace ananas\n{"
  },
  {
    "path": "cluster/cluster_conn/CMakeLists.txt",
    "chars": 56,
    "preview": "CMAKE_MINIMUM_REQUIRED(VERSION 2.6)\n\nSUBDIRS(zookeeper)\n"
  },
  {
    "path": "cluster/cluster_conn/ClusterConn.h",
    "chars": 348,
    "preview": "#ifndef BERT_CLUSTERCONN_H\n#define BERT_CLUSTERCONN_H\n\nnamespace qedis\n{\n\nclass ClusterConn\n{ \npublic:\n    virtual ~Clus"
  },
  {
    "path": "cluster/cluster_conn/zookeeper/CMakeLists.txt",
    "chars": 416,
    "preview": "CMAKE_MINIMUM_REQUIRED(VERSION 2.6)\n\nINCLUDE(${PROJECT_SOURCE_DIR}/CMakeCommon)\nINCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR"
  },
  {
    "path": "cluster/cluster_conn/zookeeper/ZkResponse.h",
    "chars": 1604,
    "preview": "#ifndef BERT_ZKRESPONSE_H\n#define BERT_ZKRESPONSE_H\n\n#include \"zookeeper.jute.h\"\n#include \"proto.h\"\n\nusing ZkResponse = "
  },
  {
    "path": "cluster/cluster_conn/zookeeper/ZookeeperContext.cc",
    "chars": 13721,
    "preview": "#include <unistd.h>\n#include <sys/time.h>\n#include \"ZookeeperContext.h\"\n#include \"proto.h\"\n#include \"zookeeper.jute.h\"\n#"
  },
  {
    "path": "cluster/cluster_conn/zookeeper/ZookeeperContext.h",
    "chars": 2935,
    "preview": "#ifndef BERT_ZOOKEEPERCONTEXT_H\n#define BERT_ZOOKEEPERCONTEXT_H\n\n#include <queue>\n#include <string>\n#include \"future/Fut"
  },
  {
    "path": "cluster/cluster_conn/zookeeper/proto.h",
    "chars": 4386,
    "preview": "/**\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NO"
  },
  {
    "path": "cluster/cluster_conn/zookeeper/recordio.c",
    "chars": 9749,
    "preview": "/**\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NO"
  },
  {
    "path": "cluster/cluster_conn/zookeeper/recordio.h",
    "chars": 2987,
    "preview": "/**\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NO"
  },
  {
    "path": "cluster/cluster_conn/zookeeper/zookeeper.jute.c",
    "chars": 52155,
    "preview": "/**\n* Licensed to the Apache Software Foundation (ASF) under one\n* or more contributor license agreements.  See the NOTI"
  },
  {
    "path": "cluster/cluster_conn/zookeeper/zookeeper.jute.h",
    "chars": 19977,
    "preview": "/**\n* Licensed to the Apache Software Foundation (ASF) under one\n* or more contributor license agreements.  See the NOTI"
  },
  {
    "path": "cluster/qedis_proxy/CMakeLists.txt",
    "chars": 412,
    "preview": "INCLUDE(${PROJECT_SOURCE_DIR}/CMakeCommon)\n\nINCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR})\nINCLUDE_DIRECTORIES(${PROJECT_SOU"
  },
  {
    "path": "cluster/qedis_proxy/ClientConn.cc",
    "chars": 3992,
    "preview": "#include <cassert>\n#include <algorithm>\n\n#include \"ProxyLog.h\"\n#include \"Command.h\"\n#include \"ClientConn.h\"\n\n#include \"C"
  },
  {
    "path": "cluster/qedis_proxy/ClientConn.h",
    "chars": 457,
    "preview": "#ifndef BERT_CLIENTCONN_H\n#define BERT_CLIENTCONN_H\n\n#include <queue>\n#include <string>\n#include <vector>\n#include <unor"
  },
  {
    "path": "cluster/qedis_proxy/ClientManager.cc",
    "chars": 1681,
    "preview": "#include \"ClientManager.h\"\n#include \"ClientConn.h\"\n#include \"ProxyLog.h\"\n\n#include \"net/EventLoop.h\"\n#include \"net/Conne"
  },
  {
    "path": "cluster/qedis_proxy/ClientManager.h",
    "chars": 651,
    "preview": "#ifndef BERT_CLIENTMANAGER_H\n#define BERT_CLIENTMANAGER_H\n\n#include <unordered_map>\n#include <vector>\n#include <string>\n"
  },
  {
    "path": "cluster/qedis_proxy/ClusterManager.cc",
    "chars": 3889,
    "preview": "#include \"ClusterManager.h\"\n#include \"ProxyLog.h\"\n\n#include \"net/EventLoop.h\"\n#include \"net/Connection.h\"\n#include \"net/"
  },
  {
    "path": "cluster/qedis_proxy/ClusterManager.h",
    "chars": 1148,
    "preview": "#ifndef BERT_CLUSTERMANAGER_H\n#define BERT_CLUSTERMANAGER_H\n\n#include <unordered_map>\n#include <vector>\n#include <string"
  }
]

// ... and 17 more files (download for full content)

About this extraction

This page contains the full source code of the loveyacper/Qedis GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 217 files (1.1 MB), approximately 329.5k tokens, and a symbol index with 1981 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!