Advertisement
Guest User

Black Magic

a guest
Nov 26th, 2014
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.28 KB | None | 0 0
  1. #include <iostream>
  2. #include <list>
  3. #include <vector>
  4. #include <algorithm>
  5. #include <iterator>
  6.  
  7. using std::vector;
  8. using std::cin;
  9. using std::cout;
  10. using std::endl;
  11. using std::sort;
  12. using std::swap;
  13. using std::list;
  14. using std::iter_swap;
  15. using std::iterator;
  16.  
  17. struct MemSegment {
  18.     int start;
  19.     int end;
  20.     bool isFree;
  21.     int heapIndex;
  22.  
  23.     MemSegment(int st, int end) {
  24.         this->start = st;
  25.         this->end = end;
  26.         isFree = true;
  27.  
  28.         heapIndex = -1;
  29.     }
  30.     MemSegment(int st, int end, bool free) {
  31.         this->start = st;
  32.         this->end = end;
  33.         this->isFree = free;
  34.  
  35.         heapIndex = -1;
  36.     }
  37.     int get_size() {
  38.         return end - start;
  39.     }
  40. };
  41.  
  42. typedef bool (* CompareSegments) (const list<MemSegment>::iterator& first,
  43.     const list<MemSegment>::iterator& second);
  44.  
  45. bool compare_size(const list<MemSegment>::iterator& first,
  46.     const list<MemSegment>::iterator& second) {
  47.     if (first->get_size() != second->get_size()) {
  48.         return first->get_size()  < second->get_size();
  49.     } else {
  50.         return first->start > second->start;
  51.     }
  52. }
  53.  
  54. class Heap {
  55. private:
  56.     vector<list<MemSegment>::iterator> elements;
  57.     CompareSegments compare;
  58.  
  59.     int left_index(int ind) {
  60.         return ind * 2 + 1;
  61.     }
  62.     int right_index(int ind) {
  63.         return left_index(ind) + 1;
  64.     }
  65.     int parent_index(int ind) {
  66.         return (ind + 1) / 2 - 1;
  67.     }
  68.     void swap_elements(int first, int second) {
  69.         iter_swap(elements.begin() + first, elements.begin() + second);
  70.  
  71.         update_index(first);
  72.         update_index(second);
  73.     }
  74.     void update_index(int ind) {
  75.         elements.at(ind)->heapIndex = ind;
  76.     }
  77.     void sift_up(int index);
  78.     void sift_down(int index);
  79.  
  80. public:
  81.     explicit Heap(CompareSegments compare) {
  82.         this->compare = compare;
  83.     }
  84.     bool isEmpty() {
  85.         return elements.size() == 0;
  86.     }
  87.     void insert_element(list<MemSegment>::iterator element) {
  88.         elements.push_back(element);
  89.         int last = elements.size() - 1;
  90.         update_index(last);
  91.         sift_up(last);
  92.     }
  93.     list<MemSegment>::iterator get_top() {
  94.         return elements[0];
  95.     }
  96.     list<MemSegment>::iterator remove_top() {
  97.         swap_elements(0, elements.size() - 1);
  98.         list<MemSegment>::iterator last = elements.back();
  99.         last->heapIndex = -1;
  100.         elements.pop_back();
  101.         sift_down(0);
  102.         return last;
  103.     }
  104.     void remove_element(list<MemSegment>::iterator& element) {
  105.         int ind = element->heapIndex;
  106.         swap_elements(elements.size() - 1, ind);
  107.  
  108.         elements.pop_back();
  109.         element->heapIndex = -1;
  110.  
  111.  
  112.         if (ind < elements.size()) {
  113.             sift_down(ind);
  114.             sift_up(ind);
  115.         }
  116.     }
  117. };
  118.  
  119. class MemoryManager {
  120. private:
  121.     Heap heap;
  122.     list<MemSegment> segments;
  123.     vector<list<MemSegment>::iterator> inquiry_results;
  124. public:
  125.     explicit MemoryManager(int slots) : heap(& compare_size) {
  126.         MemSegment segment_of_mem(0, slots);
  127.  
  128.         segments.push_back(segment_of_mem);
  129.         heap.insert_element(segments.begin());
  130.     }
  131.     int insert_inquiry(int size);
  132.     void free(int number_of_inquiry);
  133. };
  134.  
  135. int main() {
  136.     std::ios_base::sync_with_stdio(false);
  137.     int memory_size;
  138.     cin >> memory_size;
  139.     int inquiry_count;
  140.     cin >> inquiry_count;
  141.     MemoryManager memory_manager(memory_size);
  142.  
  143.     for (int inquiry_num = 0; inquiry_num < inquiry_count; ++inquiry_num) {
  144.         int inquiry;
  145.         cin >> inquiry;
  146.         if (inquiry > 0) {
  147.             int allocation_result = memory_manager.insert_inquiry(inquiry);
  148.             if (allocation_result != -1) {
  149.                 int temp = allocation_result + 1;
  150.                 cout << temp << endl;
  151.             } else {
  152.                 int temp = allocation_result;
  153.                 cout << temp << endl;
  154.             }
  155.         } else if (inquiry < 0) {
  156.             memory_manager.free(-inquiry - 1);
  157.         }
  158.     }
  159.     return 0;
  160. }
  161.  
  162. void Heap::sift_up(int index) {
  163.     bool should_proceed = true;
  164.     do {
  165.         int parent = parent_index(index);
  166.         if (parent >= 0 && compare(elements[parent], elements[index])) {
  167.             swap_elements(index, parent);
  168.             index = parent;
  169.         } else {
  170.             should_proceed = false;
  171.         }
  172.     } while (should_proceed);
  173. }
  174.  
  175. void Heap::sift_down(int index) {
  176.     bool should_proceed = true;
  177.     do {
  178.         int left = left_index(index);
  179.         int right = right_index(index);
  180.         int largest;
  181.  
  182.         if (left < elements.size() && compare(elements[index], elements[left])) {
  183.             largest = left;
  184.         } else {
  185.             largest = index;
  186.         }
  187.  
  188.         if (right < elements.size() &&  compare(elements[largest], elements[right])) {
  189.             largest = right;
  190.         }
  191.  
  192.         if (largest != index) {
  193.             swap_elements(index, largest);
  194.             index = largest;
  195.         } else {
  196.             should_proceed = false;
  197.         }
  198.     } while (should_proceed);
  199. }
  200.  
  201. int MemoryManager::insert_inquiry(int size) {
  202.     bool empty = heap.isEmpty();
  203.     if (empty) {
  204.         inquiry_results.push_back(segments.end());
  205.         return -1;
  206.     }
  207.     int top_size = heap.get_top()->get_size();
  208.  
  209.     if (top_size < size) {
  210.         inquiry_results.push_back(segments.end());
  211.  
  212.         return -1;
  213.     }
  214.     list<MemSegment>::iterator seg_element = heap.remove_top();
  215.     if (top_size == size) {
  216.         seg_element->isFree = false;
  217.         inquiry_results.push_back(seg_element);
  218.  
  219.         return seg_element->start;
  220.     } else {
  221.         MemSegment busy_block = MemSegment(
  222.             seg_element->start, seg_element->start + size, false);
  223.         MemSegment free_block = MemSegment(seg_element->start + size, seg_element->end);
  224.  
  225.         list<MemSegment>::iterator busy_element = segments.insert(seg_element, busy_block);
  226.         inquiry_results.push_back(busy_element);
  227.  
  228.         list<MemSegment>::iterator free_element = segments.insert(seg_element, free_block);
  229.         heap.insert_element(free_element);
  230.  
  231.         segments.erase(seg_element);
  232.  
  233.         return busy_block.start;
  234.     }
  235. }
  236.  
  237. void MemoryManager::free(int number_of_inquiry) {
  238.     inquiry_results.push_back(segments.end());
  239.  
  240.     list<MemSegment>::iterator busy_element = inquiry_results[number_of_inquiry];
  241.     if (busy_element == segments.end()) {
  242.         return;
  243.     }
  244.  
  245.     int start = busy_element->start;
  246.     int end = busy_element->end;
  247.  
  248.     if (busy_element != segments.begin()) {
  249.        list<MemSegment>::iterator previous = busy_element;
  250.         --previous;
  251.  
  252.         if (previous->isFree) {
  253.             start = previous->start;
  254.  
  255.             heap.remove_element(previous);
  256.             segments.erase(previous);
  257.         }
  258.     }
  259.  
  260.     list<MemSegment>::iterator next = busy_element;
  261.     ++next;
  262.  
  263.     if (next != segments.end() && next->isFree) {
  264.         end = next->end;
  265.  
  266.         heap.remove_element(next);
  267.         segments.erase(next);
  268.  
  269.         next = busy_element;
  270.         ++next;
  271.     }
  272.     segments.erase(busy_element);
  273.  
  274.     MemSegment free_block = MemSegment(start, end);
  275.     list<MemSegment>::iterator free_element = segments.insert(next, free_block);
  276.     heap.insert_element(free_element);
  277. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement