rldleblanc

Intrusive Test

Feb 11th, 2016
205
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.54 KB | None | 0 0
  1. // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
  2. // vim: ts=8 sw=2 smarttab
  3. #include "OpQueue.h"
  4.  
  5. #include <functional>
  6. #include <list>
  7. #include <iostream>
  8. #include <boost/intrusive/list.hpp>
  9. #include <boost/intrusive/avl_set.hpp>
  10.  
  11. namespace bi = boost::intrusive;
  12.  
  13. using namespace std;
  14.  
  15. template <typename T>
  16. class MapKey
  17. {
  18.   public:
  19.   bool operator()(const int i, const T &k) const
  20.   {
  21.     return i < k.key;
  22.   }
  23.   bool operator()(const T &k, const int i) const
  24.   {
  25.     return k.key < i;
  26.   }
  27. };
  28.  
  29. template <typename T, typename K>
  30. class WrrQueue :  public OpQueue <T, K>
  31. {
  32.   private:
  33.     class ListPair : public bi::list_base_hook<>
  34.     {
  35.       public:
  36.         unsigned cost;
  37.         T item;
  38.         ListPair(unsigned& c, T& i) :
  39.           cost(c),
  40.           item(i)
  41.           {}
  42.     };
  43.     class Klass : public bi::avl_set_base_hook<>
  44.     {
  45.       typedef bi::list<ListPair> ListPairs;
  46.       public:
  47.         K key;      // klass
  48.         ListPairs lp;
  49.         Klass(K& k) :
  50.           key(k)
  51.           {}
  52.     //friend bool operator< (const Klass &a, const Klass &b)
  53.     //  { return a.key < b.key; }
  54.     //friend bool operator> (const Klass &a, const Klass &b)
  55.     //  { return a.key > b.key; }
  56.     //friend bool operator== (const Klass &a, const Klass &b)
  57.     //  { return a.key == b.key; }
  58.     bool insert(unsigned& cost, T& item) {
  59.       lp.push_back(*new ListPair(cost, item));
  60.     }
  61.     bool empty() const {
  62.       return lp.empty();
  63.     }
  64.     unsigned filter_list_pairs(std::function<bool (T)>& f,
  65.       std::list<T>* out) {
  66.       unsigned ret = 0;
  67.       // intrusive containers can't erase with a reverse_iterator
  68.       // so we have to walk backwards on our own. Since there is
  69.       // no iterator before begin, we have to test at the end.
  70.       for (typename ListPairs::iterator i = --lp.end();; --i) {
  71.         std::cout << "testing: " << i->cost << ", " << i->item << std::endl;
  72.         if (f(i->item)) {
  73.           std::cout << "Deleting: " << std::endl;
  74.           if (out) {
  75.         out->push_front(i->item);
  76.           }
  77.           i = lp.erase(i);
  78.           ++ret;
  79.         }
  80.         if (i == lp.begin()) {
  81.           break;
  82.         }
  83.       }
  84.     }
  85.     void print() const {
  86.           typename ListPairs::const_iterator it(lp.begin()), ite(lp.end());
  87.           for (; it != ite; ++it) {
  88.             std::cout << "      L: " << it->cost << ", " << it->item << std::endl;
  89.           }
  90.         }
  91.     };
  92.     class SubQueue : public bi::avl_set_base_hook<>
  93.     {
  94.       typedef bi::avl_set<Klass> Klasses;
  95.       typedef typename Klasses::iterator Ki;
  96.       public:
  97.     unsigned key;   // priority
  98.     Klasses klasses;
  99.     Ki next;
  100.     SubQueue(unsigned& p) :
  101.       key(p),
  102.       next(klasses.begin())
  103.       {}
  104.       bool empty() const {
  105.     return klasses.empty();
  106.       }
  107.       bool insert(K& cl, unsigned& cost, T& item) {
  108.     typename Klasses::insert_commit_data insert_data;
  109.         std::pair<typename Klasses::iterator, bool> ret =
  110.       klasses.insert_check(cl, MapKey<Klass>(), insert_data);
  111.         if (ret.second) {
  112.           ret.first = klasses.insert_commit(*new Klass(cl), insert_data);
  113.         }
  114.         ret.first->insert(cost, item);
  115.       }
  116.       unsigned filter_list_pairs(std::function<bool (T)>& f,
  117.     std::list<T>* out) {
  118.     unsigned count = 0;
  119.     for (typename Klasses::iterator i = klasses.begin();
  120.       i != klasses.end();) {
  121.       cout << "going to test klass: " << i->key << std::endl;
  122.       count += i->filter_list_pairs(f, out);
  123.       if (i->empty()) {
  124.         // don't leak memory
  125.         Klass * k = &*i;
  126.         i = klasses.erase(i);
  127.         delete k;
  128.       } else {
  129.         ++i;
  130.       }
  131.     }
  132.     if (next == klasses.end()) {
  133.       next = klasses.begin();
  134.     }
  135.     return count;
  136.       }
  137.       void print() const {
  138.         typename Klasses::const_iterator it(klasses.begin()), ite(klasses.end());
  139.         for (; it != ite; ++it) {
  140.           std::cout << "   K: " << it->key << std::endl;
  141.           it->print();
  142.         }
  143.       }
  144.     };
  145.     class Queue {
  146.       typedef bi::avl_set<SubQueue> SubQueues;
  147.       SubQueues queues;
  148.       public:
  149.     Queue() {}
  150.     void insert(unsigned& p, K& cl, unsigned& cost, T& item) {
  151.       typename SubQueues::insert_commit_data insert_data;
  152.           std::pair<typename SubQueues::iterator, bool> ret =
  153.             queues.insert_check(p, MapKey<SubQueue>(), insert_data);
  154.           if (ret.second) {
  155.             ret.first = queues.insert_commit(*new SubQueue(p), insert_data);
  156.           }
  157.           ret.first->insert(cl, cost, item);   
  158.     }
  159.     void print() const {
  160.       typename SubQueues::const_iterator it(queues.begin()), ite(queues.end());
  161.           for (; it != ite; ++it) {
  162.             std::cout << "P: " << it->key << std::endl;
  163.             it->print();
  164.           }
  165.     }
  166.     void filter_list_pairs(std::function<bool (T)>& f, std::list<T>* out) {
  167.       for (typename SubQueues::iterator i = queues.begin(); i != queues.end();) {
  168.             i->filter_list_pairs(f, out);
  169.         if (i->empty()) {
  170.           // don't leak memeory
  171.           SubQueue * q = &*i;
  172.           i = queues.erase(i);
  173.           delete q;
  174.         } else {
  175.           ++i;
  176.         }
  177.           }
  178.     }
  179.     };
  180.  
  181.     void do_printme(T out)
  182.     {
  183.       cout << "WrrOp: " << out << "\n";
  184.     }
  185.  
  186.     Queue normal;
  187.   public:
  188.     void whoami() final
  189.     {
  190.       cout << "WrrOp\n";
  191.     }
  192.     void printme(T out) final {
  193.       do_printme(out);
  194.     }
  195.     WrrQueue() :
  196.       normal()
  197.       {}
  198.     void remove_by_filter(std::function<bool (T)> f, std::list<T>* removed = 0) {
  199.       normal.filter_list_pairs(f, removed);
  200.     }
  201.     void enqueue(unsigned p, K cl, unsigned cost, T item) {
  202.       normal.insert(p, cl, cost, item);
  203.     }
  204.     void print_queue() const {
  205.       normal.print();
  206.     }
  207. };
Advertisement
Add Comment
Please, Sign In to add comment