Skip to content

Commit 854cb5c

Browse files
committed
MNEMONIC-95: Durable Set Add/Remove/Contains implementation
1 parent 2c82bdb commit 854cb5c

File tree

4 files changed

+225
-30
lines changed

4 files changed

+225
-30
lines changed

bin/test.conf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ mvn -Dtest=DurablePersonNGTest test -pl mnemonic-collections -DskipTests=false
3838
# a testcase for module "mnemonic-collection" that requires 'pmalloc' memory service to pass
3939
mvn -Dtest=DurableHashMapNGTest test -pl mnemonic-collections -DskipTests=false
4040

41+
# a testcase for module "mnemonic-collection" that requires 'pmalloc' memory service to pass
42+
mvn -Dtest=DurableHashSetNGTest test -pl mnemonic-collections -DskipTests=false
43+
4144
# a testcase for module "mnemonic-collection" that requires 'pmalloc' memory service to pass
4245
mvn -Dtest=DurableArrayNGTest test -pl mnemonic-collections -DskipTests=false
4346

mnemonic-collections/src/main/java/org/apache/mnemonic/collections/DurableHashSet.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,23 +69,32 @@ public void setupGenericInfo(EntityFactoryProxy[] efproxies, DurableType[] gftyp
6969
/**
7070
* checks if set contains the specified element
7171
*
72+
* @param item
73+
* the item to be searched
74+
*
7275
* @return true if set contains the element
7376
*/
7477
public abstract boolean contains(E item);
7578

7679
/**
7780
* adds a specific element to the set
7881
*
82+
* @param item
83+
* the item to be added
84+
*
7985
* @return true if set did not already contain the element
8086
*/
8187
public abstract boolean add(E item);
8288

8389
/**
8490
* removes a specific element from the set
8591
*
92+
* @param item
93+
* the item to be removed
94+
*
8695
* @return true if set contained the element
8796
*/
88-
public abstract boolean remove(E value);
97+
public abstract boolean remove(E item);
8998

9099
/**
91100
* Get the number of elements in the set

mnemonic-collections/src/main/java/org/apache/mnemonic/collections/DurableHashSetImpl.java

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.apache.mnemonic.RetrieveDurableEntityError;
2727
import org.apache.mnemonic.Utils;
2828

29+
import org.apache.commons.lang3.ArrayUtils;
2930
import sun.misc.Unsafe;
3031
import java.util.Iterator;
3132

@@ -38,9 +39,10 @@ public class DurableHashSetImpl<A extends RestorableAllocator<A>, E>
3839
private EntityFactoryProxy[] factoryProxy;
3940
private DurableType[] genericType;
4041
private volatile boolean autoReclaim;
41-
private DurableHashMap<E, Object> map;
42+
private DurableHashMap<E, Boolean> map;
4243
private A allocator;
4344
private long initialCapacity;
45+
private static final Boolean DEFAULT = Boolean.TRUE;
4446

4547
public void setCapacityHint(long capacity) {
4648
initialCapacity = capacity;
@@ -53,31 +55,37 @@ public long getSize() {
5355
/**
5456
* adds a specific element to the set
5557
*
58+
* @param item
59+
* the item to be added
60+
*
5661
* @return true if set did not already contain the element
5762
*/
5863
public boolean add(E item) {
59-
//add logic for adding item
60-
return true;
64+
return map.put(item, DEFAULT) == null;
6165
}
6266

6367
/**
6468
* removes a specific element from the set
6569
*
70+
* @param item
71+
* the item to be removed
72+
*
6673
* @return true if set contained the element
6774
*/
68-
public boolean remove(E value) {
69-
//add logic for removing item
70-
return true;
75+
public boolean remove(E item) {
76+
return map.remove(item) == DEFAULT;
7177
}
7278

7379
/**
7480
* checks if set contains the specified element
7581
*
82+
* @param item
83+
* the item to be searched
84+
*
7685
* @return true if set contains the element
7786
*/
7887
public boolean contains(E item) {
79-
//add logic to check if set contains the item
80-
return true;
88+
return map.get(item) != null;
8189
}
8290

8391
@Override
@@ -143,7 +151,7 @@ public void restoreDurableEntity(A allocator, EntityFactoryProxy[] factoryProxy,
143151
if (0L == phandler) {
144152
throw new RestoreDurableEntityError("Input handler is null on restoreDurableEntity.");
145153
}
146-
map = DurableHashMapFactory.restore(allocator, factoryProxy, gType, phandler, autoReclaim);
154+
map = DurableHashMapFactory.restore(allocator, this.factoryProxy, this.genericType, phandler, autoReclaim);
147155
if (null == map) {
148156
throw new RestoreDurableEntityError("Retrieve Entity Failure!");
149157
}
@@ -155,9 +163,10 @@ public void restoreDurableEntity(A allocator, EntityFactoryProxy[] factoryProxy,
155163
public void initializeDurableEntity(A allocator, EntityFactoryProxy[] factoryProxy,
156164
DurableType[] gType, boolean autoReclaim) {
157165
this.allocator = allocator;
158-
this.factoryProxy = factoryProxy;
159-
this.genericType = gType;
160166
this.autoReclaim = autoReclaim;
167+
DurableType gftypes[] = {DurableType.BOOLEAN};
168+
this.genericType = ArrayUtils.addAll(gType, gftypes);
169+
this.factoryProxy = ArrayUtils.addAll(factoryProxy, null);
161170
try {
162171
this.unsafe = Utils.getUnsafe();
163172
} catch (Exception e) {
@@ -169,12 +178,38 @@ public void initializeDurableEntity(A allocator, EntityFactoryProxy[] factoryPro
169178
public void createDurableEntity(A allocator, EntityFactoryProxy[] factoryProxy,
170179
DurableType[] gType, boolean autoReclaim) throws OutOfHybridMemory {
171180
initializeDurableEntity(allocator, factoryProxy, gType, autoReclaim);
172-
map = DurableHashMapFactory.create(allocator, factoryProxy, gType, initialCapacity, autoReclaim);
181+
map = DurableHashMapFactory.create(allocator, this.factoryProxy, this.genericType, initialCapacity, autoReclaim);
173182
initializeAfterCreate();
174183
}
175184

176185
@Override
177186
public Iterator<E> iterator() {
178-
return null;
187+
return new HashSetItr(map.iterator());
188+
}
189+
190+
private class HashSetItr implements Iterator<E> {
191+
192+
Iterator<MapEntry<E, Boolean>> mapItr;
193+
194+
HashSetItr(Iterator<MapEntry<E, Boolean>> itr) {
195+
this.mapItr = itr;
196+
}
197+
198+
@Override
199+
public boolean hasNext() {
200+
return mapItr.hasNext();
201+
}
202+
203+
@Override
204+
public E next() {
205+
return mapItr.next().getKey();
206+
}
207+
208+
@Override
209+
public void remove() {
210+
mapItr.remove();
211+
}
212+
213+
179214
}
180215
}

mnemonic-collections/src/test/java/org/apache/mnemonic/collections/DurableHashSetNGTest.java

Lines changed: 164 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,26 @@
1717

1818
package org.apache.mnemonic.collections;
1919

20+
import java.util.Iterator;
2021
import java.nio.ByteBuffer;
2122
import java.util.Random;
2223
import java.util.zip.Checksum;
23-
//import java.util.zip.CRC32;
24-
//import org.apache.commons.lang3.tuple.Pair;
25-
//import org.apache.commons.lang3.ArrayUtils;
2624

2725
import org.apache.mnemonic.Utils;
2826
import org.apache.mnemonic.NonVolatileMemAllocator;
29-
//import org.apache.mnemonic.RestorableAllocator;
27+
import org.apache.mnemonic.RestorableAllocator;
28+
import org.apache.mnemonic.ParameterHolder;
3029
import org.apache.mnemonic.OutOfHybridMemory;
3130
import org.apache.mnemonic.DurableBuffer;
3231
import org.apache.mnemonic.DurableChunk;
3332
import org.apache.mnemonic.DurableType;
34-
//import org.apache.mnemonic.Durable;
35-
//import org.apache.mnemonic.EntityFactoryProxy;
33+
import org.apache.mnemonic.EntityFactoryProxy;
3634
import org.apache.mnemonic.Reclaim;
3735
import org.apache.commons.lang3.RandomUtils;
3836
import org.testng.annotations.AfterClass;
3937
import org.testng.annotations.BeforeClass;
4038
import org.testng.annotations.Test;
39+
import org.testng.AssertJUnit;
4140
import org.testng.Assert;
4241

4342
import sun.misc.Unsafe;
@@ -126,33 +125,182 @@ public void tearDown() {
126125
}
127126

128127
@Test(enabled = true)
129-
public void testAddRemoveSetPrimitives() {
128+
public void testAddRemoveSetIntegers() {
130129
DurableType gtypes[] = {DurableType.INTEGER};
131130
DurableHashSet<Integer> set = DurableHashSetFactory.create(m_act, null, gtypes, initialCapacity, false);
132131

133132
Long handler = set.getHandler();
134133
boolean val;
135-
/*for (int i = 0; i < 100; i++) {
134+
for (int i = 0; i < 10; i++) {
136135
val = set.add(i);
137-
Assert.assertFalse(val)
136+
Assert.assertTrue(val);
138137
}
139138

140-
for (int i = 0; i < 100; i++) {
139+
for (int i = 0; i < 10; i++) {
141140
val = set.contains(i);
142-
Assert.assertTrue(val)
141+
Assert.assertTrue(val);
143142
}
144143

145-
for (int i = 0; i < 100; i++) {
144+
for (int i = 0; i < 10; i++) {
146145
val = set.remove(i);
147-
Assert.assertTrue(val)
146+
Assert.assertTrue(val);
148147
}
149148

150-
for (int i = 0; i < 100; i++) {
149+
for (int i = 0; i < 10; i++) {
151150
val = set.contains(i);
152-
Assert.assertFalse(val)
153-
}*/
151+
Assert.assertFalse(val);
152+
}
153+
154+
set.destroy();
155+
}
156+
157+
@Test(enabled = true)
158+
public void testAddRemoveSetStrings() {
159+
DurableType gtypes[] = {DurableType.STRING};
160+
DurableHashSet<String> set = DurableHashSetFactory.create(m_act, null, gtypes, initialCapacity, false);
161+
162+
Long handler = set.getHandler();
163+
boolean val;
164+
for (int i = 0; i < 10; i++) {
165+
val = set.add("str" + i);
166+
Assert.assertTrue(val);
167+
}
168+
169+
for (int i = 0; i < 10; i++) {
170+
val = set.contains("str" + i);
171+
Assert.assertTrue(val);
172+
}
173+
174+
for (int i = 0; i < 10; i++) {
175+
val = set.remove("str" + i);
176+
Assert.assertTrue(val);
177+
}
178+
179+
for (int i = 0; i < 10; i++) {
180+
val = set.contains("str" + i);
181+
Assert.assertFalse(val);
182+
}
183+
184+
set.destroy();
185+
}
186+
187+
@Test(enabled = true)
188+
public void testAddRemoveDurable() {
189+
DurableType gtypes[] = {DurableType.DURABLE};
190+
EntityFactoryProxy efproxies[] = {new EntityFactoryProxy() {
191+
@Override
192+
public <A extends RestorableAllocator<A>> Person<Long> restore(
193+
A allocator, EntityFactoryProxy[] factoryproxys,
194+
DurableType[] gfields, long phandler, boolean autoreclaim) {
195+
return PersonFactory.restore(allocator, factoryproxys, gfields, phandler, autoreclaim);
196+
}
197+
@Override
198+
public <A extends RestorableAllocator<A>> Person<Long> restore(ParameterHolder<A> ph) {
199+
return PersonFactory.restore(ph.getAllocator(),
200+
ph.getEntityFactoryProxies(), ph.getGenericTypes(), ph.getHandler(), ph.getAutoReclaim());
201+
}
202+
@Override
203+
public <A extends RestorableAllocator<A>> Person<Long> create(
204+
A allocator, EntityFactoryProxy[] factoryproxys,
205+
DurableType[] gfields, boolean autoreclaim) {
206+
return PersonFactory.create(allocator, factoryproxys, gfields, autoreclaim);
207+
}
208+
@Override
209+
public <A extends RestorableAllocator<A>> Person<Long> create(ParameterHolder<A> ph) {
210+
return PersonFactory.create(ph.getAllocator(),
211+
ph.getEntityFactoryProxies(), ph.getGenericTypes(), ph.getAutoReclaim());
212+
}
213+
} };
214+
215+
Person<Long> person = (Person<Long>) efproxies[0].create(m_act, null, null, false);
216+
person.setAge((short) 31);
217+
person.setName("Bob", true);
218+
219+
Person<Long> anotherPerson = (Person<Long>) efproxies[0].create(m_act, null, null, false);
220+
anotherPerson.setAge((short) 30);
221+
anotherPerson.setName("Alice", true);
222+
223+
DurableHashSet<Person<Long>> set = DurableHashSetFactory.create(m_act, efproxies, gtypes, initialCapacity, false);
224+
boolean val = set.add(person);
225+
AssertJUnit.assertTrue(val);
226+
val = set.contains(person);
227+
AssertJUnit.assertTrue(val);
228+
val = set.contains(anotherPerson);
229+
AssertJUnit.assertFalse(val);
230+
val = set.add(anotherPerson);
231+
AssertJUnit.assertTrue(val);
232+
val = set.contains(anotherPerson);
233+
AssertJUnit.assertTrue(val);
234+
235+
val = set.remove(person);
236+
AssertJUnit.assertTrue(val);
237+
val = set.contains(person);
238+
AssertJUnit.assertFalse(val);
239+
val = set.contains(anotherPerson);
240+
AssertJUnit.assertTrue(val);
241+
242+
val = set.remove(anotherPerson);
243+
AssertJUnit.assertTrue(val);
244+
val = set.contains(anotherPerson);
245+
AssertJUnit.assertFalse(val);
154246

155247
set.destroy();
156248
}
249+
250+
@Test(enabled = true)
251+
public void testSetIterator() {
252+
DurableType gtypes[] = {DurableType.STRING};
253+
DurableHashSet<String> set = DurableHashSetFactory.create(m_act, null, gtypes, initialCapacity, false);
254+
255+
Long handler = set.getHandler();
256+
set.add("hello");
257+
set.add("world");
258+
AssertJUnit.assertEquals(set.getSize(), 2);
259+
260+
Iterator<String> iter = set.iterator();
261+
int count = 0;
262+
String entry = "";
263+
while (iter.hasNext()) {
264+
entry = iter.next();
265+
count++;
266+
if (entry.equals("world")) {
267+
iter.remove();
268+
}
269+
}
270+
AssertJUnit.assertEquals(count, 2);
271+
AssertJUnit.assertEquals(set.getSize(), 1);
272+
iter = set.iterator();
273+
count = 0;
274+
while (iter.hasNext()) {
275+
entry = iter.next();
276+
iter.remove();
277+
count++;
278+
}
279+
AssertJUnit.assertEquals(count, 1);
280+
AssertJUnit.assertEquals(set.getSize(), 0);
281+
AssertJUnit.assertEquals(entry, "hello");
282+
283+
iter = set.iterator();
284+
count = 0;
285+
while (iter.hasNext()) {
286+
entry = iter.next();
287+
count++;
288+
}
289+
AssertJUnit.assertEquals(count, 0);
290+
set.add("hello");
291+
set.add("world");
292+
AssertJUnit.assertEquals(set.getSize(), 2);
293+
294+
iter = set.iterator();
295+
count = 0;
296+
while (iter.hasNext()) {
297+
entry = iter.next();
298+
count++;
299+
}
300+
AssertJUnit.assertEquals(count, 2);
301+
302+
set.destroy();
303+
}
304+
157305
}
158306

0 commit comments

Comments
 (0)