Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "Mapper.h"
- void Mapper::initializeEmptyMapper()
- {
- m_size = 0;
- m_dummy = new Node;
- m_dummy->m_next = m_dummy;
- m_dummy->m_prev = m_dummy;
- }
- Mapper::Mapper()
- {
- initializeEmptyMapper();
- }
- // Before we can actually insert the node, we need to implement the insert before function
- void Mapper::insertNewHead(const std::string& name, const std::string& association)
- {
- Node* new_head = new Node;
- new_head->m_name = name;
- new_head->m_association = association;
- if (m_head == nullptr)
- {
- m_head = new_head;
- m_head->m_next = m_dummy;
- m_head->m_prev = m_dummy;
- m_tail = m_head;
- m_size++;
- m_dummy->m_next = m_head;
- m_dummy->m_prev = m_head;
- return;
- }
- m_head->m_prev = new_head;
- new_head->m_prev = m_dummy;
- new_head->m_next = m_head;
- m_head = new_head;
- m_size++;
- m_dummy->m_next = m_head;
- }
- void Mapper::insertNewTail(const std::string& name, const std::string& association)
- {
- Node* new_tail = new Node;
- m_tail->m_next = new_tail;
- new_tail->m_name = name;
- new_tail->m_association = association;
- new_tail->m_prev = m_tail;
- new_tail->m_next = m_dummy;
- m_tail = new_tail;
- m_size++;
- m_dummy->m_prev = m_tail;
- }
- void Mapper::insertBefore(Node* p, const std::string& name, const std::string& association)
- {
- //Create a new node
- Node* new_pointer = new Node;
- new_pointer->m_name = name;
- new_pointer->m_association = association;
- if (p == m_head)
- {
- insertNewHead(name, association);
- return;
- }
- // Set the new pointer's previous pointer equal to p's previous pointer
- // Then set the new pointer's next pointer equal to p
- new_pointer->m_prev = p->m_prev;
- new_pointer->m_next = p;
- // We must now make the previous nodes point to this new node
- // Then we must make the next node have its previous point to this node.
- new_pointer->m_prev->m_next = new_pointer;
- new_pointer->m_next->m_prev = new_pointer;
- m_size++;
- }
- Mapper::Node* Mapper::findClosestLocation(const std::string& name) const
- {
- // Have to change this implementation because we always start with a dummy node
- if (m_size == 0)
- {
- return m_dummy;
- }
- Node* traversalNode = m_head;
- while (traversalNode->m_next != m_dummy && traversalNode->m_name < name)
- traversalNode = traversalNode->m_next;
- return traversalNode;
- }
- void Mapper::associate(const std::string& key, const std::string& value)
- {
- if (m_head == nullptr)
- {
- insertNewHead(key, value);
- return;
- }
- Node* closestNode = findClosestLocation(key);
- if (closestNode->m_name == key)
- {
- // It doesn't really matter if the associated value before was the same or not
- // We'll ensure that the latest associated value is always updated
- closestNode->m_association = value;
- return;
- }
- else if (closestNode == m_tail)
- {
- if (key > m_tail->m_name)
- {
- insertNewTail(key, value);
- return;
- }
- }
- // insertBefore command actually checks if it should be a new head
- insertBefore(closestNode, key, value);
- }
- void Mapper::actualErase(Node* p)
- {
- // There are 4 cases to consider
- // If there is only a single node, then we will delete it and set its next and prev to nullptr
- // This is different from deleting a node in the middle because we don't have to link surrounding nodes together after deletion
- if (m_size == 1)
- {
- p->m_next = p->m_prev = nullptr;
- m_head = nullptr;
- m_tail = nullptr;
- }
- // If we are deleting the head, then we must allocate a new head
- else if (p == m_head)
- {
- m_head = m_head->m_next;
- m_dummy->m_next = m_head;
- m_head->m_prev = m_dummy;
- }
- // If we are deleting the tail, then we must allocate a new tail
- else if (p == m_tail)
- {
- m_tail = m_tail->m_prev;
- m_dummy->m_prev = m_tail;
- m_tail->m_next = m_dummy;
- }
- // Because we are deleting a node in the middle, we need to make sure that we are linking the surrounding nodes together
- else
- {
- p->m_prev->m_next = p->m_next;
- p->m_next->m_prev = p->m_prev;
- }
- delete p;
- m_size--;
- }
- void Mapper::erase(const std::string& key)
- {
- if (m_size == 0)
- return;
- Node* closestNode = findClosestLocation(key);
- if (closestNode->m_name != key)
- return;
- actualErase(closestNode);
- }
- bool Mapper::empty() const
- {
- return (m_size == 0);
- }
- Mapper::~Mapper()
- {
- while (m_size > 0)
- {
- actualErase(m_head);
- }
- delete m_dummy;
- }
- bool Mapper::find(const std::string& key, std::string& value) const
- {
- if (m_size == 0)
- return false;
- Node* closestNode = findClosestLocation(key);
- if (closestNode->m_name == key)
- {
- value = closestNode->m_association;
- return true;
- }
- else
- return false;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement