/**
 * Tencent is pleased to support the open source community by making Tars available.
 *
 * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
 *
 * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except 
 * in compliance with the License. You may obtain a copy of the License at
 *
 * https://opensource.org/licenses/BSD-3-Clause
 *
 * 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 "util/tc_multi_hashmap.h"
#include "util/tc_pack.h"
#include "util/tc_common.h"

namespace tars
{

int TC_Multi_HashMap::FailureRecover::_iRefCount = 0;

bool TC_Multi_HashMap::MainKey::next()
{
    _iHead = getHeadPtr()->_iNext;
    _pHead = _pMap->getAbsolute(_iHead);
        
    return _iHead != 0;
}
    
bool TC_Multi_HashMap::MainKey::prev()
{
    _iHead = getHeadPtr()->_iPrev;
    _pHead = _pMap->getAbsolute(_iHead);
    
    return _iHead != 0;
}

void TC_Multi_HashMap::MainKey::deallocate()
{
    if(HASNEXTCHUNK())
    {
        // 释放所有chunk
        deallocate(getHeadPtr()->_iNextChunk);
    }
    
    // 释放主key头
    vector<uint32_t> v;
    v.push_back(_iHead);
    _pMap->_pDataAllocator->deallocateMemChunk(v);
}

void TC_Multi_HashMap::MainKey::deallocate(uint32_t iChunk)
{
    vector<uint32_t> v;
    v.push_back(iChunk);

    tagChunkHead *pChunk        = getChunkHead(iChunk);
    
    //获取所有后续的chunk地址
    while(true)
    {
        if(pChunk->_bNextChunk)
        {
            v.push_back(pChunk->_iNextChunk);
            pChunk = getChunkHead(pChunk->_iNextChunk);
        }
        else
        {
            break;
        }
    }
    
    // 空间全部释放掉
    _pMap->_pDataAllocator->deallocateMemChunk(v);
}

void TC_Multi_HashMap::MainKey::makeNew(uint32_t iIndex, uint32_t iAllocSize)
{
    getHeadPtr()->_iSize        = iAllocSize;
    getHeadPtr()->_iIndex        = iIndex;
    getHeadPtr()->_iAddr        = 0;
    getHeadPtr()->_iNext        = 0;
    getHeadPtr()->_iPrev        = 0;
    getHeadPtr()->_iGetNext        = 0;
    getHeadPtr()->_iGetPrev        = 0;
    getHeadPtr()->_iDataLen     = 0;
    SETNEXTCHUNK(false);
    SETFULLDATA(false);

    _pMap->incMainKeyListCount(iIndex);
    
    // 挂到主key链上
    if(_pMap->itemMainKey(iIndex)->_iMainKeyAddr == 0)
    {
        //当前hash桶没有元素
        _pMap->saveValue(&_pMap->itemMainKey(iIndex)->_iMainKeyAddr, _iHead);
        _pMap->saveValue(&getHeadPtr()->_iNext, (uint32_t)0);
        _pMap->saveValue(&getHeadPtr()->_iPrev, (uint32_t)0);
    }
    else
    {
        //当前hash桶有元素, 挂在桶开头
        _pMap->saveValue(&getHeadPtr(_pMap->itemMainKey(iIndex)->_iMainKeyAddr)->_iPrev, _iHead);
        _pMap->saveValue(&getHeadPtr()->_iNext, _pMap->itemMainKey(iIndex)->_iMainKeyAddr);
        _pMap->saveValue(&_pMap->itemMainKey(iIndex)->_iMainKeyAddr, _iHead);
        _pMap->saveValue(&getHeadPtr()->_iPrev, (uint32_t)0);
    }
    
    //挂在Get链表头部
    if(_pMap->_pHead->_iGetHead == 0)
    {
        assert(_pMap->_pHead->_iGetTail == 0);
        _pMap->saveValue(&_pMap->_pHead->_iGetHead, _iHead);
        _pMap->saveValue(&_pMap->_pHead->_iGetTail, _iHead);
    }
    else
    {
        assert(_pMap->_pHead->_iGetTail != 0);
        _pMap->saveValue(&getHeadPtr()->_iGetNext, _pMap->_pHead->_iGetHead);
        _pMap->saveValue(&getHeadPtr(_pMap->_pHead->_iGetHead)->_iGetPrev, _iHead);
        _pMap->saveValue(&_pMap->_pHead->_iGetHead, _iHead);
    }
}

int TC_Multi_HashMap::MainKey::erase(vector<Value> &vtData)
{
    //////////////////修改备份数据链表/////////////
    if(_pMap->_pHead->_iBackupTail == _iHead)
    {
        _pMap->saveValue(&_pMap->_pHead->_iBackupTail, getHeadPtr()->_iGetPrev);
    }

    ////////////////////修改Get链表的数据//////////
    //
    {
        bool bHead = (_pMap->_pHead->_iGetHead == _iHead);
        bool bTail = (_pMap->_pHead->_iGetTail == _iHead);

        if(!bHead)
        {
            if(bTail)
            {
                assert(getHeadPtr()->_iGetNext == 0);
                //是尾部, 尾部指针指向上一个元素
                _pMap->saveValue(&_pMap->_pHead->_iGetTail, getHeadPtr()->_iGetPrev);
                _pMap->saveValue(&getHeadPtr(getHeadPtr()->_iGetPrev)->_iGetNext, (uint32_t)0);
            }
            else
            {
                //不是头部也不是尾部
                assert(getHeadPtr()->_iGetNext != 0);
                _pMap->saveValue(&getHeadPtr(getHeadPtr()->_iGetPrev)->_iGetNext, getHeadPtr()->_iGetNext);
                _pMap->saveValue(&getHeadPtr(getHeadPtr()->_iGetNext)->_iGetPrev, getHeadPtr()->_iGetPrev);
            }
        }
        else
        {
            if(bTail)
            {
                assert(getHeadPtr()->_iGetNext == 0);
                assert(getHeadPtr()->_iGetPrev == 0);
                //头部也是尾部, 指针都设置为0
                _pMap->saveValue(&_pMap->_pHead->_iGetHead, (uint32_t)0);
                _pMap->saveValue(&_pMap->_pHead->_iGetTail, (uint32_t)0);
            }
            else
            {
                //头部不是尾部, 头部指针指向下一个元素
                assert(getHeadPtr()->_iGetNext != 0);
                _pMap->saveValue(&_pMap->_pHead->_iGetHead, getHeadPtr()->_iGetNext);
                //下一个元素上指针为0
                _pMap->saveValue(&getHeadPtr(getHeadPtr()->_iGetNext)->_iGetPrev, (uint32_t)0);
            }
        }
    }

    ///////////////////删除主key下的所有block/////////////////////////////
    string mk;
    int ret = get(mk);
    if(ret != TC_Multi_HashMap::RT_OK)
    {
        // todo, 这里出错会有大问题，前面的修改都应该取消
        return ret;
    }

    while(getHeadPtr()->_iAddr != 0)
    {
        Block block(_pMap, getHeadPtr()->_iAddr);
        Value value;
        value._mkey = mk;
        int ret = block.getBlockData(value._data);
        if(ret == TC_Multi_HashMap::RT_OK)
        {
            vtData.push_back(value);
        }
        block.erase();
    }

    ///////////////////从主key链表中去掉///////////
    //
    //上一个主key指向下一个主key
    if(getHeadPtr()->_iPrev != 0)
    {
        _pMap->saveValue(&getHeadPtr(getHeadPtr()->_iPrev)->_iNext, getHeadPtr()->_iNext);
    }

    //下一个主key指向上一个
    if(getHeadPtr()->_iNext != 0)
    {
        _pMap->saveValue(&getHeadPtr(getHeadPtr()->_iNext)->_iPrev, getHeadPtr()->_iPrev);
    }

    //////////////////如果是hash头部, 需要修改hash索引数据指针//////
    //
    _pMap->delMainKeyListCount(getHeadPtr()->_iIndex);
    if(getHeadPtr()->_iPrev == 0)
    {
        //如果是hash桶的头部, 则还需要处理
        TC_Multi_HashMap::tagMainKeyHashItem *pItem  = _pMap->itemMainKey(getHeadPtr()->_iIndex);
        assert(pItem->_iMainKeyAddr == _iHead);
        if(pItem->_iMainKeyAddr == _iHead)
        {
            _pMap->saveValue(&pItem->_iMainKeyAddr, getHeadPtr()->_iNext);
        }
    }

    // 手工置空一些参数，使在数据恢复区建立记录，以便crash后恢复
    _pMap->saveValue(&getHeadPtr()->_iSize, (uint32_t)0);
    _pMap->saveValue(&getHeadPtr()->_iIndex, (uint32_t)0);
    _pMap->saveValue(&getHeadPtr()->_iBitset, (uint8_t)0);
    _pMap->saveValue(&getHeadPtr()->_iDataLen, (uint32_t)0);

    // 归还内存前先确认上述修改，因为内存被释放后是不能恢复的
    // 即使后面的内存释放失败也不会造成数据的破坏
    _pMap->doUpdate();

    //归还到内存中
    deallocate();

    return RT_OK;
}

void TC_Multi_HashMap::MainKey::refreshGetList()
{
    assert(_pMap->_pHead->_iGetHead != 0);
    assert(_pMap->_pHead->_iGetTail != 0);

    // 本身已经在头部，不需要处理
    if(_pMap->_pHead->_iGetHead == _iHead)
    {
        return;
    }
    
    uint32_t iPrev = getHeadPtr()->_iGetPrev;
    uint32_t iNext = getHeadPtr()->_iGetNext;
    
    assert(iPrev != 0);
    
    //是正在备份的数据
    if(_pMap->_pHead->_iBackupTail == _iHead)
    {
        _pMap->saveValue(&_pMap->_pHead->_iBackupTail, iPrev);
    }
    
    //挂在链表头部
    _pMap->saveValue(&getHeadPtr()->_iGetNext, _pMap->_pHead->_iGetHead);
    _pMap->saveValue(&getHeadPtr(_pMap->_pHead->_iGetHead)->_iGetPrev, _iHead);
    _pMap->saveValue(&_pMap->_pHead->_iGetHead, _iHead);
    _pMap->saveValue(&getHeadPtr()->_iGetPrev, (uint32_t)0);
    
    //上一个元素的Next指针指向下一个元素
    _pMap->saveValue(&getHeadPtr(iPrev)->_iGetNext, iNext);
    
    //下一个元素的Prev指向上一个元素
    if (iNext != 0)
    {
        _pMap->saveValue(&getHeadPtr(iNext)->_iGetPrev, iPrev);
    }
    else
    {
        //改变尾部指针
        assert(_pMap->_pHead->_iGetTail == _iHead);
        _pMap->saveValue(&_pMap->_pHead->_iGetTail, iPrev);
    }
}

int TC_Multi_HashMap::MainKey::allocate(uint32_t iDataLen, vector<TC_Multi_HashMap::Value> &vtData)
{
    uint32_t fn   = 0;
    //一个块的真正的数据容量
    fn = getHeadPtr()->_iSize - sizeof(tagMainKeyHead);
    if(fn >= iDataLen)
    {
        //一个chunk就可以了, 后续的chunk都要释放掉
        if(HASNEXTCHUNK())
        {
            uint32_t iNextChunk = getHeadPtr()->_iNextChunk;
            //先修改自己的区块
            _pMap->saveValue(&getHeadPtr()->_iBitset, NEXTCHUNK_BIT, false);
            _pMap->saveValue(&getHeadPtr()->_iDataLen, (uint32_t)0);
            //修改成功后再释放区块, 从而保证, 不会core的时候导致整个内存块不可用
            deallocate(iNextChunk);
        }
        return TC_Multi_HashMap::RT_OK;
    }

    //计算还需要多少长度
    fn = iDataLen - fn;

    if(HASNEXTCHUNK())
    {
        tagChunkHead *pChunk    = getChunkHead(getHeadPtr()->_iNextChunk);

        while(true)
        {
            if(fn <= (pChunk->_iSize - sizeof(tagChunkHead)))
            {
                //已经不需要chunk了, 释放多余的chunk
                if(pChunk->_bNextChunk)
                {
                    uint32_t iNextChunk = pChunk->_iNextChunk;
                    _pMap->saveValue(&pChunk->_bNextChunk, (uint8_t)false);
                    //一旦异常core, 最坏的情况就是少了可用的区块, 但是整个内存结构还是可用的
                    deallocate(iNextChunk);
                }
                return TC_Multi_HashMap::RT_OK;
            }

            //计算, 还需要多少长度
            fn -= pChunk->_iSize - sizeof(tagChunkHead);

            if(pChunk->_bNextChunk)
            {
                pChunk  =  getChunkHead(pChunk->_iNextChunk);
            }
            else
            {
                //没有后续chunk了, 需要新分配fn的空间
                vector<uint32_t> chunks;
                int ret = allocateChunk(fn, chunks, vtData);
                if(ret != TC_Multi_HashMap::RT_OK)
                {
                    //没有内存可以分配
                    return ret;
                }

                _pMap->saveValue(&pChunk->_bNextChunk, (uint8_t)true);
                _pMap->saveValue(&pChunk->_iNextChunk, chunks[0]);
                //chunk指向分配的第一个chunk
                pChunk  =  getChunkHead(chunks[0]);
                //修改第一个chunk的属性, 保证异常core的时候, chunk链表不会有问题
                _pMap->saveValue(&pChunk->_bNextChunk, (uint8_t)false);
                _pMap->saveValue(&pChunk->_iDataLen, (uint32_t)0);

                //连接每个chunk
                return joinChunk(pChunk, chunks);
            }
        }
    }
    else
    {
        //没有后续chunk了, 需要新分配fn空间
        vector<uint32_t> chunks;
        int ret = allocateChunk(fn, chunks, vtData);
        if(ret != TC_Multi_HashMap::RT_OK)
        {
            //没有内存可以分配
            return ret;
        }

        _pMap->saveValue(&getHeadPtr()->_iBitset, NEXTCHUNK_BIT, true);
        _pMap->saveValue(&getHeadPtr()->_iNextChunk, chunks[0]);
        //chunk指向分配的第一个chunk
        tagChunkHead *pChunk = getChunkHead(chunks[0]);
        //修改第一个chunk的属性, 保证异常core的时候, chunk链表不会有问题
        _pMap->saveValue(&pChunk->_bNextChunk, (uint8_t)false);
        _pMap->saveValue(&pChunk->_iDataLen, (uint32_t)0);

        //连接每个chunk
        return joinChunk(pChunk, chunks);
    }

    return TC_Multi_HashMap::RT_OK;
}

int TC_Multi_HashMap::MainKey::joinChunk(tagChunkHead *pChunk, const vector<uint32_t>& chunks)
{
    for (size_t i = 0; i < chunks.size(); ++i)
    {
        if (i == chunks.size() - 1)
        {
            _pMap->saveValue(&pChunk->_bNextChunk, (uint8_t)false);
            return TC_Multi_HashMap::RT_OK;
        }
        else
        {
            _pMap->saveValue(&pChunk->_bNextChunk, (uint8_t)true);
            _pMap->saveValue(&pChunk->_iNextChunk, chunks[i+1]);
            pChunk  =  getChunkHead(chunks[i+1]);
            _pMap->saveValue(&pChunk->_bNextChunk, (uint8_t)false);
            _pMap->saveValue(&pChunk->_iDataLen, (uint32_t)0);
        }
    }

    return TC_Multi_HashMap::RT_OK;
}

int TC_Multi_HashMap::MainKey::allocateChunk(uint32_t fn, vector<uint32_t> &chunks, vector<TC_Multi_HashMap::Value> &vtData)
{
    assert(fn > 0);

    while(true)
    {
        uint32_t iAllocSize = fn;
        // 分配空间
        // 分配过程中可能会淘汰数据，第一个参数是当前的主key头地址，不能被淘汰
        uint32_t t = _pMap->_pDataAllocator->allocateChunk(_iHead, iAllocSize, vtData);
        if (t == 0)
        {
            //没有内存可以分配了, 先把分配的归还
            _pMap->_pDataAllocator->deallocateMemChunk(chunks);
            chunks.clear();
            return TC_Multi_HashMap::RT_NO_MEMORY;
        }

        //设置分配的数据块的大小
        getChunkHead(t)->_iSize = iAllocSize;

        chunks.push_back(t);

        //分配够了
        if(fn <= (iAllocSize - sizeof(tagChunkHead)))
        {
            break;
        }

        //还需要多少空间
        fn -= iAllocSize - sizeof(tagChunkHead);
    }

    return TC_Multi_HashMap::RT_OK;
}

uint32_t TC_Multi_HashMap::MainKey::getDataLen()
{
    uint32_t n = 0;
    if(!HASNEXTCHUNK())
    {
        // 只有一个chunk
        n += getHeadPtr()->_iDataLen;
        return n;
    }
    
    //当前块的大小
    n += getHeadPtr()->_iSize - sizeof(tagMainKeyHead);
    tagChunkHead *pChunk = getChunkHead(getHeadPtr()->_iNextChunk);
    
    while (true)
    {
        if(pChunk->_bNextChunk)
        {
            //当前块的大小
            n += pChunk->_iSize - sizeof(tagChunkHead);
            pChunk   =  getChunkHead(pChunk->_iNextChunk);
        }
        else
        {
            // 最后一个chunk
            n += pChunk->_iDataLen;
            break;
        }
    }
    
    return n;
}

int TC_Multi_HashMap::MainKey::get(void *pData, uint32_t &iDataLen)
{
    if(!HASNEXTCHUNK())
    {
        // 没有下一个chunk, 一个chunk就可以装下数据了
        iDataLen = min(getHeadPtr()->_iDataLen, iDataLen);
        memcpy(pData, getHeadPtr()->_cData, iDataLen);
        return TC_Multi_HashMap::RT_OK;
    }
    else
    {
        uint32_t iUseSize = getHeadPtr()->_iSize - sizeof(tagMainKeyHead);
        uint32_t iCopyLen = min(iUseSize, iDataLen);
        
        // 先copy第一个chunk的数据
        memcpy(pData, getHeadPtr()->_cData, iCopyLen);
        if (iDataLen < iUseSize)
        {
            return TC_Multi_HashMap::RT_NOTALL_ERR;   // copy数据不完全
        }
        
        // 已经copy长度
        uint32_t iHasLen  = iCopyLen;
        // 最大剩余长度
        uint32_t iLeftLen = iDataLen - iCopyLen;
        
        
        // copy后面所有的chunk中的数据
        tagChunkHead *pChunk    = getChunkHead(getHeadPtr()->_iNextChunk);
        while(iHasLen < iDataLen)
        {
            iUseSize        = pChunk->_iSize - sizeof(tagChunkHead);
            if(!pChunk->_bNextChunk)
            {
                uint32_t iCopyLen = min(pChunk->_iDataLen, iLeftLen);
                memcpy((char*)pData + iHasLen, pChunk->_cData, iCopyLen);
                iDataLen = iHasLen + iCopyLen;
                
                if(iLeftLen < pChunk->_iDataLen)
                {
                    return TC_Multi_HashMap::RT_NOTALL_ERR;       // copy不完全
                }
                
                return TC_Multi_HashMap::RT_OK;
            }
            else
            {
                uint32_t iCopyLen = min(iUseSize, iLeftLen);
                memcpy((char*)pData + iHasLen, pChunk->_cData, iCopyLen);
                if (iLeftLen <= iUseSize)
                {
                    iDataLen = iHasLen + iCopyLen;
                    return TC_Multi_HashMap::RT_NOTALL_ERR;   // copy不完全
                }
                
                iHasLen  += iCopyLen;
                iLeftLen -= iCopyLen;
                
                pChunk   =  getChunkHead(pChunk->_iNextChunk);
            }
        }
    }
    
    return TC_Multi_HashMap::RT_OK;
}

int TC_Multi_HashMap::MainKey::get(string &mk)
{
    // 获取数据长度
    uint32_t iLen = getDataLen();
    
    char *cData = new char[iLen];
    uint32_t iGetLen = iLen;
    int ret = get(cData, iGetLen);
    if(ret == TC_Multi_HashMap::RT_OK)
    {
        // 解码成string
        mk.assign(cData, iGetLen);
    }
    
    delete[] cData;
    
    return ret;
}

int TC_Multi_HashMap::MainKey::set(const void *pData, uint32_t iDataLen, vector<TC_Multi_HashMap::Value> &vtData)
{
    // 首先分配刚刚够的长度, 不能多一个chunk, 也不能少一个chunk
    // allocate会判断当前chunk的长度是否满足iDataLen，少了就加chunk，多了就释放chunk
    int ret = allocate(iDataLen, vtData);
    if(ret != TC_Multi_HashMap::RT_OK)
    {
        return ret;
    }

    // 第一个chunk的有效长度
    uint32_t iUseSize = getHeadPtr()->_iSize - sizeof(tagMainKeyHead);
    if(!HASNEXTCHUNK())
    {
        // 没有下一个chunk, 一个chunk就可以装下数据了
        // 先copy数据, 再复制数据长度
        memcpy(getHeadPtr()->_cData, (char*)pData, iDataLen);
        getHeadPtr()->_iDataLen   = iDataLen;
    }
    else
    {
        // copy到当前的chunk中
        memcpy(getHeadPtr()->_cData, (char*)pData, iUseSize);
        // 剩余程度
        uint32_t iLeftLen = iDataLen - iUseSize;
        uint32_t iCopyLen = iUseSize;

        tagChunkHead *pChunk    = getChunkHead(getHeadPtr()->_iNextChunk);
        while(true)
        {
            // 计算chunk的可用大小
            iUseSize                = pChunk->_iSize - sizeof(tagChunkHead);

            if(!pChunk->_bNextChunk)
            {
                assert(iUseSize >= iLeftLen);
                // copy到当前的chunk中
                memcpy(pChunk->_cData, (char*)pData + iCopyLen, iLeftLen);
                // 最后一个chunk, 才有数据长度, 先copy数据再赋值长度
                pChunk->_iDataLen = iLeftLen;
                iCopyLen += iLeftLen;
                iLeftLen -= iLeftLen;
                break;
            }
            else
            {
                // copy到当前的chunk中
                memcpy(pChunk->_cData, (char*)pData + iCopyLen, iUseSize);
                iCopyLen += iUseSize;
                iLeftLen -= iUseSize;

                pChunk   =  getChunkHead(pChunk->_iNextChunk);
            }
        }
        assert(iLeftLen == 0);
    }

    return TC_Multi_HashMap::RT_OK;
}

int TC_Multi_HashMap::Block::getBlockData(TC_Multi_HashMap::BlockData &data)
{
    data._dirty = isDirty();
    data._synct = getSyncTime();
    data._iVersion = getVersion();

    string s;
    int ret   = get(s);

    if(ret != TC_Multi_HashMap::RT_OK)
    {
        return ret;
    }

    try
    {
        // block保存的数据中，第一部分为除主key外的联合主键
        TC_PackOut po(s.c_str(), s.length());
        po >> data._key;

        // 如果不是只有Key
        if(!isOnlyKey())
        {
            // 第二部分为数据值
            po >> data._value;
        }
        else
        {
            return TC_Multi_HashMap::RT_ONLY_KEY;
        }
    }
    catch(exception &ex)
    {
        ret = TC_Multi_HashMap::RT_DECODE_ERR;
    }

    return ret;
}

uint32_t TC_Multi_HashMap::Block::getLastBlockHead(bool bUKList)
{
    uint32_t iHead = _iHead;

    if(bUKList)
    {
        // 获取当前联合主键block链上的最后一个block
        while(getBlockHead(iHead)->_iUKBlockNext != 0)
        {
            iHead = getBlockHead(iHead)->_iUKBlockNext;
        }
    }
    else
    {
        // 获取当前主key block链上的最后一个block
        while(getBlockHead(iHead)->_iMKBlockNext != 0)
        {
            iHead = getBlockHead(iHead)->_iMKBlockNext;
        }
    }

    return iHead;
}

int TC_Multi_HashMap::Block::get(void *pData, uint32_t &iDataLen)
{
    if(!HASNEXTCHUNK())
    {
        // 没有下一个chunk, 一个chunk就可以装下数据了
        memcpy(pData, getBlockHead()->_cData, min(getBlockHead()->_iDataLen, iDataLen));
        iDataLen = getBlockHead()->_iDataLen;
        return TC_Multi_HashMap::RT_OK;
    }
    else
    {
        // 第一个chunk的有效空间长度
        uint32_t iUseSize = getBlockHead()->_iSize - sizeof(tagBlockHead);
        uint32_t iCopyLen = min(iUseSize, iDataLen);

        // copy第一个chunk中的数据
        memcpy(pData, getBlockHead()->_cData, iCopyLen);
        if (iDataLen < iUseSize)
        {
            // 外部提供的缓冲区长度不够
            return TC_Multi_HashMap::RT_NOTALL_ERR;   //copy数据不完全
        }

        // 已经copy长度
        uint32_t iHasLen  = iCopyLen;
        // 最大剩余长度
        uint32_t iLeftLen = iDataLen - iCopyLen;

        tagChunkHead *pChunk    = getChunkHead(getBlockHead()->_iNextChunk);
        while(iHasLen < iDataLen)
        {
            iUseSize        = pChunk->_iSize - sizeof(tagChunkHead);
            if(!pChunk->_bNextChunk)
            {
                // 最后一个chunk
                uint32_t iCopyLen = min(pChunk->_iDataLen, iLeftLen);
                memcpy((char*)pData + iHasLen, pChunk->_cData, iCopyLen);
                iDataLen = iHasLen + iCopyLen;

                if(iLeftLen < pChunk->_iDataLen)
                {
                    return TC_Multi_HashMap::RT_NOTALL_ERR;       // copy不完全
                }

                return TC_Multi_HashMap::RT_OK;
            }
            else
            {
                uint32_t iCopyLen = min(iUseSize, iLeftLen);
                // copy当前的chunk
                memcpy((char*)pData + iHasLen, pChunk->_cData, iCopyLen);
                if (iLeftLen <= iUseSize)
                {
                    iDataLen = iHasLen + iCopyLen;
                    return TC_Multi_HashMap::RT_NOTALL_ERR;   // copy不完全
                }

                // copy当前chunk完全
                iHasLen  += iCopyLen;
                iLeftLen -= iCopyLen;

                pChunk   =  getChunkHead(pChunk->_iNextChunk);
            }
        }
    }

    return TC_Multi_HashMap::RT_OK;
}

int TC_Multi_HashMap::Block::get(string &s)
{
    uint32_t iLen = getDataLen();

    char *cData = new char[iLen];
    uint32_t iGetLen = iLen;
    int ret = get(cData, iGetLen);
    if(ret == TC_Multi_HashMap::RT_OK)
    {
        s.assign(cData, iGetLen);
    }

    delete[] cData;

    return ret;
}

int TC_Multi_HashMap::Block::set(const void *pData, uint32_t iDataLen, bool bOnlyKey, 
                                 uint8_t iVersion, vector<TC_Multi_HashMap::Value> &vtData)
{
    // version为0表示外部不关心数据版本，onlykey时也不需要关注数据版本
    if(iVersion != 0 && !isOnlyKey() && getBlockHead()->_iVersion != iVersion)
    {
        // 数据版本不匹配
        return TC_Multi_HashMap::RT_DATA_VER_MISMATCH;
    }

    // 首先分配刚刚够的长度, 不能多一个chunk, 也不能少一个chunk
    // allocate会判断当前chunk的长度是否满足iDataLen，少了就加chunk，多了就释放chunk
    int ret = allocate(iDataLen, vtData);
    if(ret != TC_Multi_HashMap::RT_OK)
    {
        return ret;
    }

    if(bOnlyKey)
    {
        // 原始数据是脏数据
        if(isDirty())
        {
            _pMap->delDirtyCount();
        }

        // 数据被修改, 设置为脏数据
        SETDIRTY(false);

        // 原始数据不是OnlyKey数据
        if(!isOnlyKey())
        {
            _pMap->incOnlyKeyCount();
        }
    }
    else
    {
        //原始数据不是脏数据
        if(!isDirty())
        {
            _pMap->incDirtyCount();
        }

        //数据被修改, 设置为脏数据
        SETDIRTY(true);

        //原始数据是OnlyKey数据
        if(isOnlyKey())
        {
            _pMap->delOnlyKeyCount();
        }

        // 递增数据版本
        iVersion = getBlockHead()->_iVersion;
        iVersion ++;
        if(iVersion == 0)
        {
            // 0是保留版本，有效版本范围是1-255
            iVersion = 1;
        }
        getBlockHead()->_iVersion = iVersion;
    }

    //设置是否只有Key
    SETONLYKEY(bOnlyKey);

    // 第一个chunk的有效空间大小
    uint32_t iUseSize = getBlockHead()->_iSize - sizeof(tagBlockHead);
    if(!HASNEXTCHUNK())
    {
        // 没有下一个chunk, 一个chunk就可以装下数据了
        memcpy(getBlockHead()->_cData, (char*)pData, iDataLen);
        getBlockHead()->_iDataLen   = iDataLen;
    }
    else
    {
        // copy到第一个chunk中
        memcpy(getBlockHead()->_cData, (char*)pData, iUseSize);
        // 剩余程度
        uint32_t iLeftLen = iDataLen - iUseSize;
        uint32_t iCopyLen = iUseSize;

        tagChunkHead *pChunk    = getChunkHead(getBlockHead()->_iNextChunk);
        while(true)
        {
            // 计算chunk的可用大小
            iUseSize                = pChunk->_iSize - sizeof(tagChunkHead);

            if(!pChunk->_bNextChunk)
            {
                assert(iUseSize >= iLeftLen);
                // copy到当前的chunk中
                memcpy(pChunk->_cData, (char*)pData + iCopyLen, iLeftLen);
                // 最后一个chunk, 才有数据长度, 先copy数据再赋值长度
                pChunk->_iDataLen = iLeftLen;
                iCopyLen += iLeftLen;
                iLeftLen -= iLeftLen;
                break;
            }
            else
            {
                // copy到当前的chunk中
                memcpy(pChunk->_cData, (char*)pData + iCopyLen, iUseSize);
                iCopyLen += iUseSize;
                iLeftLen -= iUseSize;

                pChunk   =  getChunkHead(pChunk->_iNextChunk);
            }
        }
        assert(iLeftLen == 0);
    }

    return TC_Multi_HashMap::RT_OK;
}

void TC_Multi_HashMap::Block::setDirty(bool b)
{
    if (b)
    {
        if(!isDirty())
        {
            SETDIRTY(b);
            _pMap->incDirtyCount();
        }
    }
    else
    {
        if(isDirty())
        {
            SETDIRTY(b);
            _pMap->delDirtyCount();
        }
    }
}

bool TC_Multi_HashMap::Block::nextBlock()
{
    _iHead = getBlockHead()->_iUKBlockNext;
    _pHead = _pMap->getAbsolute(_iHead);

    return _iHead != 0;
}

bool TC_Multi_HashMap::Block::prevBlock()
{
    _iHead = getBlockHead()->_iUKBlockPrev;
    _pHead = _pMap->getAbsolute(_iHead);

    return _iHead != 0;
}

void TC_Multi_HashMap::Block::deallocate()
{
    // 先释放所有的后续chunk
    if(HASNEXTCHUNK())
    {
        deallocate(getBlockHead()->_iNextChunk);
    }

    // 再释放第一个chunk
    vector<uint32_t> v;
    v.push_back(_iHead);
    _pMap->_pDataAllocator->deallocateMemChunk(v);
}

void TC_Multi_HashMap::Block::makeNew(uint32_t iMainKeyAddr, uint32_t uIndex, uint32_t iAllocSize, bool bHead)
{
    getBlockHead()->_iSize          = iAllocSize;
    getBlockHead()->_iIndex         = uIndex;
    getBlockHead()->_iUKBlockNext   = 0;
    getBlockHead()->_iUKBlockPrev   = 0;
    getBlockHead()->_iMKBlockNext   = 0;
    getBlockHead()->_iMKBlockPrev   = 0;
    getBlockHead()->_iSetNext       = 0;
    getBlockHead()->_iSetPrev       = 0;
    getBlockHead()->_iMainKey       = iMainKeyAddr;
    getBlockHead()->_iSyncTime      = 0;
    getBlockHead()->_iDataLen       = 0;
    getBlockHead()->_iVersion        = 1;        // 有效版本范围1-255
    SETONLYKEY(false);
    SETDIRTY(true);
    SETNEXTCHUNK(false);

    _pMap->incDirtyCount();
    _pMap->incElementCount();
    _pMap->incListCount(uIndex);

    // 增加主key下面的block数量
    MainKey mainKey(_pMap, iMainKeyAddr);
    _pMap->saveValue(&mainKey.getHeadPtr()->_iBlockCount, mainKey.getHeadPtr()->_iBlockCount + 1);
    _pMap->updateMaxMainKeyBlockCount(mainKey.getHeadPtr()->_iBlockCount);

    // 挂在block链表上
    if(_pMap->item(uIndex)->_iBlockAddr == 0)
    {
        // 当前hash桶没有元素
        _pMap->saveValue(&_pMap->item(uIndex)->_iBlockAddr, _iHead);
        _pMap->saveValue(&getBlockHead()->_iUKBlockNext, (uint32_t)0);
        _pMap->saveValue(&getBlockHead()->_iUKBlockPrev, (uint32_t)0);
    }
    else
    {
        // 当前hash桶有元素, 挂在桶开头
        _pMap->saveValue(&getBlockHead(_pMap->item(uIndex)->_iBlockAddr)->_iUKBlockPrev, _iHead);
        _pMap->saveValue(&getBlockHead()->_iUKBlockNext, _pMap->item(uIndex)->_iBlockAddr);
        _pMap->saveValue(&_pMap->item(uIndex)->_iBlockAddr, _iHead);
        _pMap->saveValue(&getBlockHead()->_iUKBlockPrev, (uint32_t)0);
    }

    // 挂在主key链上
    if(mainKey.getHeadPtr()->_iAddr == 0)
    {
        // 当前主key链上还没有元素
        _pMap->saveValue(&mainKey.getHeadPtr()->_iAddr, _iHead);
        _pMap->saveValue(&getBlockHead()->_iMKBlockNext, (uint32_t)0);
        _pMap->saveValue(&getBlockHead()->_iMKBlockPrev, (uint32_t)0);
    }
    else
    {
        // 当前主key链上已经有元素
        if(bHead)
        {
            // 挂在最前面
            _pMap->saveValue(&getBlockHead(mainKey.getHeadPtr()->_iAddr)->_iMKBlockPrev, _iHead);
            _pMap->saveValue(&getBlockHead()->_iMKBlockNext, mainKey.getHeadPtr()->_iAddr);
            _pMap->saveValue(&mainKey.getHeadPtr()->_iAddr, _iHead);
            _pMap->saveValue(&getBlockHead()->_iMKBlockPrev, (uint32_t)0);
        }
        else
        {
            // 挂到最后面
            Block blkHead(_pMap, mainKey.getHeadPtr()->_iAddr);
            uint32_t iLast = blkHead.getLastBlockHead(false);
            _pMap->saveValue(&getBlockHead(iLast)->_iMKBlockNext, _iHead);
            _pMap->saveValue(&getBlockHead()->_iMKBlockNext, (uint32_t)0);
            _pMap->saveValue(&getBlockHead()->_iMKBlockPrev, iLast);
        }
    }

    // 挂在Set链表的头部
    if(_pMap->_pHead->_iSetHead == 0)
    {
        assert(_pMap->_pHead->_iSetTail == 0);
        _pMap->saveValue(&_pMap->_pHead->_iSetHead, _iHead);
        _pMap->saveValue(&_pMap->_pHead->_iSetTail, _iHead);
    }
    else
    {
        assert(_pMap->_pHead->_iSetTail != 0);
        _pMap->saveValue(&getBlockHead()->_iSetNext, _pMap->_pHead->_iSetHead);
        _pMap->saveValue(&getBlockHead(_pMap->_pHead->_iSetHead)->_iSetPrev, _iHead);
        _pMap->saveValue(&_pMap->_pHead->_iSetHead, _iHead);
    }
}

void TC_Multi_HashMap::Block::erase()
{
    //////////////////修改脏数据链表/////////////
    if(_pMap->_pHead->_iDirtyTail == _iHead)
    {
        _pMap->saveValue(&_pMap->_pHead->_iDirtyTail, getBlockHead()->_iSetPrev);
    }

    //////////////////修改回写数据链表/////////////
    if(_pMap->_pHead->_iSyncTail == _iHead)
    {
        _pMap->saveValue(&_pMap->_pHead->_iSyncTail, getBlockHead()->_iSetPrev);
    }

    ////////////////////修改Set链表的数据//////////
    {
        bool bHead = (_pMap->_pHead->_iSetHead == _iHead);
        bool bTail = (_pMap->_pHead->_iSetTail == _iHead);

        if(!bHead)
        {
            if(bTail)
            {
                assert(getBlockHead()->_iSetNext == 0);
                // 是尾部, 尾部指针指向上一个元素
                _pMap->saveValue(&_pMap->_pHead->_iSetTail, getBlockHead()->_iSetPrev);
                _pMap->saveValue(&getBlockHead(getBlockHead()->_iSetPrev)->_iSetNext, (uint32_t)0);
            }
            else
            {
                // 不是头部也不是尾部
                assert(getBlockHead()->_iSetNext != 0);
                _pMap->saveValue(&getBlockHead(getBlockHead()->_iSetPrev)->_iSetNext, getBlockHead()->_iSetNext);
                _pMap->saveValue(&getBlockHead(getBlockHead()->_iSetNext)->_iSetPrev, getBlockHead()->_iSetPrev);
            }
        }
        else
        {
            if(bTail)
            {
                assert(getBlockHead()->_iSetNext == 0);
                assert(getBlockHead()->_iSetPrev == 0);
                // 头部也是尾部, 指针都设置为0
                _pMap->saveValue(&_pMap->_pHead->_iSetHead, (uint32_t)0);
                _pMap->saveValue(&_pMap->_pHead->_iSetTail, (uint32_t)0);
            }
            else
            {
                // 头部不是尾部, 头部指针指向下一个元素
                assert(getBlockHead()->_iSetNext != 0);
                _pMap->saveValue(&_pMap->_pHead->_iSetHead, getBlockHead()->_iSetNext);
                // 下一个元素上指针为0
                _pMap->saveValue(&getBlockHead(getBlockHead()->_iSetNext)->_iSetPrev, (uint32_t)0);
            }
        }
    }

    ////////////////////修改主key链表的数据//////////
    //
    {
        MainKey mainKey(_pMap, getBlockHead()->_iMainKey);
        if(getBlockHead()->_iMKBlockPrev != 0)
        {
            // 将上一下block指向下一个
            _pMap->saveValue(&getBlockHead(getBlockHead()->_iMKBlockPrev)->_iMKBlockNext, getBlockHead()->_iMKBlockNext);
        }
        else
        {
            // 主key链上的第一个
            _pMap->saveValue(&mainKey.getHeadPtr()->_iAddr, getBlockHead()->_iMKBlockNext);
        }
        if(getBlockHead()->_iMKBlockNext != 0)
        {
            // 将下一个block指向上一个
            _pMap->saveValue(&getBlockHead(getBlockHead()->_iMKBlockNext)->_iMKBlockPrev, getBlockHead()->_iMKBlockPrev);
        }
    }

    ///////////////////从block链表中去掉///////////
    //
    //上一个block指向下一个block
    if(getBlockHead()->_iUKBlockPrev != 0)
    {
        _pMap->saveValue(&getBlockHead(getBlockHead()->_iUKBlockPrev)->_iUKBlockNext, getBlockHead()->_iUKBlockNext);
    }

    //下一个block指向上一个
    if(getBlockHead()->_iUKBlockNext != 0)
    {
        _pMap->saveValue(&getBlockHead(getBlockHead()->_iUKBlockNext)->_iUKBlockPrev, getBlockHead()->_iUKBlockPrev);
    }

    //////////////////如果是hash头部, 需要修改hash索引数据指针//////
    //
    _pMap->delListCount(getBlockHead()->_iIndex);
    if(getBlockHead()->_iUKBlockPrev == 0)
    {
        //如果是hash桶的头部, 则还需要处理
        TC_Multi_HashMap::tagHashItem *pItem  = _pMap->item(getBlockHead()->_iIndex);
        assert(pItem->_iBlockAddr == _iHead);
        if(pItem->_iBlockAddr == _iHead)
        {
            _pMap->saveValue(&pItem->_iBlockAddr, getBlockHead()->_iUKBlockNext);
        }
    }

    //////////////////脏数据///////////////////
    //
    if (isDirty())
    {
        _pMap->delDirtyCount();
    }

    if(isOnlyKey())
    {
        _pMap->delOnlyKeyCount();
    }

    //元素个数减少
    _pMap->delElementCount();

    // 减少主key下数据个数
    MainKey mainKey(_pMap, getBlockHead()->_iMainKey);
    _pMap->saveValue(&mainKey.getHeadPtr()->_iBlockCount, mainKey.getHeadPtr()->_iBlockCount - 1);
    _pMap->updateMaxMainKeyBlockCount(mainKey.getHeadPtr()->_iBlockCount);

    // 手工置空一些参数，使在数据恢复区建立记录，以便crash后恢复
    _pMap->saveValue(&getBlockHead()->_iSize, (uint32_t)0);
    _pMap->saveValue(&getBlockHead()->_iIndex, (uint32_t)0);
    _pMap->saveValue(&getBlockHead()->_iSyncTime, (time_t)0);
    _pMap->saveValue(&getBlockHead()->_iBitset, (uint8_t)0);
    _pMap->saveValue(&getBlockHead()->_iDataLen, (uint32_t)0);
    // 特别地，这里一定要手工置block指向的mainkey为空，否则crash后的恢复将无法建立起block与mainkey的联系
    _pMap->saveValue(&getBlockHead()->_iMainKey, (uint32_t)0);

    // 归还内存前先确认上述修改，因为内存被释放后是不能恢复的
    // 即使后面的内存释放失败也不会造成数据的破坏，只会造成一个数据的丢失
    _pMap->doUpdate();

    //归还到内存中
    deallocate();
}

void TC_Multi_HashMap::Block::refreshSetList()
{
    assert(_pMap->_pHead->_iSetHead != 0);
    assert(_pMap->_pHead->_iSetTail != 0);

    //修改同步链表
    if(_pMap->_pHead->_iSyncTail == _iHead && _pMap->_pHead->_iSetHead != _iHead)
    {
        _pMap->saveValue(&_pMap->_pHead->_iSyncTail, getBlockHead()->_iSetPrev);
    }

    //修改脏数据尾部链表指针, 不仅一个元素
    if(_pMap->_pHead->_iDirtyTail == _iHead && _pMap->_pHead->_iSetHead != _iHead)
    {
        //脏数据尾部位置前移
        _pMap->saveValue(&_pMap->_pHead->_iDirtyTail, getBlockHead()->_iSetPrev);
    }
    else if (_pMap->_pHead->_iDirtyTail == 0)
    {
        //原来没有脏数据
        _pMap->saveValue(&_pMap->_pHead->_iDirtyTail, _iHead);
    }

    //是头部数据或者set新数据时走到这个分支
    if(_pMap->_pHead->_iSetHead == _iHead)
    {
        //刷新Get链
        MainKey mainKey(_pMap, getBlockHead()->_iMainKey);
        mainKey.refreshGetList();
        return;
    }

    uint32_t iPrev = getBlockHead()->_iSetPrev;
    uint32_t iNext = getBlockHead()->_iSetNext;

    assert(iPrev != 0);

    //挂在链表头部
    _pMap->saveValue(&getBlockHead()->_iSetNext, _pMap->_pHead->_iSetHead);
    _pMap->saveValue(&getBlockHead(_pMap->_pHead->_iSetHead)->_iSetPrev, _iHead);
    _pMap->saveValue(&_pMap->_pHead->_iSetHead, _iHead);
    _pMap->saveValue(&getBlockHead()->_iSetPrev, (uint32_t)0);

    //上一个元素的Next指针指向下一个元素
    _pMap->saveValue(&getBlockHead(iPrev)->_iSetNext, iNext);

    //下一个元素的Prev指向上一个元素
    if (iNext != 0)
    {
        _pMap->saveValue(&getBlockHead(iNext)->_iSetPrev, iPrev);
    }
    else
    {
        //改变尾部指针
        assert(_pMap->_pHead->_iSetTail == _iHead);
        _pMap->saveValue(&_pMap->_pHead->_iSetTail, iPrev);
    }

    //刷新Get链
    MainKey mainKey(_pMap, getBlockHead()->_iMainKey);
    mainKey.refreshGetList();
}


void TC_Multi_HashMap::Block::deallocate(uint32_t iChunk)
{
    tagChunkHead *pChunk = getChunkHead(iChunk);
    vector<uint32_t> v;
    v.push_back(iChunk);

    //获取所有后续的chunk地址
    while(true)
    {
        if(pChunk->_bNextChunk)
        {
            v.push_back(pChunk->_iNextChunk);
            pChunk = getChunkHead(pChunk->_iNextChunk);
        }
        else
        {
            break;
        }
    }

    //空间全部释放掉
    _pMap->_pDataAllocator->deallocateMemChunk(v);
}

int TC_Multi_HashMap::Block::allocate(uint32_t iDataLen, vector<TC_Multi_HashMap::Value> &vtData)
{
    uint32_t fn   = 0;

    // 第一个chunk的有效数据容量
    fn = getBlockHead()->_iSize - sizeof(tagBlockHead);
    if(fn >= iDataLen)
    {
        // 一个chunk就可以了, 后续的chunk都要释放掉
        if(HASNEXTCHUNK())
        {
            uint32_t iNextChunk = getBlockHead()->_iNextChunk;
            // 先修改自己的区块
            _pMap->saveValue(&getBlockHead()->_iBitset, NEXTCHUNK_BIT, false);
            _pMap->saveValue(&getBlockHead()->_iDataLen, (uint32_t)0);
            // 修改成功后再释放区块, 从而保证, 不会core的时候导致整个内存块不可用
            deallocate(iNextChunk);
        }
        return TC_Multi_HashMap::RT_OK;
    }

    // 计算还需要多少长度
    fn = iDataLen - fn;

    if(HASNEXTCHUNK())
    {
        tagChunkHead *pChunk    = getChunkHead(getBlockHead()->_iNextChunk);

        while(true)
        {
            if(fn <= (pChunk->_iSize - sizeof(tagChunkHead)))
            {
                //已经不需要chunk了, 释放多余的chunk
                if(pChunk->_bNextChunk)
                {
                    uint32_t iNextChunk = pChunk->_iNextChunk;
                    _pMap->saveValue(&pChunk->_bNextChunk, (uint8_t)false);
                    //一旦异常core, 最坏的情况就是少了可用的区块, 但是整个内存结构还是可用的
                    deallocate(iNextChunk);
                }
                return TC_Multi_HashMap::RT_OK ;
            }

            //计算, 还需要多少长度
            fn -= pChunk->_iSize - sizeof(tagChunkHead);

            if(pChunk->_bNextChunk)
            {
                pChunk  =  getChunkHead(pChunk->_iNextChunk);
            }
            else
            {
                //没有后续chunk了, 需要新分配fn的空间
                vector<uint32_t> chunks;
                int ret = allocateChunk(fn, chunks, vtData);
                if(ret != TC_Multi_HashMap::RT_OK)
                {
                    //没有内存可以分配
                    return ret;
                }

                _pMap->saveValue(&pChunk->_bNextChunk, (uint8_t)true);
                _pMap->saveValue(&pChunk->_iNextChunk, chunks[0]);
                //chunk指向分配的第一个chunk
                pChunk  =  getChunkHead(chunks[0]);
                //修改第一个chunk的属性, 保证异常core的时候, chunk链表不会有问题
                _pMap->saveValue(&pChunk->_bNextChunk, (uint8_t)false);
                _pMap->saveValue(&pChunk->_iDataLen, (uint32_t)0);

                //连接每个chunk
                return joinChunk(pChunk, chunks);
            }
        }
    }
    else
    {
        //没有后续chunk了, 需要新分配fn空间
        vector<uint32_t> chunks;
        int ret = allocateChunk(fn, chunks, vtData);
        if(ret != TC_Multi_HashMap::RT_OK)
        {
            //没有内存可以分配
            return ret;
        }

        _pMap->saveValue(&getBlockHead()->_iBitset, NEXTCHUNK_BIT, true);
        _pMap->saveValue(&getBlockHead()->_iNextChunk, chunks[0]);
        //chunk指向分配的第一个chunk
        tagChunkHead *pChunk = getChunkHead(chunks[0]);
        //修改第一个chunk的属性, 保证异常core的时候, chunk链表不会有问题
        _pMap->saveValue(&pChunk->_bNextChunk, (uint8_t)false);
        _pMap->saveValue(&pChunk->_iDataLen, (uint32_t)0);

        //连接每个chunk
        return joinChunk(pChunk, chunks);
    }

    return TC_Multi_HashMap::RT_OK;
}

int TC_Multi_HashMap::Block::joinChunk(tagChunkHead *pChunk, const vector<uint32_t>& chunks)
{
    for (size_t i = 0; i < chunks.size(); ++i)
    {
        if (i == chunks.size() - 1)
        {
            _pMap->saveValue(&pChunk->_bNextChunk, (uint8_t)false);
            return TC_Multi_HashMap::RT_OK;
        }
        else
        {
            _pMap->saveValue(&pChunk->_bNextChunk, (uint8_t)true);
            _pMap->saveValue(&pChunk->_iNextChunk, chunks[i+1]);
            pChunk  =  getChunkHead(chunks[i+1]);
            _pMap->saveValue(&pChunk->_bNextChunk, (uint8_t)false);
            _pMap->saveValue(&pChunk->_iDataLen, (uint32_t)0);
        }
    }

    return TC_Multi_HashMap::RT_OK;
}

int TC_Multi_HashMap::Block::allocateChunk(uint32_t fn, vector<uint32_t> &chunks, vector<TC_Multi_HashMap::Value> &vtData)
{
    assert(fn > 0);

    while(true)
    {
        uint32_t iAllocSize = fn;
        // 分配空间
        // 正在分配的block所属的主key是不能被淘汰的
        uint32_t t = _pMap->_pDataAllocator->allocateChunk(getBlockHead()->_iMainKey, iAllocSize, vtData);
        if (t == 0)
        {
            //没有内存可以分配了, 先把分配的归还
            _pMap->_pDataAllocator->deallocateMemChunk(chunks);
            chunks.clear();
            return TC_Multi_HashMap::RT_NO_MEMORY;
        }

        //设置分配的数据块的大小
        getChunkHead(t)->_iSize = iAllocSize;

        chunks.push_back(t);

        //分配够了
        if(fn <= (iAllocSize - sizeof(tagChunkHead)))
        {
            break;
        }

        //还需要多少空间
        fn -= iAllocSize - sizeof(tagChunkHead);
    }

    return TC_Multi_HashMap::RT_OK;
}

uint32_t TC_Multi_HashMap::Block::getDataLen()
{
    uint32_t n = 0;
    if(!HASNEXTCHUNK())
    {
        n += getBlockHead()->_iDataLen;
        return n;
    }

    //当前块的大小
    n += getBlockHead()->_iSize - sizeof(tagBlockHead);
    tagChunkHead *pChunk    = getChunkHead(getBlockHead()->_iNextChunk);

    while (true)
    {
        if(pChunk->_bNextChunk)
        {
            //当前块的大小
            n += pChunk->_iSize - sizeof(tagChunkHead);
            pChunk   =  getChunkHead(pChunk->_iNextChunk);
        }
        else
        {
            n += pChunk->_iDataLen;
            break;
        }
    }

    return n;
}

////////////////////////////////////////////////////////

uint32_t TC_Multi_HashMap::BlockAllocator::allocateMemBlock(uint32_t iMainKeyAddr, uint32_t index, bool bHead, 
                                                          uint32_t &iAllocSize, vector<TC_Multi_HashMap::Value> &vtData)
{
begin:
    size_t iAddr = 0;
    size_t bigSize = iAllocSize;
    _pChunkAllocator->allocate2(bigSize, bigSize, iAddr);
    iAllocSize = (uint32_t)bigSize;
    if(iAddr == 0)
    {
        size_t ret = _pMap->eraseExcept(iMainKeyAddr, vtData);
        if(ret == 0)
        {
            return 0;     //没有空间可以释放了
        }
        goto begin;
    }

    // 初始化block头部信息
    Block block(_pMap, (uint32_t)iAddr);
    block.makeNew(iMainKeyAddr, index, iAllocSize, bHead);

    _pMap->incChunkCount();

    return (uint32_t)iAddr;
}

uint32_t TC_Multi_HashMap::BlockAllocator::allocateMainKeyHead(uint32_t index, vector<TC_Multi_HashMap::Value> &vtData)
{
    size_t iAllocSize = sizeof(MainKey::tagMainKeyHead);
begin:
    size_t iAddr = 0;
    _pChunkAllocator->allocate2(iAllocSize, iAllocSize, iAddr);
    if(iAddr == 0)
    {
        size_t ret = _pMap->eraseExcept(0, vtData);
        if(ret == 0)
        {
            return 0;     //没有空间可以释放了
        }
        goto begin;
    }

    // 分配的新的MemBlock, 初始化一下
    MainKey mainKey(_pMap, (uint32_t)iAddr);
    mainKey.makeNew(index, (uint32_t)iAllocSize);

    _pMap->incChunkCount();

    return (uint32_t)iAddr;
}


uint32_t TC_Multi_HashMap::BlockAllocator::allocateChunk(uint32_t iAddr, uint32_t &iAllocSize, vector<TC_Multi_HashMap::Value> &vtData)
{
begin:
    size_t iChunkAddr = 0;
    size_t bigSize = iAllocSize;
    _pChunkAllocator->allocate2(bigSize, bigSize, iChunkAddr);
    iAllocSize = (uint32_t)bigSize;
    if(iChunkAddr == 0)
    {
        size_t ret = _pMap->eraseExcept(iAddr, vtData);
        if(ret == 0)
        {
            return 0;     //没有空间可以释放了
        }
        goto begin;
    }

    _pMap->incChunkCount();

    return iChunkAddr;
}

void TC_Multi_HashMap::BlockAllocator::deallocateMemChunk(const vector<uint32_t> &v)
{
    for(size_t i = 0; i < v.size(); i++)
    {
        _pChunkAllocator->deallocate2(v[i]);
        _pMap->delChunkCount();
    }
}

void TC_Multi_HashMap::BlockAllocator::deallocateMemChunk(uint32_t iChunk)
{
    _pChunkAllocator->deallocate2(iChunk);
    _pMap->delChunkCount();
}

///////////////////////////////////////////////////////////////////

TC_Multi_HashMap::HashMapLockItem::HashMapLockItem(TC_Multi_HashMap *pMap, uint32_t iAddr)
: _pMap(pMap)
, _iAddr(iAddr)
{
}

TC_Multi_HashMap::HashMapLockItem::HashMapLockItem(const HashMapLockItem &mcmdi)
: _pMap(mcmdi._pMap)
, _iAddr(mcmdi._iAddr)
{
}

TC_Multi_HashMap::HashMapLockItem &TC_Multi_HashMap::HashMapLockItem::operator=(const TC_Multi_HashMap::HashMapLockItem &mcmdi)
{
    if(this != &mcmdi)
    {
        _pMap   = mcmdi._pMap;
        _iAddr  = mcmdi._iAddr;
    }
    return (*this);
}

bool TC_Multi_HashMap::HashMapLockItem::operator==(const TC_Multi_HashMap::HashMapLockItem &mcmdi)
{
    return _pMap == mcmdi._pMap && _iAddr == mcmdi._iAddr;
}

bool TC_Multi_HashMap::HashMapLockItem::operator!=(const TC_Multi_HashMap::HashMapLockItem &mcmdi)
{
    return _pMap != mcmdi._pMap || _iAddr != mcmdi._iAddr;
}

bool TC_Multi_HashMap::HashMapLockItem::isDirty()
{
    Block block(_pMap, _iAddr);
    return block.isDirty();
}

bool TC_Multi_HashMap::HashMapLockItem::isOnlyKey()
{
    Block block(_pMap, _iAddr);
    return block.isOnlyKey();
}

time_t TC_Multi_HashMap::HashMapLockItem::getSyncTime()
{
    Block block(_pMap, _iAddr);
    return block.getSyncTime();
}

int TC_Multi_HashMap::HashMapLockItem::get(TC_Multi_HashMap::Value &v)
{
    Block block(_pMap, _iAddr);
    MainKey mainKey(_pMap, block.getBlockHead()->_iMainKey);

    // 先获取主key
    int ret = mainKey.get(v._mkey);
    if(ret != TC_Multi_HashMap::RT_OK)
    {
        return ret;
    }

    // 获取数据
    ret = block.getBlockData(v._data);
    if(ret != TC_Multi_HashMap::RT_OK)
    {
        return ret;
    }

    return TC_Multi_HashMap::RT_OK;
}

int TC_Multi_HashMap::HashMapLockItem::get(string &mk, string &uk)
{
    Block block(_pMap, _iAddr);
    MainKey mainKey(_pMap, block.getBlockHead()->_iMainKey);

    // 获取主key
    int ret = mainKey.get(mk);
    if(ret != TC_Multi_HashMap::RT_OK)
    {
        return ret;
    }

    // 获取数据区
    string s;
    ret = block.get(s);
    if(ret != TC_Multi_HashMap::RT_OK)
    {
        return ret;
    }

    try
    {
        // 提取除主key外的联合主键
        TC_PackOut po(s.c_str(), s.length());
        po >> uk;
    }
    catch ( exception &ex )
    {
        return TC_Multi_HashMap::RT_EXCEPTION_ERR;
    }

    return TC_Multi_HashMap::RT_OK;
}

int TC_Multi_HashMap::HashMapLockItem::set(const string &mk, const string &uk, 
                                           const string &v, uint8_t iVersion, vector<TC_Multi_HashMap::Value> &vtData)
{
    Block block(_pMap, _iAddr);

    TC_PackIn pi;
    pi << uk;        // 数据区只存放uk，不存mk，节省空间
    pi << v;

    return block.set(pi.topacket().c_str(), pi.topacket().length(), false, iVersion, vtData);
}

int TC_Multi_HashMap::HashMapLockItem::set(const string &mk, const string &uk, vector<TC_Multi_HashMap::Value> &vtData)
{
    Block block(_pMap, _iAddr);

    TC_PackIn pi;
    pi << uk;        // 数据区只存放uk

    return block.set(pi.topacket().c_str(), pi.topacket().length(), true, 0, vtData);
}

bool TC_Multi_HashMap::HashMapLockItem::equal(const string &mk, const string &uk, TC_Multi_HashMap::Value &v, int &ret)
{
    ret = get(v);

    if ((ret == TC_Multi_HashMap::RT_OK || ret == TC_Multi_HashMap::RT_ONLY_KEY) 
        && mk == v._mkey && uk == v._data._key)
    {
        return true;
    }

    return false;
}

bool TC_Multi_HashMap::HashMapLockItem::equal(const string &mk, const string &uk, int &ret)
{
    string mk1, uk1;
    ret = get(mk1, uk1);

    if (ret == TC_Multi_HashMap::RT_OK && mk == mk1 && uk == uk1)
    {
        return true;
    }

    return false;
}

void TC_Multi_HashMap::HashMapLockItem::nextItem(int iType)
{
    if(_iAddr == 0)
    {
        // 到头了
        return;
    }

    Block block(_pMap, _iAddr);

    if(iType == HashMapLockIterator::IT_BLOCK)
    {
        // 按联合主键索引下的block链遍历
        uint32_t index = block.getBlockHead()->_iIndex;

        //当前block链表有元素
        if(block.nextBlock())
        {
            _iAddr = block.getHead();
            return;
        }

        index += 1;

        while(index < _pMap->_hash.size())
        {
            //当前的hash桶也没有数据
            if (_pMap->item(index)->_iBlockAddr == 0)
            {
                ++index;
                continue;
            }

            _iAddr = _pMap->item(index)->_iBlockAddr;
            return;
        }

        _iAddr = 0;  //到尾部了
    }
    else if(iType == HashMapLockIterator::IT_SET)
    {
        // 按set链遍历
        _iAddr = block.getBlockHead()->_iSetNext;
    }
    else if(iType == HashMapLockIterator::IT_GET)
    {
        // 按get(同一主key下的block)链遍历，即获取下一个get链上的数据
        _iAddr = block.getBlockHead()->_iMKBlockNext;
        if(_iAddr == 0)
        {
            // 当前主key下的block链已经没有数据了，移动GET链上的下一个主key链
            MainKey mainKey(_pMap, block.getBlockHead()->_iMainKey);
            while(mainKey.getHeadPtr()->_iGetNext)
            {
                mainKey = MainKey(_pMap, mainKey.getHeadPtr()->_iGetNext);
                _iAddr = mainKey.getHeadPtr()->_iAddr;
                if(_iAddr != 0)
                {
                    break;
                }
            }
        }
    }
    else if(iType == HashMapLockIterator::IT_MKEY)
    {
        // 按同一主key下block链遍历
        _iAddr = block.getBlockHead()->_iMKBlockNext;
    }
    else if(iType == HashMapLockIterator::IT_UKEY)
    {
        // 按同一联合主键索引的block链遍历
        _iAddr = block.getBlockHead()->_iUKBlockNext;
    }
}

void TC_Multi_HashMap::HashMapLockItem::prevItem(int iType)
{
    if(_iAddr == 0)
    {
        // 到头了
        return;
    }

    Block block(_pMap, _iAddr);

    if(iType == HashMapLockIterator::IT_BLOCK)
    {
        // 按联合主键索引下的block链遍历
        uint32_t index = block.getBlockHead()->_iIndex;
        if(block.prevBlock())
        {
            _iAddr = block.getHead();
            return;
        }

        while(index > 0)
        {
            //当前的hash桶也没有数据
            if (_pMap->item(index-1)->_iBlockAddr == 0)
            {
                --index;
                continue;
            }

            //需要到这个桶的末尾
            Block tmp(_pMap, _pMap->item(index-1)->_iBlockAddr);
            _iAddr = tmp.getLastBlockHead(true);

            return;
        }

        _iAddr = 0;  //到尾部了
    }
    else if(iType == HashMapLockIterator::IT_SET)
    {
        // 按set链遍历
        _iAddr = block.getBlockHead()->_iSetPrev;
    }
    else if(iType == HashMapLockIterator::IT_GET)
    {
        // 按get(同一主key下的block)链遍历，即获取下一个get链上的数据
        _iAddr = block.getBlockHead()->_iMKBlockPrev;
        if(_iAddr == 0)
        {
            // 当前主key下的block链已经没有数据了，移动get链上的上一个主key链
            MainKey mainKey(_pMap, block.getBlockHead()->_iMainKey);
            while(mainKey.getHeadPtr()->_iGetPrev)
            {
                mainKey = MainKey(_pMap, mainKey.getHeadPtr()->_iGetPrev);
                _iAddr = mainKey.getHeadPtr()->_iAddr;
                if(_iAddr != 0)
                {
                    // 移动到主key链上的最后一个block
                    Block tmp(_pMap, _iAddr);
                    while(tmp.getBlockHead()->_iMKBlockNext)
                    {
                        _iAddr = tmp.getBlockHead()->_iMKBlockNext;
                        tmp = Block(_pMap, _iAddr);
                    }
                    break;
                }
            }
        }
    }
    else if(iType == HashMapLockIterator::IT_MKEY)
    {
        // 按同一主key下block链遍历
        _iAddr = block.getBlockHead()->_iMKBlockPrev;
    }
    else if(iType == HashMapLockIterator::IT_UKEY)
    {
        // 按同一联合主键索引的block链遍历
        _iAddr = block.getBlockHead()->_iUKBlockPrev;
    }
}

///////////////////////////////////////////////////////////////////

TC_Multi_HashMap::HashMapLockIterator::HashMapLockIterator()
: _pMap(NULL), _iItem(NULL, 0), _iType(IT_BLOCK), _iOrder(IT_NEXT)
{
}

TC_Multi_HashMap::HashMapLockIterator::HashMapLockIterator(TC_Multi_HashMap *pMap, uint32_t iAddr, int iType, int iOrder)
: _pMap(pMap), _iItem(_pMap, iAddr), _iType(iType), _iOrder(iOrder)
{
}

TC_Multi_HashMap::HashMapLockIterator::HashMapLockIterator(const HashMapLockIterator &it)
: _pMap(it._pMap),_iItem(it._iItem), _iType(it._iType), _iOrder(it._iOrder)
{
}

TC_Multi_HashMap::HashMapLockIterator& TC_Multi_HashMap::HashMapLockIterator::operator=(const HashMapLockIterator &it)
{
    if(this != &it)
    {
        _pMap       = it._pMap;
        _iItem      = it._iItem;
        _iType      = it._iType;
        _iOrder     = it._iOrder;
    }

    return (*this);
}

bool TC_Multi_HashMap::HashMapLockIterator::operator==(const HashMapLockIterator& mcmi)
{
    if (_iItem.getAddr() != 0 || mcmi._iItem.getAddr() != 0)
    {
        return _pMap == mcmi._pMap
            && _iItem == mcmi._iItem
            && _iType == mcmi._iType
            && _iOrder == mcmi._iOrder;
    }

    return _pMap == mcmi._pMap;
}

bool TC_Multi_HashMap::HashMapLockIterator::operator!=(const HashMapLockIterator& mcmi)
{
    if (_iItem.getAddr() != 0 || mcmi._iItem.getAddr() != 0 )
    {
        return _pMap != mcmi._pMap
            || _iItem != mcmi._iItem
            || _iType != mcmi._iType
            || _iOrder != mcmi._iOrder;
    }

    return _pMap != mcmi._pMap;
}

TC_Multi_HashMap::HashMapLockIterator& TC_Multi_HashMap::HashMapLockIterator::operator++()
{
    if(_iOrder == IT_NEXT)
    {
        // 顺序遍历
        _iItem.nextItem(_iType);
    }
    else
    {
        // 逆序遍历
        _iItem.prevItem(_iType);
    }
    return (*this);

}

TC_Multi_HashMap::HashMapLockIterator TC_Multi_HashMap::HashMapLockIterator::operator++(int)
{
    HashMapLockIterator it(*this);

    if(_iOrder == IT_NEXT)
    {
        // 顺序遍历
        _iItem.nextItem(_iType);
    }
    else
    {
        // 逆序遍历
        _iItem.prevItem(_iType);
    }

    return it;

}

///////////////////////////////////////////////////////////////////

TC_Multi_HashMap::HashMapItem::HashMapItem(TC_Multi_HashMap *pMap, uint32_t iIndex)
: _pMap(pMap)
, _iIndex(iIndex)
{
}

TC_Multi_HashMap::HashMapItem::HashMapItem(const HashMapItem &mcmdi)
: _pMap(mcmdi._pMap)
, _iIndex(mcmdi._iIndex)
{
}

TC_Multi_HashMap::HashMapItem &TC_Multi_HashMap::HashMapItem::operator=(const TC_Multi_HashMap::HashMapItem &mcmdi)
{
    if(this != &mcmdi)
    {
        _pMap   = mcmdi._pMap;
        _iIndex  = mcmdi._iIndex;
    }
    return (*this);
}

bool TC_Multi_HashMap::HashMapItem::operator==(const TC_Multi_HashMap::HashMapItem &mcmdi)
{
    return _pMap == mcmdi._pMap && _iIndex == mcmdi._iIndex;
}

bool TC_Multi_HashMap::HashMapItem::operator!=(const TC_Multi_HashMap::HashMapItem &mcmdi)
{
    return _pMap != mcmdi._pMap || _iIndex != mcmdi._iIndex;
}

void TC_Multi_HashMap::HashMapItem::get(vector<TC_Multi_HashMap::Value> &vtData)
{
    uint32_t iAddr = _pMap->item(_iIndex)->_iBlockAddr;

    while(iAddr != 0)
    {
        Block block(_pMap, iAddr);
        MainKey mainKey(_pMap, block.getBlockHead()->_iMainKey);
        TC_Multi_HashMap::Value data;

        // 获取主key
        int ret = mainKey.get(data._mkey);
        if(ret == TC_Multi_HashMap::RT_OK)
        {
            // 获取联合主键及数据
            ret = block.getBlockData(data._data);
            if(ret == TC_Multi_HashMap::RT_OK)
            {
                vtData.push_back(data);
            }
        }

        iAddr = block.getBlockHead()->_iUKBlockNext;
    }
}

void TC_Multi_HashMap::HashMapItem::nextItem()
{
    if(_iIndex == (uint32_t)(-1))
    {
        return;
    }

    if(_iIndex >= _pMap->getHashCount() - 1)
    {
        _iIndex = (uint32_t)(-1);
        return;
    }
    _iIndex++;
}

///////////////////////////////////////////////////////////////////

TC_Multi_HashMap::HashMapIterator::HashMapIterator()
: _pMap(NULL), _iItem(NULL, (uint32_t)-1)
{
}

TC_Multi_HashMap::HashMapIterator::HashMapIterator(TC_Multi_HashMap *pMap, uint32_t iIndex)
: _pMap(pMap), _iItem(_pMap, iIndex)
{
}

TC_Multi_HashMap::HashMapIterator::HashMapIterator(const HashMapIterator &it)
: _pMap(it._pMap),_iItem(it._iItem)
{
}

TC_Multi_HashMap::HashMapIterator& TC_Multi_HashMap::HashMapIterator::operator=(const HashMapIterator &it)
{
    if(this != &it)
    {
        _pMap       = it._pMap;
        _iItem      = it._iItem;
    }

    return (*this);
}

bool TC_Multi_HashMap::HashMapIterator::operator==(const HashMapIterator& mcmi)
{
    if (_iItem.getIndex() != (uint32_t)-1 || mcmi._iItem.getIndex() != (uint32_t)-1)
    {
        return _pMap == mcmi._pMap && _iItem == mcmi._iItem;
    }

    return _pMap == mcmi._pMap;
}

bool TC_Multi_HashMap::HashMapIterator::operator!=(const HashMapIterator& mcmi)
{
    if (_iItem.getIndex() != (uint32_t)-1 || mcmi._iItem.getIndex() != (uint32_t)-1 )
    {
        return _pMap != mcmi._pMap || _iItem != mcmi._iItem;
    }

    return _pMap != mcmi._pMap;
}

TC_Multi_HashMap::HashMapIterator& TC_Multi_HashMap::HashMapIterator::operator++()
{
    _iItem.nextItem();
    return (*this);
}

TC_Multi_HashMap::HashMapIterator TC_Multi_HashMap::HashMapIterator::operator++(int)
{
    HashMapIterator it(*this);
    _iItem.nextItem();
    return it;
}

//////////////////////////////////////////////////////////////////////////////////

void TC_Multi_HashMap::init(void *pAddr)
{
    _pHead          = static_cast<tagMapHead*>(pAddr);
    _pstModifyHead  = static_cast<tagModifyHead*>((void*)((char*)pAddr + sizeof(tagMapHead)));
}

void TC_Multi_HashMap::initDataBlockSize(size_t iMinDataSize, size_t iMaxDataSize, float fFactor)
{
    _iMinDataSize   = iMinDataSize;
    _iMaxDataSize   = iMaxDataSize;
    _fFactor        = fFactor;
}

void TC_Multi_HashMap::create(void *pAddr, size_t iSize)
{
    if(sizeof(tagHashItem)
       + sizeof(tagMainKeyHashItem)
       + sizeof(tagMapHead)
       + sizeof(tagModifyHead)
       + sizeof(TC_MemMultiChunkAllocator::tagChunkAllocatorHead)
       + 10 > iSize)
    {
        throw TC_Multi_HashMap_Exception("[TC_Multi_HashMap::create] mem size not enougth.");
    }

    if(_iMinDataSize == 0 || _iMaxDataSize == 0 || _fFactor < 1.0)
    {
        throw TC_Multi_HashMap_Exception("[TC_Multi_HashMap::create] init data size error:" + TC_Common::tostr(_iMinDataSize) + "|" + TC_Common::tostr(_iMaxDataSize) + "|" + TC_Common::tostr(_fFactor));
    }

    init(pAddr);

    _pHead->_cMaxVersion    = MAX_VERSION;
    _pHead->_cMinVersion    = MIN_VERSION;
    _pHead->_bReadOnly      = false;
    _pHead->_bAutoErase     = true;
    _pHead->_cEraseMode     = ERASEBYGET;
    _pHead->_iMemSize       = iSize;
    _pHead->_iMinDataSize   = _iMinDataSize;
    _pHead->_iMaxDataSize   = _iMaxDataSize;
    _pHead->_fFactor        = _fFactor;
    _pHead->_fHashRatio     = _fHashRatio;
    _pHead->_fMainKeyRatio  = _fMainKeyRatio;
    _pHead->_iElementCount  = 0;
    _pHead->_iEraseCount    = 10;
    _pHead->_iSetHead       = 0;
    _pHead->_iSetTail       = 0;
    _pHead->_iGetHead       = 0;
    _pHead->_iGetTail       = 0;
    _pHead->_iDirtyCount    = 0;
    _pHead->_iDirtyTail     = 0;
    _pHead->_iSyncTime      = 60 * 10;  //缺省十分钟回写一次
    _pHead->_iUsedChunk     = 0;
    _pHead->_iGetCount      = 0;
    _pHead->_iHitCount      = 0;
    _pHead->_iBackupTail    = 0;
    _pHead->_iSyncTail      = 0;
    _pHead->_iMKOnlyKeyCount= 0;
    _pHead->_iOnlyKeyCount    = 0;
    _pHead->_iMaxBlockCount = 0;
    memset(_pHead->_iReserve, 0, sizeof(_pHead->_iReserve));

    size_t iMaxHeadSize = sizeof(Block::tagBlockHead) > sizeof(MainKey::tagMainKeyHead) ? 
                            sizeof(Block::tagBlockHead) : sizeof(MainKey::tagMainKeyHead);

    // 计算平均block大小
    size_t iBlockSize   = (_pHead->_iMinDataSize + _pHead->_iMaxDataSize)/2 + iMaxHeadSize;

    // 计算近似主key Hash个数
    size_t iMHashCount   = (iSize - sizeof(tagMapHead) - sizeof(tagModifyHead) - sizeof(TC_MemChunkAllocator::tagChunkAllocatorHead)) / 
                            ((size_t)(iBlockSize*_fHashRatio*_fMainKeyRatio) + 
                            (size_t)(sizeof(tagHashItem)*_fMainKeyRatio) + sizeof(tagMainKeyHashItem));
    // 采用最近的素数作为hash值
    iMHashCount          = getMinPrimeNumber(iMHashCount);
    // 联合hash个数
    size_t iUHashCount     = getMinPrimeNumber(size_t(iMHashCount * _fMainKeyRatio));

    void *pHashAddr     = (char*)_pHead + sizeof(tagMapHead) + sizeof(tagModifyHead);

    // 主key hash索引区
    size_t iHashMemSize = TC_MemVector<tagMainKeyHashItem>::calcMemSize(iMHashCount);
    if((char*)pHashAddr - (char*)_pHead + iHashMemSize > iSize)
    {
        throw TC_Multi_HashMap_Exception("[TC_Multi_HashMap::create] mem size not enougth.");
    }
    _hashMainKey.create(pHashAddr, iHashMemSize);
    pHashAddr = (char*)pHashAddr + _hashMainKey.getMemSize();

    // 联合hash索引区
    iHashMemSize = TC_MemVector<tagHashItem>::calcMemSize(iUHashCount);
    if((char*)pHashAddr - (char*)_pHead + iHashMemSize > iSize)
    {
        throw TC_Multi_HashMap_Exception("[TC_Multi_HashMap::create] mem size not enougth.");
    }
    _hash.create(pHashAddr, iHashMemSize);

    // chunk数据区
    void *pDataAddr     = (char*)pHashAddr + _hash.getMemSize();
    if((char*)pDataAddr - (char*)_pHead + iMaxHeadSize + _pHead->_iMinDataSize > iSize)
    {
        throw TC_Multi_HashMap_Exception("[TC_Multi_HashMap::create] mem size not enougth.");
    }
    _pDataAllocator->create(pDataAddr, iSize - ((char*)pDataAddr - (char*)_pHead), 
        iMaxHeadSize + _pHead->_iMinDataSize, iMaxHeadSize + _pHead->_iMaxDataSize, _pHead->_fFactor);
}

void TC_Multi_HashMap::connect(void *pAddr, size_t iSize)
{
    init(pAddr);

    if(_pHead->_cMaxVersion != MAX_VERSION || _pHead->_cMinVersion != MIN_VERSION)
    {
        // 版本不匹配
        ostringstream os;
        os << (int)_pHead->_cMaxVersion << "." << (int)_pHead->_cMinVersion << " != " << ((int)MAX_VERSION) << "." << ((int)MIN_VERSION);
        throw TC_Multi_HashMap_Exception("[TC_Multi_HashMap::connect] hash map version not equal:" + os.str() + " (data != code)");
    }

    if(_pHead->_iMemSize != iSize)
    {
        // 内存大小不匹配
        throw TC_Multi_HashMap_Exception("[TC_Multi_HashMap::connect] hash map size not equal:" + TC_Common::tostr(_pHead->_iMemSize) + "!=" + TC_Common::tostr(iSize));
    }

    // 连接主key hash区
    void *pHashAddr = (char*)_pHead + sizeof(tagMapHead) + sizeof(tagModifyHead);
    _hashMainKey.connect(pHashAddr);

    // 连接联合hash区
    pHashAddr = (char*)pHashAddr + _hashMainKey.getMemSize();
    _hash.connect(pHashAddr);

    // 连接chunk区
    void *pDataAddr = (char*)pHashAddr + _hash.getMemSize();
    _pDataAllocator->connect(pDataAddr);

    _iMinDataSize   = _pHead->_iMinDataSize;
    _iMaxDataSize   = _pHead->_iMaxDataSize;
    _fFactor        = _pHead->_fFactor;
    _fHashRatio     = _pHead->_fHashRatio;
    _fMainKeyRatio  = _pHead->_fMainKeyRatio;

    // 恢复可能的错误
    doRecover();
}

int TC_Multi_HashMap::append(void *pAddr, size_t iSize)
{
    if(iSize <= _pHead->_iMemSize)
    {
        return -1;
    }

    init(pAddr);

    if(_pHead->_cMaxVersion != MAX_VERSION || _pHead->_cMinVersion != MIN_VERSION)
    {
        // 版本不匹配
        ostringstream os;
        os << (int)_pHead->_cMaxVersion << "." << (int)_pHead->_cMinVersion << " != " << ((int)MAX_VERSION) << "." << ((int)MIN_VERSION);
        throw TC_Multi_HashMap_Exception("[TC_Multi_HashMap::append] hash map version not equal:" + os.str() + " (data != code)");
    }
    
    _pHead->_iMemSize = iSize;

    // 连接主key hash区
    void *pHashAddr = (char*)_pHead + sizeof(tagMapHead) + sizeof(tagModifyHead);
    _hashMainKey.connect(pHashAddr);

    // 连接联合hash区
    pHashAddr = (char*)pHashAddr + _hashMainKey.getMemSize();
    _hash.connect(pHashAddr);

    // 扩展chunk区
    void *pDataAddr = (char*)pHashAddr + _hash.getMemSize();
    _pDataAllocator->append(pDataAddr, iSize - ((size_t)pDataAddr - (size_t)pAddr));
    
    _iMinDataSize   = _pHead->_iMinDataSize;
    _iMaxDataSize   = _pHead->_iMaxDataSize;
    _fFactor        = _pHead->_fFactor;
    _fHashRatio     = _pHead->_fHashRatio;
    _fMainKeyRatio  = _pHead->_fMainKeyRatio;

    return 0;
}

void TC_Multi_HashMap::clear()
{
    assert(_pHead);

    _pHead->_iElementCount  = 0;
    _pHead->_iSetHead       = 0;
    _pHead->_iSetTail       = 0;
    _pHead->_iGetHead       = 0;
    _pHead->_iGetTail       = 0;
    _pHead->_iDirtyCount    = 0;
    _pHead->_iDirtyTail     = 0;
    _pHead->_iUsedChunk     = 0;
    _pHead->_iGetCount      = 0;
    _pHead->_iHitCount      = 0;
    _pHead->_iBackupTail    = 0;
    _pHead->_iSyncTail      = 0;

    _hashMainKey.clear();
    _hash.clear();

    // 清除错误
    doUpdate();

    _pDataAllocator->rebuild();
}

int TC_Multi_HashMap::dump2file(const string &sFile)
{
    FILE *fp = fopen(sFile.c_str(), "wb");
    if(fp == NULL)
    {
        return RT_DUMP_FILE_ERR;
    }

    size_t ret = fwrite((void*)_pHead, 1, _pHead->_iMemSize, fp);
    fclose(fp);

    if(ret == _pHead->_iMemSize)
    {
        return RT_OK;
    }
    return RT_DUMP_FILE_ERR;
}

int TC_Multi_HashMap::load5file(const string &sFile)
{
    FILE *fp = fopen(sFile.c_str(), "rb");
    if(fp == NULL)
    {
        return RT_LOAD_FILE_ERR;
    }
    fseek(fp, 0L, SEEK_END);
    size_t fs = ftell(fp);
    if(fs != _pHead->_iMemSize)
    {
        fclose(fp);
        return RT_LOAD_FILE_ERR;
    }

    fseek(fp, 0L, SEEK_SET);

    size_t iSize    = 1024*1024*10;
    size_t iLen     = 0;
    char *pBuffer = new char[iSize];
    bool bEof = false;
    while(true)
    {
        int ret = fread(pBuffer, 1, iSize, fp);
        if(ret != (int)iSize)
        {
            if(feof(fp))
            {
                bEof = true;
            }
            else
            {
                fclose(fp);
                delete[] pBuffer;
                return RT_LOAD_FILE_ERR;
            }

        }
        //检查版本
        if(iLen == 0)
        {
            if(pBuffer[0] != MAX_VERSION || pBuffer[1] != MIN_VERSION)
            {
                fclose(fp);
                delete[] pBuffer;
                return RT_VERSION_MISMATCH_ERR;
            }
        }

        memcpy((char*)_pHead + iLen, pBuffer, ret);
        iLen += ret;
        if(bEof)
            break;
    }
    fclose(fp);
    delete[] pBuffer;
    if(iLen == _pHead->_iMemSize)
    {
        return RT_OK;
    }

    return RT_LOAD_FILE_ERR;
}

int TC_Multi_HashMap::checkMainKey(const string &mk)
{
    TC_Multi_HashMap::FailureRecover recover(this);
    
    incGetCount();
    
    int ret          = RT_OK;
    uint32_t index   = mhashIndex(mk);
    if(itemMainKey(index)->_iMainKeyAddr == 0)
    {
        return RT_NO_DATA;
    }
    
    MainKey mainKey(this, itemMainKey(index)->_iMainKeyAddr);
    do 
    {
        string s;
        ret = mainKey.get(s);
        if(ret != RT_OK)
        {
            return ret;
        }
        if(s == mk)
        {
            incHitCount();
            // 找到了
            if(mainKey.getHeadPtr()->_iAddr == 0)
            {
                return RT_ONLY_KEY;
            }
            if(!mainKey.ISFULLDATA())
            {
                return RT_PART_DATA;
            }
            return RT_OK;
        }
        
    } while (mainKey.next());
    
    return RT_NO_DATA;
}

int TC_Multi_HashMap::setFullData(const string &mk, bool bFull)
{
    if(_pHead->_bReadOnly) return RT_READONLY;

    TC_Multi_HashMap::FailureRecover recover(this);
    
    incGetCount();

    int ret          = RT_OK;
    uint32_t index   = mhashIndex(mk);
    if(itemMainKey(index)->_iMainKeyAddr == 0)
    {
        return RT_NO_DATA;
    }
    
    MainKey mainKey(this, itemMainKey(index)->_iMainKeyAddr);
    do 
    {
        string s;
        ret = mainKey.get(s);
        if(ret != RT_OK)
        {
            return ret;
        }
        if(s == mk)
        {
            incHitCount();
            // 找到了
            mainKey.SETFULLDATA(bFull);
            return RT_OK;
        }
        
    } while (mainKey.next());
    
    return RT_NO_DATA;
}

int TC_Multi_HashMap::checkDirty(const string &mk, const string &uk)
{
    TC_Multi_HashMap::FailureRecover recover(this);

    incGetCount();

    int ret          = TC_Multi_HashMap::RT_OK;
    uint32_t index   = hashIndex(mk, uk);
    lock_iterator it = find(mk, uk, index, ret);
    if(ret != TC_Multi_HashMap::RT_OK)
    {
        return ret;
    }

    //没有数据
    if(it == end())
    {
        return TC_Multi_HashMap::RT_NO_DATA;
    }

    incHitCount();

    //只有Key
    if(it->isOnlyKey())
    {
        return TC_Multi_HashMap::RT_ONLY_KEY;
    }

    Block block(this, it->getAddr());
    if (block.isDirty())
    {
        return TC_Multi_HashMap::RT_DIRTY_DATA;
    }

    return TC_Multi_HashMap::RT_OK;
}

int TC_Multi_HashMap::checkDirty(const string &mk)
{
    TC_Multi_HashMap::FailureRecover recover(this);

    incGetCount();

    int ret          = RT_OK;
    uint32_t index   = mhashIndex(mk);
    if(itemMainKey(index)->_iMainKeyAddr == 0)
    {
        return RT_NO_DATA;
    }

    MainKey mainKey(this, itemMainKey(index)->_iMainKeyAddr);
    do 
    {
        string s;
        ret = mainKey.get(s);
        if(ret != RT_OK)
        {
            return ret;
        }
        if(s == mk)
        {
            incHitCount();
            // 找到了
            if(mainKey.getHeadPtr()->_iAddr == 0)
            {
                ret = RT_ONLY_KEY;
            }
            lock_iterator it(this, mainKey.getHeadPtr()->_iAddr, lock_iterator::IT_MKEY, lock_iterator::IT_NEXT);
            while(it != end())
            {
                if(it->isDirty())
                {
                    if(_pHead->_iDirtyTail == 0)
                    {
                        _pHead->_iDirtyTail = mainKey.getHeadPtr()->_iAddr;
                    }
                    return RT_DIRTY_DATA;
                }
                it ++;
            }
            return RT_OK;
        }
        
    } while (mainKey.next());

    return RT_NO_DATA;
}

int TC_Multi_HashMap::setDirty(const string &mk, const string &uk)
{
    TC_Multi_HashMap::FailureRecover recover(this);

    if(_pHead->_bReadOnly) return RT_READONLY;

    incGetCount();

    int ret         = TC_Multi_HashMap::RT_OK;
    uint32_t index    = hashIndex(mk, uk);
    lock_iterator it= find(mk, uk, index, ret);
    if(ret != TC_Multi_HashMap::RT_OK)
    {
        return ret;
    }

    //没有数据或只有Key
    if(it == end())
    {
        return TC_Multi_HashMap::RT_NO_DATA;
    }

    incHitCount();

    //只有Key
    if(it->isOnlyKey())
    {
        return TC_Multi_HashMap::RT_ONLY_KEY;
    }

    Block block(this, it->getAddr());
    block.setDirty(true);
    block.refreshSetList();

    return TC_Multi_HashMap::RT_OK;
}

int TC_Multi_HashMap::setClean(const string &mk, const string &uk)
{
    TC_Multi_HashMap::FailureRecover recover(this);

    if(_pHead->_bReadOnly) return RT_READONLY;

    incGetCount();

    int ret          = TC_Multi_HashMap::RT_OK;
    uint32_t index     = hashIndex(mk, uk);
    lock_iterator it = find(mk, uk, index, ret);
    if(ret != TC_Multi_HashMap::RT_OK)
    {
        return ret;
    }

    //没有数据或只有Key
    if(it == end())
    {
        return TC_Multi_HashMap::RT_NO_DATA;
    }

    incHitCount();

    //只有Key
    if(it->isOnlyKey())
    {
        return TC_Multi_HashMap::RT_ONLY_KEY;
    }

    Block block(this, it->getAddr());
    block.setDirty(false);
    block.refreshSetList();

    return TC_Multi_HashMap::RT_OK;
}

int TC_Multi_HashMap::setSyncTime(const string &mk, const string &uk, time_t iSyncTime)
{
    TC_Multi_HashMap::FailureRecover recover(this);
    
    if(_pHead->_bReadOnly) return RT_READONLY;
    
    incGetCount();
    
    int ret          = TC_Multi_HashMap::RT_OK;
    uint32_t index   = hashIndex(mk, uk);
    lock_iterator it = find(mk, uk, index, ret);
    if(ret != TC_Multi_HashMap::RT_OK)
    {
        return ret;
    }
    
    //没有数据或只有Key
    if(it == end())
    {
        return TC_Multi_HashMap::RT_NO_DATA;
    }
    
    incHitCount();
    
    //只有Key
    if(it->isOnlyKey())
    {
        return TC_Multi_HashMap::RT_ONLY_KEY;
    }
    
    Block block(this, it->getAddr());
    block.setSyncTime(iSyncTime);
    
    return TC_Multi_HashMap::RT_OK;
}

void TC_Multi_HashMap::incMainKeyBlockCount(const string &mk, bool bInc)
{
    uint32_t index = mhashIndex(mk);

    // 找到真正的主key头
    if(itemMainKey(index)->_iMainKeyAddr != 0)
    {
        MainKey mainKey(this, itemMainKey(index)->_iMainKeyAddr);
        do
        {
            string sKey;
            mainKey.get(sKey);
            if(mk == sKey)
            {
                // 找到了，增加计数
                if(bInc)
                {
                    saveValue(&mainKey.getHeadPtr()->_iBlockCount, mainKey.getHeadPtr()->_iBlockCount + 1);
                    updateMaxMainKeyBlockCount(mainKey.getHeadPtr()->_iBlockCount + 1);
                }
                else
                {
                    saveValue(&mainKey.getHeadPtr()->_iBlockCount, mainKey.getHeadPtr()->_iBlockCount - 1);
                    updateMaxMainKeyBlockCount(mainKey.getHeadPtr()->_iBlockCount - 1);
                }
                break;
            }
        }while(mainKey.next());
    }
}

void TC_Multi_HashMap::updateMaxMainKeyBlockCount(size_t iCount)
{
    if(iCount > _pHead->_iMaxBlockCount)
    {
        saveValue(&_pHead->_iMaxBlockCount, iCount);
    }
}

int TC_Multi_HashMap::get(const string &mk, const string &uk, Value &v)
{
    TC_Multi_HashMap::FailureRecover recover(this);

    incGetCount();

    int ret             = RT_OK;

    uint32_t index      = hashIndex(mk, uk);
    lock_iterator it    = find(mk, uk, index, v, ret);

    if(ret != RT_OK && ret != RT_ONLY_KEY)
    {
        return ret;
    }

    if(it == end())
    {
        // 没有数据
        // 查询主key信息
        uint32_t mIndex = mhashIndex(mk);
        uint32_t iAddr = find(mk, mIndex, ret);
        if(ret != RT_OK)
        {
            // 这里有可能返回RT_ONLY_KEY
            return ret;
        }
        if(iAddr != 0)
        {
            MainKey mainKey(this, iAddr);
            if(mainKey.ISFULLDATA())
            {
                // 主key存在，由于cache中的数据必须与数据源(如数据库)保持一致
                // 说明数据源必定没有此记录，返回only key即可，可以使得调用者不必
                // 从数据源再取数据
                return RT_ONLY_KEY;
            }
            // 如果主key存在，但数据不全，则有可能会在数据库中有，应该返回RT_NO_DATA
        }
        return RT_NO_DATA;
    }

    incHitCount();

    // 只有Key
    if(it->isOnlyKey())
    {
        return RT_ONLY_KEY;
    }

    Block block(this, it->getAddr());
    // 如果只读, 则不刷新get链表
    if(!_pHead->_bReadOnly)
    {
        MainKey mainKey(this, block.getBlockHead()->_iMainKey);
        mainKey.refreshGetList();
    }
    return RT_OK;
}

int TC_Multi_HashMap::get(const string &mk, vector<Value> &vs)
{
    TC_Multi_HashMap::FailureRecover recover(this);

    incGetCount();

    int ret = TC_Multi_HashMap::RT_OK;
    
    uint32_t index = mhashIndex(mk);
    uint32_t iMainKeyAddr = find(mk, index, ret);
    if(ret != RT_OK)
    {
        return ret;
    }
    if(iMainKeyAddr == 0)
    {
        // 主key不存在
        return RT_NO_DATA;
    }

    incHitCount();

    MainKey mainKey(this, iMainKeyAddr);
    if(mainKey.getHeadPtr()->_iAddr == 0)
    {
        return RT_ONLY_KEY;
    }
    uint32_t iAddr = mainKey.getHeadPtr()->_iAddr;
    while(iAddr != 0)
    {
        Block block(this, iAddr);
        Value v;
        v._mkey = mk;
        ret = block.getBlockData(v._data);
        if(ret != RT_OK && ret != RT_ONLY_KEY)
        {
            return ret;
        }
        if(ret == RT_OK)
        {
            // 仅取非only key的数据
            vs.push_back(v);
        }
        iAddr = block.getBlockHead()->_iMKBlockNext;
    }

    if(!mainKey.ISFULLDATA())
    {
        return RT_PART_DATA;
    }

    return RT_OK;
}

int TC_Multi_HashMap::get(uint32_t &mh, map<string, vector<Value> > &vs)
{
    int ret = TC_Multi_HashMap::RT_OK;
    
    uint32_t index = mh % _hashMainKey.size();
    uint32_t iMainKeyAddr = itemMainKey(index)->_iMainKeyAddr;
    if(iMainKeyAddr == 0)
    {
        return RT_OK;
    }
    
    MainKey mainKey(this, iMainKeyAddr);
    do
    {
        if(mainKey.getHeadPtr()->_iAddr != 0)
        {
            lock_iterator it(this, mainKey.getHeadPtr()->_iAddr, lock_iterator::IT_MKEY, lock_iterator::IT_NEXT);
            while(it != end())
            {
                Value v;
                ret = it->get(v);
                if(ret != RT_OK && ret != RT_ONLY_KEY)
                {
                    return ret;
                }
                if(ret == RT_OK)
                {
                    // 仅取非only key的数据
                    vs[v._mkey].push_back(v);
                }
                it ++;
            }
        }
    }while(mainKey.next());
    
    return RT_OK;
}

int TC_Multi_HashMap::set(const string &mk, const string &uk, const string &v, 
                          uint8_t iVersion, bool bDirty, DATATYPE eType, bool bHead, vector<Value> &vtData)
{
    TC_Multi_HashMap::FailureRecover recover(this);

    incGetCount();

    if(_pHead->_bReadOnly) return RT_READONLY;

    int ret             = TC_Multi_HashMap::RT_OK;
    uint32_t index      = hashIndex(mk, uk);
    lock_iterator it    = find(mk, uk, index, ret);
    bool bNewBlock = false;

    if(ret != TC_Multi_HashMap::RT_OK)
    {
        return ret;
    }

    incHitCount();

    if(it == end())
    {
        // 数据尚不存在

        // 查找是否已经存在于主key链
        uint32_t mIndex = mhashIndex(mk);        // 主key索引
        uint32_t iMainKeyAddr = find(mk, mIndex, ret);
        if(ret != RT_OK && ret != RT_ONLY_KEY)
        {
            return ret;
        }
        if(iMainKeyAddr == 0)
        {
            // 主key头尚不存在，新建一个
            iMainKeyAddr = _pDataAllocator->allocateMainKeyHead(mIndex, vtData);
            if(iMainKeyAddr == 0)
            {
                return TC_Multi_HashMap::RT_NO_MEMORY;
            }
            // 将主key设置到主key头中
            MainKey mainKey(this, iMainKeyAddr);
            ret = mainKey.set(mk.c_str(), mk.length(), vtData);
            if(ret != TC_Multi_HashMap::RT_OK)
            {
                return ret;
            }
        }

        TC_PackIn pi;
        pi << uk;
        pi << v;
        uint32_t iAllocSize = (uint32_t)pi.length();

        // 先分配Blcok空间, 并获得淘汰的数据
        uint32_t iAddr = _pDataAllocator->allocateMemBlock(iMainKeyAddr, index, bHead, iAllocSize, vtData);
        if(iAddr == 0)
        {
            return TC_Multi_HashMap::RT_NO_MEMORY;
        }

        it = HashMapLockIterator(this, iAddr, HashMapLockIterator::IT_BLOCK, HashMapLockIterator::IT_NEXT);
        bNewBlock = true;
    }

    ret = it->set(mk, uk, v, iVersion, vtData);
    if(ret != TC_Multi_HashMap::RT_OK)
    {
        // set数据失败，可能的情况是空间不够了
        if(bNewBlock)
        {
            // 如果是新set的数据，此时要注意删除前面分配并挂接的block头
            // 否则这个block将永远无法访问，也不能删除，因为block里是一个空的block
            Block block(this, it->getAddr());
            block.erase();
        }
        return ret;
    }

    Block block(this, it->getAddr());
    if(bNewBlock)
    {
        block.setSyncTime(time(NULL));
    }
    block.setDirty(bDirty);

    if(eType != AUTO_DATA)
    {
        MainKey mainKey(this, block.getBlockHead()->_iMainKey);
        mainKey.SETFULLDATA(eType == FULL_DATA);
    }

    block.refreshSetList();

    return TC_Multi_HashMap::RT_OK;
}

int TC_Multi_HashMap::set(const string &mk, const string &uk, DATATYPE eType, bool bHead, vector<Value> &vtData)
{
    TC_Multi_HashMap::FailureRecover recover(this);

    incGetCount();

    if(_pHead->_bReadOnly) return RT_READONLY;

    int ret             = TC_Multi_HashMap::RT_OK;
    uint32_t index        = hashIndex(mk, uk);
    lock_iterator it    = find(mk, uk, index, ret);
    bool bNewBlock = false;

    if(ret != TC_Multi_HashMap::RT_OK)
    {
        return ret;
    }

    incHitCount();

    if(it == end())
    {
        // 查找是否已经存在于主key链
        uint32_t mIndex = mhashIndex(mk);        // 主key索引
        uint32_t iMainKeyAddr = find(mk, mIndex, ret);
        if(ret != RT_OK && ret != RT_ONLY_KEY)
        {
            return ret;
        }
        if(iMainKeyAddr == 0)
        {
            // 主key头尚不存在，新建一个
            iMainKeyAddr = _pDataAllocator->allocateMainKeyHead(mIndex, vtData);
            if(iMainKeyAddr == 0)
            {
                return TC_Multi_HashMap::RT_NO_MEMORY;
            }
            // 将主key设置到主key头中
            MainKey mainKey(this, iMainKeyAddr);
            ret = mainKey.set(mk.c_str(), mk.length(), vtData);
            if(ret != TC_Multi_HashMap::RT_OK)
            {
                return ret;
            }
        }

        TC_PackIn pi;
        pi << uk;
        uint32_t iAllocSize = (uint32_t)pi.length();

        //先分配空间, 并获得淘汰的数据
        uint32_t iAddr = _pDataAllocator->allocateMemBlock(iMainKeyAddr, index, bHead, iAllocSize, vtData);
        if(iAddr == 0)
        {
            return TC_Multi_HashMap::RT_NO_MEMORY;
        }

        it = HashMapLockIterator(this, iAddr, HashMapLockIterator::IT_BLOCK, HashMapLockIterator::IT_NEXT);
        bNewBlock = true;
    }

    ret = it->set(mk, uk, vtData);
    if(ret != TC_Multi_HashMap::RT_OK)
    {
        // set数据失败，可能的情况是空间不够了
        if(bNewBlock)
        {
            // 如果是新set的数据，此时要注意删除前面分配并挂接的block头
            // 否则这个block将永远无法访问，也不能删除，因为block里是一个空的block
            Block block(this, it->getAddr());
            block.erase();
        }
        return ret;
    }

    Block block(this, it->getAddr());
    if(bNewBlock)
    {
        block.setSyncTime(time(NULL));
    }

    if(eType != AUTO_DATA)
    {
        MainKey mainKey(this, block.getBlockHead()->_iMainKey);
        mainKey.SETFULLDATA(eType == FULL_DATA);
    }

    block.refreshSetList();

    return TC_Multi_HashMap::RT_OK;
}

int TC_Multi_HashMap::set(const string &mk, vector<Value> &vtData)
{
    TC_Multi_HashMap::FailureRecover recover(this);

    incGetCount();
    
    if(_pHead->_bReadOnly) return RT_READONLY;
    
    int ret             = TC_Multi_HashMap::RT_OK;

    // 查找是否已经存在该主key
    uint32_t mIndex = mhashIndex(mk);        // 主key索引
    uint32_t iMainKeyAddr = find(mk, mIndex, ret);
    if(ret != RT_OK && ret != RT_ONLY_KEY)
    {
        return ret;
    }

    incHitCount();

    if(iMainKeyAddr == 0)
    {
        // 主key头尚不存在，新建一个
        iMainKeyAddr = _pDataAllocator->allocateMainKeyHead(mIndex, vtData);
        if(iMainKeyAddr == 0)
        {
            return TC_Multi_HashMap::RT_NO_MEMORY;
        }
    }

    MainKey mainKey(this, iMainKeyAddr);

    while(mainKey.getHeadPtr()->_iAddr != 0)
    {
        // 下面还有数据，需要清理这些数据
        Block block(this, mainKey.getHeadPtr()->_iAddr);
        Value value;
        value._mkey = mk;
        int ret = block.getBlockData(value._data);
        if(ret == TC_Multi_HashMap::RT_OK)
        {
            vtData.push_back(value);
        }
        block.erase();
    }
    
    // 将主key设置到主key头中
    ret = mainKey.set(mk.c_str(), mk.length(), vtData);
    if(ret != TC_Multi_HashMap::RT_OK)
    {
        return ret;
    }
    mainKey.refreshGetList();

    return TC_Multi_HashMap::RT_OK;
}

int TC_Multi_HashMap::set(const vector<Value> &vtSet, DATATYPE eType, bool bHead, bool bForce, vector<Value> &vtErased)
{
    // 这里不需要加恢复代码
    //TC_Multi_HashMap::FailureRecover recover(this);

    int ret = RT_OK;

    for(size_t i = 0; i < vtSet.size(); i ++)
    {
        if(bForce || checkMainKey(vtSet[i]._mkey) == RT_NO_DATA)
        {
            // 强制更新或主key下没有数据
            if(vtSet[i]._data._key.empty())
            {
                // 没有联合key，当作主key的only key设置
                ret = set(vtSet[i]._mkey, vtErased);
            }
            else if(vtSet[i]._data._value.empty())
            {
                // 没有value，当作联合主键的only key设置
                ret = set(vtSet[i]._mkey, vtSet[i]._data._key, eType, bHead, vtErased);
            }
            else
            {
                ret = set(vtSet[i]._mkey, vtSet[i]._data._key, vtSet[i]._data._value, 
                    vtSet[i]._data._iVersion, vtSet[i]._data._dirty, eType, bHead, vtErased);
            }
            if(ret != RT_OK)
            {
                return ret;
            }
        }
    }

    return RT_OK;
}

int TC_Multi_HashMap::del(const string &mk, const string &uk, Value &data)
{
    TC_Multi_HashMap::FailureRecover recover(this);

    incGetCount();

    if(_pHead->_bReadOnly) return RT_READONLY;

    int    ret      = RT_OK;
    uint32_t index    = hashIndex(mk, uk);
    lock_iterator it     = find(mk, uk, index, data, ret);
    if(ret != TC_Multi_HashMap::RT_OK && ret != TC_Multi_HashMap::RT_ONLY_KEY)
    {
        return ret;
    }

    if(it == end())
    {
        return TC_Multi_HashMap::RT_NO_DATA;
    }

    incHitCount();

    Block block(this, it->getAddr());
    block.erase();

    return ret;
}

int TC_Multi_HashMap::del(const string &mk, vector<Value> &data)
{
    if(_pHead->_bReadOnly) return RT_READONLY;

    TC_Multi_HashMap::FailureRecover recover(this);

    incGetCount();

    uint32_t iIndex = mhashIndex(mk);
    if(itemMainKey(iIndex)->_iMainKeyAddr != 0)
    {
        incHitCount();

        MainKey mainKey(this, itemMainKey(iIndex)->_iMainKeyAddr);
        do
        {
            string sKey;
            mainKey.get(sKey);
            if(mk == sKey)
            {
                // 找到主key头了
                return mainKey.erase(data);
            }
        }while(mainKey.next());
    }

    return TC_Multi_HashMap::RT_NO_DATA;         
}

int TC_Multi_HashMap::erase(int ratio, vector<Value> &vtData, bool bCheckDirty)
{
    if(_pHead->_bReadOnly) return RT_READONLY;

    TC_Multi_HashMap::FailureRecover recover(this);

    if(ratio <= 0)   ratio = 1;
    if(ratio >= 100) ratio = 100;

    uint32_t iAddr    = _pHead->_iGetTail;
    //到链表头部
    if(iAddr == 0)
    {
        return RT_OK;
    }

    //删除到指定比率了
    if((_pHead->_iUsedChunk * 100. / allBlockChunkCount()) < ratio)
    {
        return RT_OK;
    }

    // 删除是针对主key的
    MainKey mainKey(this, iAddr);
    if(bCheckDirty)
    {
        // 检查脏数据，脏数据不淘汰
        // 只要主key下有一条脏数据就不淘汰
        lock_iterator it(this, mainKey.getHeadPtr()->_iAddr, lock_iterator::IT_MKEY, lock_iterator::IT_NEXT);
        while(it != end())
        {
            if(it->isDirty())
            {
                if(_pHead->_iDirtyTail == 0)
                {
                    _pHead->_iDirtyTail = mainKey.getHeadPtr()->_iAddr;
                }
                return RT_OK;
            }
            it ++;
        }
    }

    // 淘汰主key下的所有数据
    mainKey.erase(vtData);

    return RT_ERASE_OK;
}

void TC_Multi_HashMap::sync()
{
    TC_Multi_HashMap::FailureRecover recover(this);
    
    _pHead->_iSyncTail = _pHead->_iDirtyTail;
}

int TC_Multi_HashMap::sync(time_t iNowTime, Value &data)
{
    TC_Multi_HashMap::FailureRecover recover(this);

    uint32_t iAddr    = _pHead->_iSyncTail;

    //到链表头部了, 返回RT_OK
    if(iAddr == 0)
    {
        return RT_OK;
    }

    Block block(this, iAddr);

    _pHead->_iSyncTail = block.getBlockHead()->_iSetPrev;

    //当前数据是干净数据
    if( !block.isDirty())
    {
        if(_pHead->_iDirtyTail == iAddr)
        {
            _pHead->_iDirtyTail = block.getBlockHead()->_iSetPrev;
        }
        return RT_NONEED_SYNC;
    }

    // 取出主key
    MainKey mainKey(this, block.getBlockHead()->_iMainKey);
    mainKey.get(data._mkey);

    int ret = block.getBlockData(data._data);
    if(ret != TC_Multi_HashMap::RT_OK)
    {
        //没有获取完整的记录
        if(_pHead->_iDirtyTail == iAddr)
        {
            _pHead->_iDirtyTail = block.getBlockHead()->_iSetPrev;
        }
        return ret;
    }

    //脏数据且超过_pHead->_iSyncTime没有回写, 需要回写
    if(_pHead->_iSyncTime + data._data._synct < iNowTime && block.isDirty())
    {
        block.setDirty(false);
        block.setSyncTime(iNowTime);

        if(_pHead->_iDirtyTail == iAddr)
        {
            _pHead->_iDirtyTail = block.getBlockHead()->_iSetPrev;
        }

        return RT_NEED_SYNC;
    }

    //脏数据, 但是不需要回写, 脏链表不往前推
    return RT_NONEED_SYNC;
}

void TC_Multi_HashMap::backup(bool bForceFromBegin)
{
    TC_Multi_HashMap::FailureRecover recover(this);

    if(bForceFromBegin || _pHead->_iBackupTail == 0)
    {
        //移动备份指针到Get链尾部, 准备开始备份数据
        _pHead->_iBackupTail = _pHead->_iGetTail;
    }
}

int TC_Multi_HashMap::backup(vector<Value> &vtData)
{
    TC_Multi_HashMap::FailureRecover recover(this);

    uint32_t iAddr    = _pHead->_iBackupTail;

    //到链表头部了, 返回RT_OK
    if(iAddr == 0)
    {
        return RT_OK;
    }

    // 取出主key
    MainKey mainKey(this, iAddr);
    string mk;
    mainKey.get(mk);

    // 一次备份整个主key
    int ret = RT_OK;
    lock_iterator it(this, mainKey.getHeadPtr()->_iAddr, lock_iterator::IT_MKEY, lock_iterator::IT_NEXT);
    while(it != end())
    {
        Block block(this, it->_iAddr);
        Value value;
        value._mkey = mk;
        ret = block.getBlockData(value._data);
        if(ret != RT_OK)
        {
            break;
        }
        vtData.push_back(value);
        
        it++;
    }

    //迁移一次
    _pHead->_iBackupTail = mainKey.getHeadPtr()->_iGetPrev;

    if(ret == RT_OK)
    {
        return RT_NEED_BACKUP;
    }

    return ret;
}

TC_Multi_HashMap::lock_iterator TC_Multi_HashMap::begin()
{
    TC_Multi_HashMap::FailureRecover recover(this);

    for(size_t i = 0; i < _hash.size(); i++)
    {
        tagHashItem &hashItem = _hash[i];
        if(hashItem._iBlockAddr != 0)
        {
            return lock_iterator(this, hashItem._iBlockAddr, lock_iterator::IT_BLOCK, lock_iterator::IT_NEXT);
        }
    }

    return end();
}

TC_Multi_HashMap::lock_iterator TC_Multi_HashMap::rbegin()
{
    TC_Multi_HashMap::FailureRecover recover(this);

    for(size_t i = _hash.size(); i > 0; i--)
    {
        tagHashItem &hashItem = _hash[i-1];
        if(hashItem._iBlockAddr != 0)
        {
            Block block(this, hashItem._iBlockAddr);
            return lock_iterator(this, block.getLastBlockHead(true), lock_iterator::IT_BLOCK, lock_iterator::IT_PREV);
        }
    }

    return end();
}

TC_Multi_HashMap::lock_iterator TC_Multi_HashMap::beginSetTime()
{
    TC_Multi_HashMap::FailureRecover recover(this);
    return lock_iterator(this, _pHead->_iSetHead, lock_iterator::IT_SET, lock_iterator::IT_NEXT);
}

TC_Multi_HashMap::lock_iterator TC_Multi_HashMap::rbeginSetTime()
{
    TC_Multi_HashMap::FailureRecover recover(this);
    return lock_iterator(this, _pHead->_iSetTail, lock_iterator::IT_SET, lock_iterator::IT_PREV);
}

TC_Multi_HashMap::lock_iterator TC_Multi_HashMap::beginGetTime()
{
    TC_Multi_HashMap::FailureRecover recover(this);
    if(_pHead->_iGetHead != 0)
    {
        MainKey mainKey(this, _pHead->_iGetHead);
        return lock_iterator(this, mainKey.getHeadPtr()->_iAddr, lock_iterator::IT_GET, lock_iterator::IT_NEXT);
    }
    else
    {
        return lock_iterator(this, 0, lock_iterator::IT_GET, lock_iterator::IT_NEXT);
    }
}

TC_Multi_HashMap::lock_iterator TC_Multi_HashMap::rbeginGetTime()
{
    TC_Multi_HashMap::FailureRecover recover(this);
    if(_pHead->_iGetTail != 0)
    {
        MainKey mainKey(this, _pHead->_iGetTail);
        // 找到主key链上的最后一个数据
        uint32_t iAddr = mainKey.getHeadPtr()->_iAddr;
        if(iAddr)
        {
            Block block(this, iAddr);
            while(block.getBlockHead()->_iMKBlockNext)
            {
                iAddr = block.getBlockHead()->_iMKBlockNext;
                block = Block(this, iAddr);
            }
        }
        return lock_iterator(this, iAddr, lock_iterator::IT_GET, lock_iterator::IT_PREV);
    }
    else
    {
        return lock_iterator(this, 0, lock_iterator::IT_GET, lock_iterator::IT_PREV);
    }
}

TC_Multi_HashMap::lock_iterator TC_Multi_HashMap::beginDirty()
{
    TC_Multi_HashMap::FailureRecover recover(this);
    return lock_iterator(this, _pHead->_iDirtyTail, lock_iterator::IT_SET, lock_iterator::IT_PREV);
}

TC_Multi_HashMap::hash_iterator TC_Multi_HashMap::hashBegin()
{
    TC_Multi_HashMap::FailureRecover recover(this);
    return hash_iterator(this, 0);
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////

string TC_Multi_HashMap::desc()
{
    ostringstream s;
    {
        s << "[Version          = "   << (int)_pHead->_cMaxVersion << "." << (int)_pHead->_cMinVersion << "]" << endl;
        s << "[ReadOnly         = "   << _pHead->_bReadOnly    << "]" << endl;
        s << "[AutoErase        = "   << _pHead->_bAutoErase   << "]" << endl;
        s << "[MemSize          = "   << _pHead->_iMemSize          << "]" << endl;
        s << "[Capacity         = "   << _pDataAllocator->getCapacity()  << "]" << endl;
        s << "[SingleBlockCount = "   << TC_Common::tostr(singleBlockChunkCount())         << "]" << endl;
        s << "[AllBlockChunk    = "   << allBlockChunkCount()       << "]" << endl;
        s << "[UsedChunk        = "   << _pHead->_iUsedChunk        << "]" << endl;
        s << "[FreeChunk        = "   << allBlockChunkCount() - _pHead->_iUsedChunk        << "]" << endl;
        s << "[MinDataSize      = "   << _pHead->_iMinDataSize      << "]" << endl;
        s << "[MaxDataSize      = "   << _pHead->_iMaxDataSize      << "]" << endl;
        s << "[HashCount        = "   << _hash.size()               << "]" << endl;
        s << "[MainKeyHashCount = "   << _hashMainKey.size()        << "]" << endl;
        s << "[HashRatio        = "   << _pHead->_fHashRatio            << "]" << endl;
        s << "[MainKeyRatio     = "   << _pHead->_fMainKeyRatio         << "]" << endl;
        s << "[ElementCount     = "   << _pHead->_iElementCount     << "]" << endl;
        s << "[SetHead          = "   << _pHead->_iSetHead       << "]" << endl;
        s << "[SetTail          = "   << _pHead->_iSetTail       << "]" << endl;
        s << "[GetHead          = "   << _pHead->_iGetHead       << "]" << endl;
        s << "[GetTail          = "   << _pHead->_iGetTail       << "]" << endl;
        s << "[DirtyTail        = "   << _pHead->_iDirtyTail        << "]" << endl;
        s << "[SyncTail         = "   << _pHead->_iSyncTail        << "]" << endl;
        s << "[SyncTime         = "   << _pHead->_iSyncTime        << "]" << endl;
        s << "[BackupTail       = "   << _pHead->_iBackupTail      << "]" << endl;
        s << "[DirtyCount       = "   << _pHead->_iDirtyCount       << "]" << endl;
        s << "[GetCount         = "   << _pHead->_iGetCount         << "]" << endl;
        s << "[HitCount         = "   << _pHead->_iHitCount         << "]" << endl;
        s << "[HitRatio         = "   << (_pHead->_iGetCount == 0 ? 0 :_pHead->_iHitCount * 100 / _pHead->_iGetCount) << "]" << endl;
        s << "[OnlyKeyCount     = "      << _pHead->_iOnlyKeyCount        << "]" << endl;
        s << "[MKOnlyKeyCount   = "      << _pHead->_iMKOnlyKeyCount    << "]" << endl;
        s << "[MaxMKBlockCount  = "      << _pHead->_iMaxBlockCount    << "]" << endl;
        s << "[ModifyStatus     = "   << (int)_pstModifyHead->_cModifyStatus     << "]" << endl;
        s << "[ModifyIndex      = "   << _pstModifyHead->_iNowIndex << "]" << endl;
    }

    uint32_t iMaxHash;
    uint32_t iMinHash;
    float fAvgHash;

    analyseHash(iMaxHash, iMinHash, fAvgHash);
    {
        s << "[MaxHash          = "   << iMaxHash      << "]" << endl;
        s << "[MinHash          = "   << iMinHash     << "]" << endl;
        s << "[AvgHash          = "   << fAvgHash     << "]" << endl;
    }

    analyseHashM(iMaxHash, iMinHash, fAvgHash);
    {
        s << "[MaxMainkeyHash   = "   << iMaxHash      << "]" << endl;
        s << "[MinMainKeyHash   = "   << iMinHash     << "]" << endl;
        s << "[AvgMainKeyHash   = "   << fAvgHash     << "]" << endl;
    }

    vector<TC_MemChunk::tagChunkHead> vChunkHead = _pDataAllocator->getBlockDetail();

    s << "*************************************************************************" << endl;
    s << "[DiffBlockCount   = "   << vChunkHead.size()  << "]" << endl;
    for(size_t i = 0; i < vChunkHead.size(); i++)
    {
        s << "[BlockSize        = "   << vChunkHead[i]._iBlockSize      << "] ";
        s << "[BlockCount       = "   << vChunkHead[i]._iBlockCount     << "] ";
        s << "[BlockAvailable   = "   << vChunkHead[i]._blockAvailable  << "]" << endl;
    }

    return s.str();
}

size_t TC_Multi_HashMap::eraseExcept(uint32_t iNowAddr, vector<Value> &vtData)
{
    //不能被淘汰
    if(!_pHead->_bAutoErase) return 0;

    size_t n = _pHead->_iEraseCount;
    if(n == 0) n = 10;
    size_t d = n;

    while (d != 0)
    {
        uint32_t iAddr;

        //判断按照哪种方式淘汰
        if(_pHead->_cEraseMode == TC_Multi_HashMap::ERASEBYSET)
        {
            // 按set链淘汰
            iAddr = _pHead->_iSetTail;
            if (iAddr == 0)
            {
                break;
            }
            // set链是block链，换算成主key头的地址
            Block block(this, iAddr);
            iAddr = block.getBlockHead()->_iMainKey;
        }
        else
        {
            // 按get链淘汰
            iAddr = _pHead->_iGetTail;
            if (iAddr == 0)
            {
                break;
            }
        }
        
        // 不管是按get链淘汰还是按set链淘汰，都是要淘汰主key下所有数据
        MainKey mainKey(this, iAddr);
        if(iNowAddr == iAddr)
        {
            // 当前主key链中有正在分配的block，跳过
            iAddr = mainKey.getHeadPtr()->_iGetPrev;
        }
        if(iAddr == 0)
        {
            break;
        }

        uint32_t iBlockCount = mainKey.getHeadPtr()->_iBlockCount;
        if(d >= iBlockCount)
        {
            // 淘汰主key链下的所有数据
            int ret = mainKey.erase(vtData);
            if(ret == RT_OK)
            {
                d -= iBlockCount;
            }
        }
        else
        {
            if(d == n)
            {
                // 设置的要删除的数量太小，没有满足条件的主key，直接删除
                int ret = mainKey.erase(vtData);
                if(ret == RT_OK)
                {
                    n = d + iBlockCount;    // 使返回正确的数据量
                }
            }
            break;
        }
    }

    return n-d;
}

uint32_t TC_Multi_HashMap::hashIndex(const string &mk, const string &uk)
{
    // mk是主key，uk是除主key外的辅key，二者加起来作为联合主键
    return hashIndex(mk + uk);
}

uint32_t TC_Multi_HashMap::hashIndex(const string& k)
{
    return _hashf(k) % _hash.size();
}

uint32_t TC_Multi_HashMap::mhashIndex(const string &mk)
{
    if(_mhashf)
    {
        return _mhashf(mk) % _hashMainKey.size();
    }
    else
    {
        // 如果没有单独指定主key hash函数，则使用联合主键的hash函数
        return _hashf(mk) % _hashMainKey.size();
    }
}

TC_Multi_HashMap::lock_iterator TC_Multi_HashMap::find(const string &mk, const string &uk)
{
    TC_Multi_HashMap::FailureRecover recover(this);

    incGetCount();

    uint32_t index = hashIndex(mk, uk);
    int ret = TC_Multi_HashMap::RT_OK;
    
    if(item(index)->_iBlockAddr == 0)
    {
        return end();
    }
    
    Block mb(this, item(index)->_iBlockAddr);
    while(true)
    {
        HashMapLockItem mcmdi(this, mb.getHead());
        if(mcmdi.equal(mk, uk, ret))
        {
            // 找到了，不仅索引相同，key也相同
            incHitCount();
            return lock_iterator(this, mb.getHead(), lock_iterator::IT_BLOCK, lock_iterator::IT_NEXT);
        }
        
        if (!mb.nextBlock())
        {
            return end();
        }
    }
    
    return end();
}

TC_Multi_HashMap::lock_iterator TC_Multi_HashMap::find(const string &mk, const string &uk, uint32_t index, Value &v, int &ret)
{
    ret = TC_Multi_HashMap::RT_OK;

    if(item(index)->_iBlockAddr == 0)
    {
        return end();
    }

    Block mb(this, item(index)->_iBlockAddr);
    while(true)
    {
        HashMapLockItem mcmdi(this, mb.getHead());
        if(mcmdi.equal(mk, uk, v, ret))
        {
            // 找到了，不仅索引相同，key也相同
            return lock_iterator(this, mb.getHead(), lock_iterator::IT_BLOCK, lock_iterator::IT_NEXT);
        }

        if (!mb.nextBlock())
        {
            return end();
        }
    }

    return end();
}

TC_Multi_HashMap::lock_iterator TC_Multi_HashMap::find(const string &mk, const string &uk, uint32_t index, int &ret)
{
    ret = TC_Multi_HashMap::RT_OK;

    if(item(index)->_iBlockAddr == 0)
    {
        return end();
    }

    Block mb(this, item(index)->_iBlockAddr);
    while(true)
    {
        HashMapLockItem mcmdi(this, mb.getHead());
        if(mcmdi.equal(mk, uk, ret))
        {
            // 找到了，不仅索引相同，key也相同
            return lock_iterator(this, mb.getHead(), lock_iterator::IT_BLOCK, lock_iterator::IT_NEXT);
        }

        if (!mb.nextBlock())
        {
            return end();
        }
    }

    return end();
}

uint32_t TC_Multi_HashMap::find(const string &mk, uint32_t index, int &ret)
{
    ret = TC_Multi_HashMap::RT_OK;

    if(itemMainKey(index)->_iMainKeyAddr == 0)
    {
        return 0;
    }

    MainKey mainKey(this, itemMainKey(index)->_iMainKeyAddr);
    do 
    {
        string s;
        ret = mainKey.get(s);
        if(ret != RT_OK)
        {
            return 0;
        }
        if(s == mk)
        {
            // 找到了
            if(mainKey.getHeadPtr()->_iAddr == 0)
            {
                ret = RT_ONLY_KEY;
            }
            return mainKey.getHead();
        }

    } while (mainKey.next());

    return 0;
}

size_t TC_Multi_HashMap::count(const string &mk)
{
    TC_Multi_HashMap::FailureRecover recover(this);

    incGetCount();

    uint32_t iIndex = mhashIndex(mk);
    if(itemMainKey(iIndex)->_iMainKeyAddr != 0)
    {
        MainKey mainKey(this, itemMainKey(iIndex)->_iMainKeyAddr);
        do
        {
            string sKey;
            mainKey.get(sKey);
            if(mk == sKey)
            {
                // 找到对应的主key了
                incHitCount();
                return mainKey.getHeadPtr()->_iBlockCount;
            }
        }while(mainKey.next());
    }
    return 0;
}

TC_Multi_HashMap::lock_iterator TC_Multi_HashMap::find(const string &mk)
{
    TC_Multi_HashMap::FailureRecover recover(this);

    incGetCount();

    uint32_t iIndex = mhashIndex(mk);
    if(itemMainKey(iIndex)->_iMainKeyAddr != 0)
    {
        MainKey mainKey(this, itemMainKey(iIndex)->_iMainKeyAddr);
        do
        {
            string sKey;
            mainKey.get(sKey);
            if(mk == sKey)
            {
                // 找到对应的主key了
                incHitCount();
                if(mainKey.getHeadPtr()->_iAddr != 0)
                {
                    // 主key下面有数据
                    return lock_iterator(this, mainKey.getHeadPtr()->_iAddr, lock_iterator::IT_MKEY, lock_iterator::IT_NEXT);
                }
                break;
            }
        }while(mainKey.next());
    }
    return end();
}

void TC_Multi_HashMap::analyseHash(uint32_t &iMaxHash, uint32_t &iMinHash, float &fAvgHash)
{
    iMaxHash = 0;
    iMinHash = (uint32_t)-1;

    fAvgHash = 0;

    uint32_t n = 0;
    for(uint32_t i = 0; i < _hash.size(); i++)
    {
        iMaxHash = max(_hash[i]._iListCount, iMaxHash);
        iMinHash = min(_hash[i]._iListCount, iMinHash);
        //平均值只统计非0的
        if(_hash[i]._iListCount != 0)
        {
            n++;
            fAvgHash  += _hash[i]._iListCount;
        }
    }

    if(n != 0)
    {
        fAvgHash = fAvgHash / n;
    }
}

void TC_Multi_HashMap::analyseHashM(uint32_t &iMaxHash, uint32_t &iMinHash, float &fAvgHash)
{
    iMaxHash = 0;
    iMinHash = (uint32_t)-1;
    
    fAvgHash = 0;
    
    uint32_t n = 0;
    for(uint32_t i = 0; i < _hashMainKey.size(); i++)
    {
        iMaxHash = max(_hashMainKey[i]._iListCount, iMaxHash);
        iMinHash = min(_hashMainKey[i]._iListCount, iMinHash);
        //平均值只统计非0的
        if(_hashMainKey[i]._iListCount != 0)
        {
            n++;
            fAvgHash  += _hashMainKey[i]._iListCount;
        }
    }
    
    if(n != 0)
    {
        fAvgHash = fAvgHash / n;
    }
}

void TC_Multi_HashMap::doRecover()
{
    //==1 copy过程中, 程序失败, 恢复原数据
    if(_pstModifyHead->_cModifyStatus == 1)
    {
        for(int i = _pstModifyHead->_iNowIndex-1; i >=0; i--)
        {
            if(_pstModifyHead->_stModifyData[i]._cBytes == sizeof(uint64_t))
            {
                *(uint64_t*)((char*)_pHead + _pstModifyHead->_stModifyData[i]._iModifyAddr) = _pstModifyHead->_stModifyData[i]._iModifyValue;
            }
            //#if __WORDSIZE == 64 || defined _WIN64
            else if(_pstModifyHead->_stModifyData[i]._cBytes == sizeof(uint32_t))
            {
                *(uint32_t*)((char*)_pHead + _pstModifyHead->_stModifyData[i]._iModifyAddr) = (uint32_t)_pstModifyHead->_stModifyData[i]._iModifyValue;
            }
            //#endif
            else if(_pstModifyHead->_stModifyData[i]._cBytes == sizeof(uint8_t))
            {
                *(uint8_t*)((char*)_pHead + _pstModifyHead->_stModifyData[i]._iModifyAddr) = (bool)_pstModifyHead->_stModifyData[i]._iModifyValue;
            }
            else
            {
                assert(true);
            }
        }
        _pstModifyHead->_iNowIndex        = 0;
        _pstModifyHead->_cModifyStatus    = 0;
    }
}

void TC_Multi_HashMap::doUpdate()
{
    //==2,已经修改成功, 清除
    if(_pstModifyHead->_cModifyStatus == 1)
    {
        _pstModifyHead->_iNowIndex        = 0;
        _pstModifyHead->_cModifyStatus    = 0;
    }
}

size_t TC_Multi_HashMap::getMinPrimeNumber(size_t n)
{
    while(true)
    {
        if(TC_Common::isPrimeNumber(n))
        {
            return n;
        }
        ++n;
    }
    return 3;
}

size_t TC_Multi_HashMap::checkBadBlock(uint32_t iHash, bool bRepair)
{
    size_t iCount = 0;
    if(iHash >= _hash.size())
    {
        return 0;
    }

    TC_Multi_HashMap::FailureRecover recover(this);

check:
    uint32_t iAddr = item(iHash)->_iBlockAddr;
    Block block(this, iAddr);
    while(block.getHead() != 0)
    {
        BlockData blkData;
        int ret = block.getBlockData(blkData);
        if(ret != RT_OK && ret != RT_ONLY_KEY)
        {
            iCount ++;
            if(bRepair)
            {
                // 删除这个block
                block.erase();
                goto check;
            }
        }
        if(!block.nextBlock())
        {
            break;
        }
    }

    return iCount;
}

}

