#ifndef ENVIRONNEMENT_QUEUE_SORT_QUEUE_DYNAMIC_H #define ENVIRONNEMENT_QUEUE_SORT_QUEUE_DYNAMIC_H #include #include #include "Parameters.h" #include "Queue.h" namespace environnement { namespace queue { #define PERCENT_USE_MAX 90 #define PERCENT_USE_MIN 33 /* * Queue, sort by delay with a dynamic size */ template class Sort_Queue_Dynamic : public Queue { // *****[ variables ]***** private : uint32_t _factor ; private : uint32_t _size_base; // *****[ constructor ]***** public : Sort_Queue_Dynamic (std::string name, Parameters * param) : Queue (name, param->_size) { _size_base = param->_size; _factor = 1; }; // *****[ destructor ]***** public : ~Sort_Queue_Dynamic () { }; // *****[ must_decrease ]***** // Test if the queue must be decrease private : bool must_decrease (void) { return ( (_factor > 1 ) and (((100*Queue ::_nb_slot)/Queue ::_size) <= PERCENT_USE_MIN)); } // *****[ must_increase ]***** // Test if the queue must be increase private : bool must_increase (void) { return (((100*Queue ::_nb_slot)/Queue ::_size) >= PERCENT_USE_MAX); } // *****[ increase ]***** // increase the queue private : void increase (void) { _factor ++; change_size (_factor*_size_base); } // *****[ decrease ]***** // decrease the queue private : void decrease (void) { _factor --; change_size (_factor*_size_base); } // *****[ change_size ]***** // decrease the queue private : void change_size (uint32_t new_size) { slot_t * new_slot = new slot_t [new_size]; // copy data for (uint32_t it = 0; it < Queue ::_nb_slot; it ++) { new_slot [it] = Queue ::_slot [it]; } // Change information delete [] Queue ::_slot; Queue ::_slot = new_slot; Queue ::_size = new_size; } // *****[ reset ]***** // Reset the queue in the empty state public : void reset (void) { Queue ::_nb_slot = 0; }; // *****[ transition ]***** // Decrease the delay at all cycle public : void transition () { for (uint32_t it = 0; it < Queue ::_nb_slot; it ++) { if (Queue ::_slot[it]._delay != 0) Queue ::_slot[it] ._delay --; } } // *****[ read ]***** // return the n-eme slot. // (first = 0) public : slot_t read (uint32_t num) { if (num >= Queue ::_nb_slot) { std::cerr << " {ERROR} can't read because : num (" << num << ") >= _nb_slot (" << Queue ::_nb_slot << ")" << std::endl; exit(1); } return Queue ::_slot[num]; }; // *****[ pop ]***** // read the queue, and update the pointer public : T pop () { return pop (0); } // *****[ pop ]***** // read the queue, and update the pointer public : T pop (uint32_t num) { if (num >= Queue ::_nb_slot) { std::cerr << " {ERROR} can't read because : num (" << num << ") >= _nb_slot (" << Queue ::_nb_slot << ")" << std::endl; exit(1); } // If full -> quit if (must_decrease() == true) decrease(); T val = Queue ::_slot [num]._data; // Reorganize the queue for (uint32_t it = num; it < Queue ::_nb_slot; it ++) { uint32_t ptr = (it); uint32_t ptr_next = (it+1); Queue ::_slot [ptr] = Queue ::_slot [ptr_next]; } Queue ::_nb_slot --; return val; } // *****[ push ]***** // Push a new value (they must have a slot free) // Is sort by delay public : bool push (uint32_t delay, T val) { // std::cout << val << std::endl; // Test if must increase the queue (never full) if (must_increase() == true) increase(); uint32_t ptr = Queue ::_nb_slot; // Scan the fill to find the good position (keep the sort) for (uint32_t it = 0; it < Queue ::_nb_slot; it ++) { uint32_t ptr_scan = ptr-1; // ptr > 0 if (Queue ::_slot[ptr_scan]._delay <= delay) break; //find // reformor the queue Queue ::_slot [ptr] = Queue ::_slot [ptr_scan]; ptr = ptr_scan; } Queue ::_slot [ptr] = slot_t (delay,val); Queue ::_nb_slot ++; return true; } // *****[ print ]***** public : friend std::ostream& operator<< (std::ostream& output, const Sort_Queue_Dynamic & x) { output << "<" << x._name << ">" << std::endl; output << " * nb_slot : " << x._nb_slot << std::endl; output << " * size : " << x._size << std::endl; output << " * factor : " << x._factor << std::endl; for (uint32_t it = 0; it < x._nb_slot; it ++) { output << x._slot [it] << std::endl; } return output; }; }; }; }; #endif