132 lines
3.7 KiB
C++
132 lines
3.7 KiB
C++
/*
|
||
* HotReserve.hpp
|
||
*
|
||
* Created on: 9 мар. 2020 г.
|
||
* Author: titov
|
||
*/
|
||
|
||
#ifndef UMLIBRARY_ALGORITHM_HOTRESERVE_HPP_
|
||
#define UMLIBRARY_ALGORITHM_HOTRESERVE_HPP_
|
||
|
||
namespace algorithm {
|
||
|
||
template< template<typename Type, typename> class ContainerType, typename Key, template<typename Item> class Locator >
|
||
class HotLinearReserve {
|
||
public:
|
||
typedef std::size_t Index;
|
||
|
||
struct Node {
|
||
Key key;
|
||
Index before;
|
||
Index after;
|
||
bool state;
|
||
|
||
Node(Key k, Index b, Index a, bool s) : key(k), before(b), after(a), state(s) {}
|
||
};
|
||
|
||
typedef Locator<Node> Allocator;
|
||
typedef ContainerType<Node, Allocator> Container;
|
||
|
||
HotLinearReserve(Key passive, Allocator alloca = Allocator() );
|
||
|
||
Index push(Key key);
|
||
|
||
bool activate(Index token);
|
||
void deactivate(Index token);
|
||
|
||
Key top() const;
|
||
|
||
private:
|
||
Container container;
|
||
Index active;
|
||
Index last_item;
|
||
|
||
void do_deactivate(Index index, const HotLinearReserve<ContainerType, Key, Locator>::Node & item);
|
||
void do_activate(Index index, HotLinearReserve<ContainerType, Key, Locator>::Node & item);
|
||
};
|
||
|
||
template< template<typename Type, typename> class ContainerType, typename Key, template<typename Item> class Locator >
|
||
HotLinearReserve<ContainerType, Key, Locator>::HotLinearReserve(Key passive, Allocator alloca) :
|
||
container(alloca), active(push(passive)), last_item(active) {}
|
||
|
||
template< template<typename Type, typename> class ContainerType, typename Key, template<typename Item> class Locator >
|
||
typename HotLinearReserve<ContainerType, Key, Locator>::Index HotLinearReserve<ContainerType, Key, Locator>::push(Key key) {
|
||
|
||
container.push_back( Node( key, 0, 0, false ) );
|
||
|
||
return container.size() - 1;
|
||
}
|
||
|
||
template< template<typename Type, typename> class ContainerType, typename Key, template<typename Item> class Locator >
|
||
bool HotLinearReserve<ContainerType, Key, Locator>::activate(Index index) {
|
||
|
||
Node & item = container.at(index);
|
||
|
||
if( not item.state) {
|
||
|
||
do_activate(index, item);
|
||
|
||
item.state = true;
|
||
}
|
||
|
||
return active == index;
|
||
}
|
||
|
||
template< template<typename Type, typename> class ContainerType, typename Key, template<typename Item> class Locator >
|
||
void HotLinearReserve<ContainerType, Key, Locator>::do_activate(
|
||
HotLinearReserve<ContainerType, Key, Locator>::Index index,
|
||
HotLinearReserve<ContainerType, Key, Locator>::Node & item ) {
|
||
|
||
item.after = 0;
|
||
item.before = last_item;
|
||
|
||
if( not active) {
|
||
active = last_item = index;
|
||
} else {
|
||
container[last_item].after = index;
|
||
last_item = index;
|
||
}
|
||
|
||
}
|
||
|
||
template< template<typename Type, typename> class ContainerType, typename Key, template<typename Item> class Locator >
|
||
void HotLinearReserve<ContainerType, Key, Locator>::deactivate(Index index) {
|
||
|
||
Node & item = container.at(index);
|
||
|
||
if( item.state ) {
|
||
|
||
do_deactivate(index, item);
|
||
|
||
item.state = false;
|
||
}
|
||
|
||
|
||
}
|
||
|
||
template< template<typename Type, typename> class ContainerType, typename Key, template<typename Item> class Locator >
|
||
void HotLinearReserve<ContainerType, Key, Locator>::do_deactivate(
|
||
HotLinearReserve<ContainerType, Key, Locator>::Index index,
|
||
const HotLinearReserve<ContainerType, Key, Locator>::Node & item ) {
|
||
|
||
if(active == index ) {
|
||
active = item.after;
|
||
} else {
|
||
container[item.before].after = item.after;
|
||
container[item.after].before = item.before;
|
||
}
|
||
}
|
||
|
||
template< template<typename Type, typename> class ContainerType, typename Key, template<typename Item> class Locator >
|
||
Key HotLinearReserve<ContainerType, Key, Locator>::top() const {
|
||
|
||
return container[active].key;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
#endif /* UMLIBRARY_ALGORITHM_HOTRESERVE_HPP_ */
|