Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache improvement #56

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 92 additions & 49 deletions LinkedList.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ struct ListNode
{
T data;
ListNode<T> *next;

ListNode<T>(ListNode<T>* _next = nullptr) : next(_next) {}
ListNode<T>(const T _v, ListNode<T>* _next = nullptr) : data(_v), next(_next) {}
};

template <typename T>
Expand All @@ -31,11 +34,8 @@ class LinkedList{
ListNode<T> *last;

// Helps "get" method, by saving last position
ListNode<T> *lastNodeGot;
int lastIndexGot;
// isCached should be set to FALSE
// everytime the list suffer changes
bool isCached;
ListNode<T> *lastNodeGot = nullptr;
int lastIndexGot=0; // cached node index

ListNode<T>* getNode(int index);

Expand All @@ -49,7 +49,7 @@ class LinkedList{
/*
Returns current size of LinkedList
*/
virtual int size();
virtual int size() const;
/*
Adds a T object in the specified index;
Unlink and link the LinkedList correcly;
Expand Down Expand Up @@ -91,6 +91,27 @@ class LinkedList{
*/
virtual T get(int index);

/*
Get first element of the list;
Return Element if accessible,
else, return false;
*/
virtual T head();

/*
Get last element of the list;
Return Element if accessible,
else, return false;
*/
virtual T tail();


/*
Return true if element with specified index exist
note: this works faster than (uncached) get(index)
*/
virtual bool exist(int index) const;

/*
Clear the entire array
*/
Expand All @@ -112,29 +133,24 @@ class LinkedList{
template<typename T>
LinkedList<T>::LinkedList()
{
root=NULL;
last=NULL;
root=nullptr;
last=nullptr;
_size=0;

lastNodeGot = root;
lastIndexGot = 0;
isCached = false;
}

// Clear Nodes and free Memory
template<typename T>
LinkedList<T>::~LinkedList()
{
ListNode<T>* tmp;
while(root!=NULL)
while(root)
{
tmp=root;
root=root->next;
delete tmp;
}
last = NULL;
last = nullptr;
_size=0;
isCached = false;
}

/*
Expand All @@ -149,7 +165,7 @@ ListNode<T>* LinkedList<T>::getNode(int index){

// Check if the node trying to get is
// immediatly AFTER the previous got one
if(isCached && lastIndexGot <= index){
if(lastIndexGot > 0 && lastIndexGot <= index){
_pos = lastIndexGot;
current = lastNodeGot;
}
Expand All @@ -162,7 +178,6 @@ ListNode<T>* LinkedList<T>::getNode(int index){

// Check if the object index got is the same as the required
if(_pos == index){
isCached = true;
lastIndexGot = index;
lastNodeGot = current;

Expand All @@ -173,7 +188,7 @@ ListNode<T>* LinkedList<T>::getNode(int index){
}

template<typename T>
int LinkedList<T>::size(){
int LinkedList<T>::size() const {
return _size;
}

Expand All @@ -186,44 +201,42 @@ LinkedList<T>::LinkedList(int sizeIndex, T _t){

template<typename T>
bool LinkedList<T>::add(int index, T _t){
if (index<0)
return false;

if(index >= _size)
return add(_t);

if(index == 0)
return unshift(_t);

ListNode<T> *tmp = new ListNode<T>(),
*_prev = getNode(index-1);
tmp->data = _t;
tmp->next = _prev->next;
_prev->next = tmp;
lastIndexGot = index;
ListNode<T> *_prev = getNode(--index);

_prev->next = new ListNode<T>(_t, _prev->next);
lastNodeGot = _prev->next;

_size++;
isCached = false;

return true;
}

template<typename T>
bool LinkedList<T>::add(T _t){

ListNode<T> *tmp = new ListNode<T>();
tmp->data = _t;
tmp->next = NULL;

if(root){
// Already have elements inserted
last->next = tmp;
last = tmp;
last->next = new ListNode<T>(_t);
last = last->next;
}else{
// First element being inserted
root = tmp;
last = tmp;
root = new ListNode<T>(_t);
last = root;
}

_size++;
isCached = false;
lastIndexGot = _size;
lastNodeGot = last;

return true;
}
Expand All @@ -234,13 +247,12 @@ bool LinkedList<T>::unshift(T _t){
if(_size == 0)
return add(_t);

ListNode<T> *tmp = new ListNode<T>();
tmp->next = root;
tmp->data = _t;
root = tmp;
root = new ListNode<T>(_t, root);

_size++;
isCached = false;

lastIndexGot = 0;
lastNodeGot = root;

return true;
}
Expand All @@ -266,22 +278,26 @@ T LinkedList<T>::pop(){
if(_size <= 0)
return T();

isCached = false;

if(_size >= 2){
if(_size > 1){
ListNode<T> *tmp = getNode(_size - 2);
T ret = tmp->next->data;
delete(tmp->next);
tmp->next = NULL;
tmp->next = nullptr;
last = tmp;
lastNodeGot = tmp;
_size--;
lastIndexGot = _size;
--lastIndexGot;
return ret;
}else{
// Only one element left on the list
T ret = root->data;
delete(root);
root = NULL;
last = NULL;
root = nullptr;
last = nullptr;
lastNodeGot = nullptr;
lastIndexGot = 0;
_size = 0;
return ret;
}
Expand All @@ -297,8 +313,9 @@ T LinkedList<T>::shift(){
T ret = root->data;
delete(root);
root = _next;
_size --;
isCached = false;
--_size;
lastIndexGot = 0;
lastNodeGot = root;

return ret;
}else{
Expand All @@ -323,13 +340,14 @@ T LinkedList<T>::remove(int index){
return pop();
}

ListNode<T> *tmp = getNode(index - 1);
ListNode<T> *tmp = getNode(--index);
ListNode<T> *toDelete = tmp->next;
T ret = toDelete->data;
tmp->next = tmp->next->next;
delete(toDelete);
_size--;
isCached = false;
lastIndexGot = index;
lastNodeGot = tmp;
return ret;
}

Expand Down Expand Up @@ -362,7 +380,7 @@ void LinkedList<T>::sort(int (*cmp)(T &, T &)){
if(!a_end->next ) {
if(joinPoint == &root) {
last = a_end;
isCached = false;
lastIndexGot = 0;
return;
}
else {
Expand Down Expand Up @@ -416,4 +434,29 @@ ListNode<T>* LinkedList<T>::findEndOfSortedString(ListNode<T> *p, int (*cmp)(T &
return p;
}

#endif
template<typename T>
T LinkedList<T>::head(){
if(_size>0)
return root->data;

return T();
}

template<typename T>
T LinkedList<T>::tail(){
if(_size>0)
return last->data;

return T();
}

template<typename T>
bool LinkedList<T>::exist(int index) const {
if (_size>0 && index >= 0 && index < _size)
return true;

return false;
}


#endif
49 changes: 49 additions & 0 deletions tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,52 @@ void GivenThreeInList_WhenClearIsCalled_ThenListEmpty()
assert(list.size() == 0);
}

// test head() method
void GivenTwoInList_WhenHeadIsCalled_ThenReturnsData()
{
//Arrange
LinkedList<int> list = LinkedList<int>();
list.add(0);
list.add(1);

//Assert
assert(list.head() == 0);
}

// test tail() method
void GivenTwoInList_WhenTailIsCalled_ThenReturnsData()
{
//Arrange
LinkedList<int> list = LinkedList<int>();
list.add(0);
list.add(1);

//Assert
assert(list.tail() == 1);
}

// test exist() method
void GivenThreeNodesInList_WhenExistCalled_ReturnsVarious()
{
//Arrange
LinkedList<int> list = LinkedList<int>();
//Act Assert
assert(list.exist(-1) == false);
assert(list.exist(0) == false);
assert(list.exist(1) == false);

list.add(1);
assert(list.exist(-1) == false);
assert(list.exist(0) == true);
assert(list.exist(1) == false);

list.add(2);
assert(list.exist(-1) == false);
assert(list.exist(0) == true);
assert(list.exist(1) == true);
}


int main()
{
GivenNothingInList_WhenSizeCalled_Returns0();
Expand Down Expand Up @@ -328,6 +374,9 @@ int main()
GivenThreeNodesInList_WhenGetIsCalled_ThenReturnsData();
GivenNothingInList_WhenClearIsCalled_ThenSizeUnchanged();
GivenThreeInList_WhenClearIsCalled_ThenListEmpty();
GivenTwoInList_WhenHeadIsCalled_ThenReturnsData();
GivenTwoInList_WhenTailIsCalled_ThenReturnsData();
GivenThreeNodesInList_WhenExistCalled_ReturnsVarious();

std::cout<< "Tests pass"<< std::endl;
}