Commit 52d97608 authored by MoutazDebbaneh's avatar MoutazDebbaneh

Solved all questions

parent ef4a140b
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Entry {
public Integer object;
public Entry next;
public ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public Entry(Integer object) {
this.object = object;
}
......
......@@ -25,6 +25,7 @@ public class LockList extends SortList {
Entry newEntry = new Entry(obj);
newEntry.next = curr;
prev.next = newEntry;
this.length++;
return true;
}
} finally {
......@@ -44,8 +45,11 @@ public class LockList extends SortList {
}
if (curr.object.equals(obj)) {
prev.next = curr.next;
this.length--;
successfulRemoves++;
return true;
} else {
unsuccessfulRemoves++;
return false;
}
} finally {
......@@ -65,8 +69,10 @@ public class LockList extends SortList {
curr = prev.next;
}
if (curr.object.equals(obj) || prev.object.equals(obj)) {
successfulContains++;
return true;
} else {
unsuccessfulContains++;
return false;
}
} finally {
......
......@@ -2,6 +2,8 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
public class RWLockList extends SortList {
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
ReentrantReadWriteLock successfulContainsLock = new ReentrantReadWriteLock();
ReentrantReadWriteLock unsuccessfulContainsLock = new ReentrantReadWriteLock();
public RWLockList() {
super();
......@@ -24,6 +26,7 @@ public class RWLockList extends SortList {
Entry newEntry = new Entry(obj);
newEntry.next = curr;
prev.next = newEntry;
this.length++;
return true;
}
} finally {
......@@ -43,8 +46,11 @@ public class RWLockList extends SortList {
}
if (curr.object.equals(obj)) {
prev.next = curr.next;
this.length--;
successfulRemoves++;
return true;
} else {
unsuccessfulRemoves++;
return false;
}
} finally {
......@@ -64,8 +70,14 @@ public class RWLockList extends SortList {
curr = prev.next;
}
if (curr.object.equals(obj) || prev.object.equals(obj)) {
successfulContainsLock.writeLock().lock();
successfulContains++;
successfulContainsLock.writeLock().unlock();
return true;
} else {
unsuccessfulContainsLock.writeLock().lock();
unsuccessfulContains++;
unsuccessfulContainsLock.writeLock().unlock();
return false;
}
} finally {
......@@ -73,4 +85,46 @@ public class RWLockList extends SortList {
}
}
public boolean safeRemoveElement(Integer obj){
Entry prev, curr;
this.head.lock.readLock().lock();
prev = this.head;
prev.next.lock.readLock().lock();
curr = prev.next;
while (curr.object.compareTo(obj) < 0) {
curr.next.lock.readLock().lock();
prev.lock.readLock().unlock();
prev = curr;
curr = prev.next;
}
prev.lock.readLock().unlock();
curr.lock.readLock().unlock();
prev.lock.writeLock().lock();
curr.lock.writeLock().lock();
boolean isRemoved;
if (curr.object.equals(obj)) {
prev.next = curr.next;
isRemoved = true;
} else {
isRemoved = false;
}
prev.lock.writeLock().unlock();
curr.lock.writeLock().unlock();
return isRemoved;
}
public void removeList(Integer[] toRemoveList){
for(Integer obj: toRemoveList){
safeRemoveElement(obj);
}
}
}
public abstract class SortList {
public Entry head;
public int length;
public int successfulContains = 0;
public int unsuccessfulContains = 0;
public int successfulRemoves = 0;
public int unsuccessfulRemoves = 0;
public SortList() {
this.head = new Entry(Integer.MIN_VALUE);
this.head.next =new Entry(Integer.MAX_VALUE);
this.head.next =new Entry(Integer.MAX_VALUE);
this.length = 2;
}
public abstract boolean add(Integer obj);
......@@ -19,4 +25,13 @@ public abstract class SortList {
}
}
public boolean isSorted(){
Entry curr = this.head;
while (curr.next != null){
if(curr.object > curr.next.object) return false;
curr = curr.next;
}
return true;
}
}
......@@ -18,6 +18,7 @@ public class SyncList extends SortList {
Entry newEntry = new Entry(obj);
newEntry.next = curr;
prev.next = newEntry;
this.length++;
return true;
}
}
......@@ -32,8 +33,11 @@ public class SyncList extends SortList {
}
if (curr.object.equals(obj)) {
prev.next = curr.next;
this.length--;
successfulRemoves++;
return true;
} else {
unsuccessfulRemoves++;
return false;
}
......@@ -48,8 +52,10 @@ public class SyncList extends SortList {
curr = prev.next;
}
if (curr.object.equals(obj) || prev.object.equals(obj)) {
successfulContains++;
return true;
} else {
unsuccessfulContains++;
return false;
}
}
......
public class RemoveAllThread extends TestThread implements Runnable {
public RemoveAllThread(RandomSequenceGenerator seq, RWLockList setList, int seqPart) {
super(seq, setList, seqPart);
}
@Override
public void run() {
((RWLockList)list).removeList(nums);
}
}
import junit.framework.TestCase;
import org.junit.Assert;
import java.util.ArrayList;
import java.util.List;
......@@ -29,18 +30,20 @@ public class SyncListTest extends TestCase {
}
int randLength = 20_000;
int numOfThreads = 8;
int randNumsRange = 80_000;
public void testHelp(SortList sortList, String label) {
RandomSequenceGenerator randomSeq = new RandomSequenceGenerator(0, 80_000);
RandomSequenceGenerator randomSeq = new RandomSequenceGenerator(0, randNumsRange);
List<Thread> addThreads = new ArrayList<Thread>();
List<Thread> containThreads = new ArrayList<Thread>();
List<Thread> removeThreads = new ArrayList<Thread>();
for (int i = 0; i < 8; i++) {
AddThread addThread = new AddThread(randomSeq, sortList,randLength/8 );
ContainThread containThread = new ContainThread(randomSeq, sortList,randLength/8 );
RemoveThread removeThread = new RemoveThread(randomSeq, sortList,randLength/8 );
for (int i = 0; i < numOfThreads; i++) {
AddThread addThread = new AddThread(randomSeq, sortList,randLength/numOfThreads);
ContainThread containThread = new ContainThread(randomSeq, sortList,randLength/numOfThreads);
RemoveThread removeThread = new RemoveThread(randomSeq, sortList,randLength/numOfThreads);
addThreads.add(new Thread(addThread));
containThreads.add(new Thread(containThread));
......@@ -62,6 +65,13 @@ public class SyncListTest extends TestCase {
System.out.println(label + " add execution time: " + (end-start));
// Ensure list is still sorted
Assert.assertTrue(sortList.isSorted());
// List length after add operations
int listLengthAfterAdds = sortList.length;
System.out.println("List length after add " + listLengthAfterAdds);
start = System.currentTimeMillis();
containThreads.stream().forEach(e -> e.start());
......@@ -76,6 +86,9 @@ public class SyncListTest extends TestCase {
end = System.currentTimeMillis();
System.out.println(label + " contain execution time: " + (end-start));
int totalSuccessfulContains = sortList.successfulContains;
int totalUnsuccessfulContains = sortList.unsuccessfulContains;
System.out.println("Total number of successes found " + totalSuccessfulContains + ", failures found: " + totalUnsuccessfulContains);
start = System.currentTimeMillis();
......@@ -92,7 +105,91 @@ public class SyncListTest extends TestCase {
System.out.println(label + " remove execution time: " + (end-start));
// Ensure list is still sorted
Assert.assertTrue(sortList.isSorted());
// List length after remove operations
int listLengthAfterRemove = sortList.length;
System.out.println("List length after remove " + listLengthAfterRemove);
int totalSuccessfulRemoves = sortList.successfulRemoves;
int totalUnsuccessfulRemoves = sortList.unsuccessfulRemoves;
System.out.println("Total number of successes removed " + totalSuccessfulRemoves + ", failures found: " + totalUnsuccessfulRemoves);
}
public void testWithRemoveAllHelp(RWLockList sortList, String label) {
RandomSequenceGenerator randomSeq = new RandomSequenceGenerator(0, randNumsRange);
List<Thread> addThreads = new ArrayList<Thread>();
List<Thread> containThreads = new ArrayList<Thread>();
List<Thread> removeThreads = new ArrayList<Thread>();
for (int i = 0; i < 8; i++) {
AddThread addThread = new AddThread(randomSeq, sortList,randLength/numOfThreads);
ContainThread containThread = new ContainThread(randomSeq, sortList,randLength/numOfThreads);
RemoveAllThread removeAllThread = new RemoveAllThread(randomSeq, sortList,randLength/numOfThreads);
addThreads.add(new Thread(addThread));
containThreads.add(new Thread(containThread));
removeThreads.add(new Thread(removeAllThread));
}
long start = System.currentTimeMillis();
addThreads.stream().forEach(e -> e.start());
addThreads.stream().forEach(e -> {
try {
e.join();
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
});
long end = System.currentTimeMillis();
System.out.println(label + " add execution time: " + (end-start));
// Ensure list is still sorted
Assert.assertTrue(sortList.isSorted());
// List length after add operations
int listLengthAfterAdds = sortList.length;
System.out.println("List length after add " + listLengthAfterAdds);
start = System.currentTimeMillis();
containThreads.stream().forEach(e -> e.start());
containThreads.stream().forEach(e -> {
try {
e.join();
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
});
end = System.currentTimeMillis();
System.out.println(label + " contain execution time: " + (end-start));
int totalSuccessfulContains = sortList.successfulContains;
int totalUnsuccessfulContains = sortList.unsuccessfulContains;
System.out.println("Total number of successes found " + totalSuccessfulContains + ", failures found: " + totalUnsuccessfulContains);
start = System.currentTimeMillis();
removeThreads.stream().forEach(e -> e.start());
removeThreads.stream().forEach(e -> {
try {
e.join();
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
});
end = System.currentTimeMillis();
System.out.println(label + " remove execution time: " + (end-start));
}
......@@ -109,5 +206,9 @@ public class SyncListTest extends TestCase {
testHelp(rwLockList, "RWLockList");
}
public void testWithRemoveAllRun(){
RWLockList rwLockList = new RWLockList();
testWithRemoveAllHelp(rwLockList, "RWLockList With Remove All");
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment