[common-sln]: base增加唯一标识管理类

20 篇文章 0 订阅
7 篇文章 0 订阅

目的:创建某种场景下的唯一标识,就好像文件描述符那种
#ifndef COMMON_BASE_HANDLE_MANAGER_H
#define COMMON_BASE_HANDLE_MANAGER_H


#include <deque>
#include <algorithm>
#include <functional>

#include "base_common.h"
#include "base_uncopy.h"
#include "base_locker.h"
#include "base_guard.hpp"

NAMESPACE_COMMON_BEGIN

template <typename HandleType, typename LockerType = NullLocker>
class YRK_EXPORT_DLL HandleManager : public BaseUncopy
{
public:
    HandleManager(HandleType min, HandleType max);

public:
    bool acquire(HandleType & handle);
    bool release(HandleType handle);

private:
    const HandleType         m_min_handle;
    const HandleType         m_max_handle;
    HandleType               m_next_handle;
    std::deque<HandleType>   m_unused_handle;
    LockerType               m_locker;
};

template <typename HandleType, typename LockerType>
HandleManager<HandleType, LockerType>::HandleManager
(
    HandleType min, HandleType max
)
    : m_min_handle(min)
    , m_max_handle(max)
    , m_next_handle(min)
    , m_unused_handle()
    , m_locker()
{

}

template <typename HandleType, typename LockerType>
bool HandleManager<HandleType, LockerType>::acquire(HandleType & handle)
{
    BaseGuard<LockerType> guard(m_locker);

    if (!m_unused_handle.empty())
    {
        handle = m_unused_handle.back();
        m_unused_handle.pop_back();
        return(true);
    }

    if (m_next_handle >= m_max_handle)
    {
        return(false);
    }

    handle = m_next_handle++;

    return(true);
}

template <typename HandleType, typename LockerType>
bool HandleManager<HandleType, LockerType>::release(HandleType handle)
{
    BaseGuard<LockerType> guard(m_locker);

    if (handle <  m_min_handle || 
        handle >= m_next_handle)
    {
        return(false);
    }

    if (m_unused_handle.end() != 
        std::find(m_unused_handle.begin(), m_unused_handle.end(), handle))
    {
        return(false);
    }

    if (handle + 1 == m_next_handle)
    {
        m_next_handle = handle;
    }
    else
    {
        m_unused_handle.push_back(handle);
        std::sort(m_unused_handle.begin(), m_unused_handle.end(), 
                  std::greater<HandleType>());
    }

    typename std::deque<HandleType>::iterator iter = m_unused_handle.begin();
    while (m_unused_handle.end() != iter)
    {
        if (*iter + 1 == m_next_handle)
        {
            m_next_handle = *iter++;
        }
        else
        {
            break;
        }
    }
    m_unused_handle.erase(m_unused_handle.begin(), iter);

    return(true);
}

NAMESPACE_COMMON_END


#endif // COMMON_BASE_HANDLE_MANAGER_H

测试:
#include <cassert>
#include <iostream>

#include "base_handle_manager.hpp"

USING_NAMESPACE_COMMON

int main(int argc, char * argv[])
{
    int min = 0;
    int max = 20;
    HandleManager<int, NullLocker> manager(min, max);

    if (!manager.release(min))
    {
        std::cout << "as i known, release " << min << " failed" << std::endl;
    }
    else
    {
        assert(false);
    }

    int handle = 0;
    while (manager.acquire(handle))
    {
        std::cout << "acquire " << handle << std::endl;
    }

    for (int i = min; i < max; i += 2)
    {
        manager.release(i);
        std::cout << "release " << i << std::endl;
    }

    if (!manager.release(min))
    {
        std::cout << "as i known, release " << min << " failed" << std::endl;
    }
    else
    {
        assert(false);
    }

    if (manager.acquire(handle))
    {
        std::cout << "acquire " << handle << std::endl;
        manager.release(handle);
        std::cout << "release " << handle << std::endl;
    }

    for (int i = max - 1; i > min; i -= 2)
    {
        manager.release(i);
        std::cout << "release " << i << std::endl;
    }

    if (!manager.release(min))
    {
        std::cout << "as i known, release " << min << " failed" << std::endl;
    }
    else
    {
        assert(false);
    }

    if (manager.acquire(handle) && min == handle)
    {
        std::cout << "acquire " << handle << std::endl;
    }
    else
    {
        assert(false);
    }

    return(0);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值