[common-sln]: base增加唯一标识管理类
来源:互联网 发布:泛雅网络教学平台答案 编辑:程序博客网 时间:2024/05/22 08:12
目的:创建某种场景下的唯一标识,就好像文件描述符那种
#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_BEGINtemplate <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_COMMONint 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);}