/** Removes all of the mappings from this map. */ @Override public void clear() { // Smack a new empty table down Object[] newkvs = new NonBlockingIdentityHashMap(MIN_SIZE)._kvs; while( !CAS_kvs(_kvs,newkvs) ) // Spin until the clear works ; }
/** * Creates a shallow copy of this hashtable. All the structure of the * hashtable itself is copied, but the keys and values are not cloned. * This is a relatively expensive operation. * * @return a clone of the hashtable. */ @Override public Object clone() { try { // Must clone, to get the class right; NBHM might have been // extended so it would be wrong to just make a new NBHM. NonBlockingIdentityHashMap<TypeK,TypeV> t = (NonBlockingIdentityHashMap<TypeK,TypeV>) super.clone(); // But I don't have an atomic clone operation - the underlying _kvs // structure is undergoing rapid change. If I just clone the _kvs // field, the CHM in _kvs[0] won't be in sync. // // Wipe out the cloned array (it was shallow anyways). t.clear(); // Now copy sanely for( TypeK K : keySet() ) { final TypeV V = get(K); // Do an official 'get' t.put(K,V); } return t; } catch (CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable throw new InternalError(); } }
@Override public boolean contains( Object k ) { return NonBlockingIdentityHashMap.this.containsKey(k); } @Override public boolean remove ( Object k ) { return NonBlockingIdentityHashMap.this.remove (k) != null; }
private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject(); // Read nothing initialize(MIN_SIZE); for(;;) { final TypeK K = (TypeK) s.readObject(); final TypeV V = (TypeV) s.readObject(); if( K == null ) break; put(K,V); // Insert with an offical put } }
private void writeObject(java.io.ObjectOutputStream s) throws IOException { s.defaultWriteObject(); // Nothing to write for( Object K : keySet() ) { final Object V = get(K); // Do an official 'get' s.writeObject(K); // Write the <TypeK,TypeV> pair s.writeObject(V); } s.writeObject(null); // Sentinel to indicate end-of-data s.writeObject(null); }
assertTrue(_nbhm.isEmpty()); assertThat(_nbhm.putIfAbsent("k1", "v1"), nullValue()); checkSizes(1); assertThat(_nbhm.putIfAbsent("k2", "v2"), nullValue()); checkSizes(2); assertTrue(_nbhm.containsKey("k2")); assertThat(_nbhm.put("k1", "v1a"), is("v1")); assertThat(_nbhm.put("k2", "v2a"), is("v2")); checkSizes(2); assertThat(_nbhm.putIfAbsent("k2", "v2b"), is("v2a")); assertThat(_nbhm.remove("k1"), is("v1a")); assertFalse(_nbhm.containsKey("k1")); checkSizes(1); assertThat(_nbhm.remove("k1"), nullValue()); assertThat(_nbhm.remove("k2"), is("v2a")); checkSizes(0); assertThat(_nbhm.remove("k2"), nullValue()); assertThat(_nbhm.remove("k3"), nullValue()); assertTrue(_nbhm.isEmpty()); assertThat(_nbhm.put("k0", "v0"), nullValue()); assertTrue(_nbhm.containsKey("k0")); checkSizes(1); assertThat(_nbhm.remove("k0"), is("v0")); assertFalse(_nbhm.containsKey("k0")); checkSizes(0); assertThat(_nbhm.replace("k0", "v0"), nullValue()); assertFalse(_nbhm.containsKey("k0"));
@Test public void testIteration() { assertTrue(_nbhm.isEmpty()); assertThat(_nbhm.put("k1", "v1"), nullValue()); assertThat(_nbhm.put("k2", "v2"), nullValue()); String str1 = ""; for (Map.Entry<String, String> e : _nbhm.entrySet()) { str1 += e.getKey(); } assertThat("found all entries", str1, anyOf(is("k1k2"), is("k2k1"))); String str2 = ""; for (String key : _nbhm.keySet()) { str2 += key; } assertThat("found all keys", str2, anyOf(is("k1k2"), is("k2k1"))); String str3 = ""; for (String val : _nbhm.values()) { str3 += val; } assertThat("found all vals", str3, anyOf(is("v1v2"), is("v2v1"))); assertThat("toString works", _nbhm.toString(), anyOf(is("{k1=v1, k2=v2}"), is("{k2=v2, k1=v1}"))); _nbhm.clear(); }
String[] keys = new String[CNT]; String[] vals = new String[CNT]; assertThat(_nbhm.size(), is(0)); for (int i = 0; i < CNT; i++) _nbhm.put(keys[i] = ("k" + i), vals[i] = ("v" + i)); assertThat(_nbhm.size(), is(CNT)); for (String s : _nbhm.keySet()) assertThat("Found all integers in list", sum, is(CNT * (CNT - 1) / 2)); assertThat("can remove 3", _nbhm.remove(keys[3]), is(vals[3])); assertThat("can remove 4", _nbhm.remove(keys[4]), is(vals[4])); sz = 0; sum = 0; for (String s : _nbhm.keySet()) sum += x; assertTrue(x >= 0 && x <= (CNT - 1)); String v = _nbhm.get(s); assertThat("", v.charAt(0), is('v')); assertThat("", s.substring(1), is(v.substring(1))); _nbhm.clear();
@Test public void testSerial() assertTrue(_nbhm.isEmpty()); assertThat(_nbhm.put("k1", "v1"), nullValue()); assertThat(_nbhm.put("k2", "v2"), nullValue()); in.close(); assertEquals(_nbhm.size(), nbhm.size()); Object[] keys = nbhm.keySet().toArray(); if (keys[0].equals("k1")) assertEquals(nbhm.get(keys[0]), "v1"); assertEquals(nbhm.get(keys[1]), "v2"); assertEquals(nbhm.get(keys[1]), "v1"); assertEquals(nbhm.get(keys[0]), "v2"); _nbhm.clear();
@Test public void testIterationBig2() { final int CNT = 10000; NonBlockingIdentityHashMap<Integer, String> nbhm = new NonBlockingIdentityHashMap<>(); final String v = "v"; for (int i = 0; i < CNT; i++) { final Integer z = i; String s0 = nbhm.get(z); assertThat(s0, nullValue()); nbhm.put(z, v); String s1 = nbhm.get(z); assertThat(s1, is(v)); } assertThat(nbhm.size(), is(CNT)); _nbhm.clear(); }
@Test public final void testNonBlockingIdentityHashMapSize() NonBlockingIdentityHashMap<Long, String> items = new NonBlockingIdentityHashMap<>(); items.put(100L, "100"); items.put(101L, "101"); assertEquals("keySet().size()", 2, items.keySet().size()); assertTrue("keySet().contains(100)", items.keySet().contains(100L)); assertTrue("keySet().contains(101)", items.keySet().contains(101L)); assertEquals("values().size()", 2, items.values().size()); assertTrue("values().contains(\"100\")", items.values().contains("100")); assertTrue("values().contains(\"101\")", items.values().contains("101")); assertEquals("entrySet().size()", 2, items.entrySet().size()); boolean found100 = false; boolean found101 = false; for (Map.Entry<Long, String> entry : items.entrySet())
private void checkSizes(int expectedSize) { assertEquals("size()", _nbhm.size(), expectedSize); Collection<String> vals = _nbhm.values(); checkSizes("values()", vals.size(), vals.iterator(), expectedSize); Set<String> keys = _nbhm.keySet(); checkSizes("keySet()", keys.size(), keys.iterator(), expectedSize); Set<Map.Entry<String, String>> ents = _nbhm.entrySet(); checkSizes("entrySet()", ents.size(), ents.iterator(), expectedSize); }
final int ITEM_COUNT = PER_CNT * THREAD_COUNT; // fix roundoff for odd thread counts NonBlockingIdentityHashMap<Long, TestKey> nbhml = new NonBlockingIdentityHashMap<>(); assertEquals("values().size()", ITEM_COUNT, nbhml.values().size()); assertEquals("entrySet().size()", ITEM_COUNT, nbhml.entrySet().size()); int itemCount = 0; for (TestKey K : nbhml.values())
@Test public void testConcurrentSimple() throws InterruptedException final NonBlockingIdentityHashMap<String, String> nbhm = new NonBlockingIdentityHashMap<>(); final String[] keys = new String[20000]; for (int i = 0; i < 20000; i++) buf.append("Should be emptyset but has these elements: {"); boolean found = false; for (String x : nbhm.keySet()) assertThat("concurrent size=0", nbhm.size(), is(0)); assertThat("keySet size=0", nbhm.keySet().size(), is(0));
@Test public void testNonBlockingIdentityHashMapIteratorMultithreaded() throws InterruptedException, ExecutionException { TestKeyFeeder feeder = getTestKeyFeeder(); final int itemCount = feeder.size(); // validate results final NonBlockingIdentityHashMap<Long, TestKey> items = feeder.getMapMultithreaded(); assertEquals("size()", itemCount, items.size()); assertEquals("values().size()", itemCount, items.values().size()); assertEquals("entrySet().size()", itemCount, items.entrySet().size()); int iteratorCount = 0; for (TestKey m : items.values()) { iteratorCount++; } // sometimes a different result comes back the second time int iteratorCount2 = 0; for (TestKey m : items.values()) { iteratorCount2++; } assertEquals("iterator counts differ", iteratorCount, iteratorCount2); assertEquals("values().iterator() count", itemCount, iteratorCount); }
@Override public int size ( ) { return NonBlockingIdentityHashMap.this.size ( ); } @Override public boolean contains( Object v ) { return NonBlockingIdentityHashMap.this.containsValue(v); }
@Override public void clear ( ) { NonBlockingIdentityHashMap.this.clear ( ); } @Override public int size ( ) { return NonBlockingIdentityHashMap.this.size ( ); }
void work_helper(NonBlockingIdentityHashMap<String, String> nbhm, String thrd, int d, String[] keys) { final int ITERS = 20000; for (int j = 0; j < 10; j++) { //long start = System.nanoTime(); for (int i = d; i < ITERS; i += 2) { assertThat("this key not in there, so putIfAbsent must work", nbhm.putIfAbsent(keys[i], thrd), is((String) null)); } for (int i = d; i < ITERS; i += 2) { assertTrue(nbhm.remove(keys[i], thrd)); } //double delta_nanos = System.nanoTime()-start; //double delta_secs = delta_nanos/1000000000.0; //double ops = ITERS*2; //System.out.println("Thrd"+thrd+" "+(ops/delta_secs)+" ops/sec size="+nbhm.size()); } }
/** Copies all of the mappings from the specified map to this one, replacing * any existing mappings. * @param m mappings to be stored in this map */ @Override public void putAll(Map<? extends TypeK, ? extends TypeV> m) { for (Map.Entry<? extends TypeK, ? extends TypeV> e : m.entrySet()) put(e.getKey(), e.getValue()); }
/** Tests if the key in the table using the <tt>equals</tt> method. * @return <tt>true</tt> if the key is in the table using the <tt>equals</tt> method * @throws NullPointerException if the specified key is null */ @Override public boolean containsKey( Object key ) { return get(key) != null; }