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_ */
|