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

Replace method #3

Open
wants to merge 2 commits 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
27 changes: 23 additions & 4 deletions contracts/DLL.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ library DLL {
function contains(Data storage self, uint _curr) public view returns (bool) {
if (isEmpty(self) || _curr == NULL_NODE_ID) {
return false;
}
}

bool isSingleNode = (getStart(self) == _curr) && (getEnd(self) == _curr);
bool isNullNode = (getNext(self, _curr) == NULL_NODE_ID) && (getPrev(self, _curr) == NULL_NODE_ID);
Expand All @@ -44,7 +44,7 @@ library DLL {
}

/**
@dev Inserts a new node between _prev and _next. When inserting a node already existing in
@dev Inserts a new node between _prev and _next. When inserting a node already existing in
the list it will be automatically removed from the old position.
@param _prev the node which _new will be inserted after
@param _curr the id of the new node being inserted
Expand All @@ -53,11 +53,11 @@ library DLL {
function insert(Data storage self, uint _prev, uint _curr, uint _next) public {
require(_curr != NULL_NODE_ID);

remove(self, _curr);

require(_prev == NULL_NODE_ID || contains(self, _prev));
require(_next == NULL_NODE_ID || contains(self, _next));

remove(self, _curr);

require(getNext(self, _prev) == _next);
require(getPrev(self, _next) == _prev);

Expand All @@ -68,6 +68,25 @@ library DLL {
self.dll[_next].prev = _curr;
}

function replace(Data storage self, uint _curr, uint _prev) public {
require(contains(self, _curr));
if (self.dll[_curr].prev == _prev) {
return;
}

require(_prev == NULL_NODE_ID || contains(self, _prev));

remove(self, _curr);

uint next = self.dll[_prev].next;

self.dll[_curr].prev = _prev;
self.dll[_curr].next = next;

self.dll[_prev].next = _curr;
self.dll[next].prev = _curr;
}

function remove(Data storage self, uint _curr) public {
if (!contains(self, _curr)) {
return;
Expand Down
12 changes: 8 additions & 4 deletions contracts/TestDLL.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,23 @@ contract TestDLL {
function isEmpty() public view returns (bool) {
return dll.isEmpty();
}

function contains(uint _curr) public view returns (bool) {
return dll.contains(_curr);
}

function getNext(uint _curr) public view returns (uint) {
return dll.getNext(_curr);
}

function getPrev(uint _curr) public view returns (uint) {
return dll.getPrev(_curr);
}

function getStart() public view returns (uint) {
return dll.getStart();
}

function getEnd() public view returns (uint) {
return dll.getEnd();
}
Expand All @@ -38,4 +38,8 @@ contract TestDLL {
function remove(uint _curr) public {
dll.remove(_curr);
}

function replace(uint _curr, uint _prev) public {
dll.replace(_curr, _prev);
}
}
52 changes: 52 additions & 0 deletions test/replace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
const TestDLL = artifacts.require('TestDLL.sol');
const utils = require('./utils.js');

contract('DLL', () => {
describe('Function: replace', () => {
it('Should throw error in non-existent node case', async () => {
const proxy = await TestDLL.deployed();

await proxy.insert(0, 1, 0);
try {
await proxy.replace(2, 0);
} catch (err) {
assert(utils.isEVMException(err), err.toString());

return;
}

assert(false, 'replace a non-existent node');
});

it('Should ignore replacing self-positioning node', async () => {
const proxy = await TestDLL.deployed();

await proxy.insert(0, 1, 0);
await proxy.replace(1, 0);

const start = await proxy.getStart();
const end = await proxy.getEnd();

assert.strictEqual(start.toString(10), '1', 'expected start to be 1');
assert.strictEqual(end.toString(10), '1', 'expected end to be 1');
});

it('Should replace a node', async () => {
const proxy = await TestDLL.deployed();

await proxy.insert(1, 2, 0);
await proxy.insert(2, 3, 0);
await proxy.replace(3, 1);

const start = await proxy.getStart();
const end = await proxy.getEnd();
const next = await proxy.getNext(1);
const nextAfter = await proxy.getNext(3);

assert.strictEqual(start.toString(10), '1', 'expected start to be 1');
assert.strictEqual(end.toString(10), '2', 'expected end to be 2');
assert.strictEqual(next.toString(10), '3', 'expected next to be 3');
assert.strictEqual(nextAfter.toString(10), '2', 'expected next after 3 to be 2');
});
});
});