Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/cache/test/UtilCacheTests.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/cache/test/UtilCacheTests.java?rev=1695126&r1=1695125&r2=1695126&view=diff ============================================================================== --- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/cache/test/UtilCacheTests.java (original) +++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/cache/test/UtilCacheTests.java Mon Aug 10 16:15:37 2015 @@ -1,436 +1,436 @@ -/******************************************************************************* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - *******************************************************************************/ -package org.ofbiz.base.util.cache.test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.greaterThan; - -import java.io.Serializable; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.ofbiz.base.test.GenericTestCaseBase; -import org.ofbiz.base.util.UtilMisc; -import org.ofbiz.base.util.UtilObject; -import org.ofbiz.base.util.cache.CacheListener; -import org.ofbiz.base.util.cache.UtilCache; - -@SuppressWarnings("serial") -public class UtilCacheTests extends GenericTestCaseBase implements Serializable { - public static final String module = UtilCacheTests.class.getName(); - - protected static abstract class Change<V> { - protected int count = 1; - } - - protected static final class Removal<V> extends Change<V> { - protected final V oldValue; - - protected Removal(V oldValue) { - this.oldValue = oldValue; - } - - @Override - public int hashCode() { - return UtilObject.doHashCode(oldValue); - } - - @Override - public boolean equals(Object o) { - if (o instanceof Removal<?>) { - Removal<?> other = (Removal<?>) o; - return UtilObject.equalsHelper(oldValue, other.oldValue); - } - return false; - } - } - - protected static final class Addition<V> extends Change<V> { - protected final V newValue; - - protected Addition(V newValue) { - this.newValue = newValue; - } - - @Override - public int hashCode() { - return UtilObject.doHashCode(newValue); - } - - @Override - public boolean equals(Object o) { - if (o instanceof Addition<?>) { - Addition<?> other = (Addition<?>) o; - return UtilObject.equalsHelper(newValue, other.newValue); - } - return false; - } - } - - protected static final class Update<V> extends Change<V> { - protected final V newValue; - protected final V oldValue; - - protected Update(V newValue, V oldValue) { - this.newValue = newValue; - this.oldValue = oldValue; - } - - @Override - public int hashCode() { - return UtilObject.doHashCode(newValue) ^ UtilObject.doHashCode(oldValue); - } - - @Override - public boolean equals(Object o) { - if (o instanceof Update<?>) { - Update<?> other = (Update<?>) o; - if (!UtilObject.equalsHelper(newValue, other.newValue)) { - return false; - } - return UtilObject.equalsHelper(oldValue, other.oldValue); - } - return false; - } - } - - protected static class Listener<K, V> implements CacheListener<K, V> { - protected Map<K, Set<Change<V>>> changeMap = new HashMap<K, Set<Change<V>>>(); - - private void add(K key, Change<V> change) { - Set<Change<V>> changeSet = changeMap.get(key); - if (changeSet == null) { - changeSet = new HashSet<Change<V>>(); - changeMap.put(key, changeSet); - } - for (Change<V> checkChange: changeSet) { - if (checkChange.equals(change)) { - checkChange.count++; - return; - } - } - changeSet.add(change); - } - - public synchronized void noteKeyRemoval(UtilCache<K, V> cache, K key, V oldValue) { - add(key, new Removal<V>(oldValue)); - } - - public synchronized void noteKeyAddition(UtilCache<K, V> cache, K key, V newValue) { - add(key, new Addition<V>(newValue)); - } - - public synchronized void noteKeyUpdate(UtilCache<K, V> cache, K key, V newValue, V oldValue) { - add(key, new Update<V>(newValue, oldValue)); - } - - @Override - public boolean equals(Object o) { - Listener<?, ?> other = (Listener<?, ?>) o; - return changeMap.equals(other.changeMap); - } - } - - private static <K, V> Listener<K, V> createListener(UtilCache<K, V> cache) { - Listener<K, V> listener = new Listener<K, V>(); - cache.addListener(listener); - return listener; - } - - public UtilCacheTests(String name) { - super(name); - } - - private <K, V> UtilCache<K, V> createUtilCache(int sizeLimit, int maxInMemory, long ttl, boolean useSoftReference, boolean useFileSystemStore) { - return UtilCache.createUtilCache(getClass().getName() + "." + getName(), sizeLimit, maxInMemory, ttl, useSoftReference, useFileSystemStore); - } - - private static <K, V> void assertUtilCacheSettings(UtilCache<K, V> cache, Integer sizeLimit, Integer maxInMemory, Long expireTime, Boolean useSoftReference, Boolean useFileSystemStore) { - if (sizeLimit != null) { - assertEquals(cache.getName() + ":sizeLimit", sizeLimit.intValue(), cache.getSizeLimit()); - } - if (maxInMemory != null) { - assertEquals(cache.getName() + ":maxInMemory", maxInMemory.intValue(), cache.getMaxInMemory()); - } - if (expireTime != null) { - assertEquals(cache.getName() + ":expireTime", expireTime.longValue(), cache.getExpireTime()); - } - if (useSoftReference != null) { - assertEquals(cache.getName() + ":useSoftReference", useSoftReference.booleanValue(), cache.getUseSoftReference()); - } - if (useFileSystemStore != null) { - assertEquals(cache.getName() + ":useFileSystemStore", useFileSystemStore.booleanValue(), cache.getUseFileSystemStore()); - } - assertEquals("initial empty", true, cache.isEmpty()); - assertEquals("empty keys", Collections.emptySet(), cache.getCacheLineKeys()); - assertEquals("empty values", Collections.emptyList(), cache.values()); - assertSame("find cache", cache, UtilCache.findCache(cache.getName())); - assertNotSame("new cache", cache, UtilCache.createUtilCache()); - } - - public void testCreateUtilCache() { - String name = getClass().getName() + "." + getName(); - assertUtilCacheSettings(UtilCache.createUtilCache(), null, null, null, null, null); - assertUtilCacheSettings(UtilCache.createUtilCache(name), null, null, null, null, null); - assertUtilCacheSettings(UtilCache.createUtilCache(name, false), null, null, null, Boolean.FALSE, null); - assertUtilCacheSettings(UtilCache.createUtilCache(name, true), null, null, null, Boolean.TRUE, null); - assertUtilCacheSettings(UtilCache.createUtilCache(5, 15000), 5, null, 15000L, null, null); - assertUtilCacheSettings(UtilCache.createUtilCache(name, 6, 16000), 6, null, 16000L, null, null); - assertUtilCacheSettings(UtilCache.createUtilCache(name, 7, 17000, false), 7, null, 17000L, Boolean.FALSE, null); - assertUtilCacheSettings(UtilCache.createUtilCache(name, 8, 18000, true), 8, null, 18000L, Boolean.TRUE, null); - assertUtilCacheSettings(UtilCache.createUtilCache(name, 9, 5, 19000, false, false), 9, 5, 19000L, Boolean.FALSE, null); - assertUtilCacheSettings(UtilCache.createUtilCache(name, 10, 6, 20000, false, true), 10, 6, 20000L, Boolean.FALSE, null); - assertUtilCacheSettings(UtilCache.createUtilCache(name, 11, 7, 21000, false, false, "a", "b"), 11, 7, 21000L, Boolean.FALSE, Boolean.FALSE); - assertUtilCacheSettings(UtilCache.createUtilCache(name, 12, 8, 22000, false, true, "c", "d"), 12, 8, 22000L, Boolean.FALSE, Boolean.TRUE); - } - - public static <K, V> void assertKey(String label, UtilCache<K, V> cache, K key, V value, V other, int size, Map<K, V> map) { - assertNull(label + ":get-empty", cache.get(key)); - assertFalse(label + ":containsKey-empty", cache.containsKey(key)); - V oldValue = cache.put(key, other); - assertTrue(label + ":containsKey-class", cache.containsKey(key)); - assertEquals(label + ":get-class", other, cache.get(key)); - assertNull(label + ":oldValue-class", oldValue); - assertEquals(label + ":size-class", size, cache.size()); - oldValue = cache.put(key, value); - assertTrue(label + ":containsKey-value", cache.containsKey(key)); - assertEquals(label + ":get-value", value, cache.get(key)); - assertEquals(label + ":oldValue-value", other, oldValue); - assertEquals(label + ":size-value", size, cache.size()); - map.put(key, value); - assertEquals(label + ":map-keys", map.keySet(), cache.getCacheLineKeys()); - assertEquals(label + ":map-values", map.values(), cache.values()); - } - - private static <K, V> void assertHasSingleKey(UtilCache<K, V> cache, K key, V value) { - assertFalse("is-empty", cache.isEmpty()); - assertEquals("size", 1, cache.size()); - assertTrue("found", cache.containsKey(key)); - assertTrue("validKey", UtilCache.validKey(cache.getName(), key)); - assertFalse("validKey", UtilCache.validKey(":::" + cache.getName(), key)); - assertEquals("get", value, cache.get(key)); - assertEquals("keys", new HashSet<K>(UtilMisc.toList(key)), cache.getCacheLineKeys()); - assertEquals("values", UtilMisc.toList(value), cache.values()); - } - - private static <K, V> void assertNoSingleKey(UtilCache<K, V> cache, K key) { - assertFalse("not-found", cache.containsKey(key)); - assertFalse("validKey", UtilCache.validKey(cache.getName(), key)); - assertNull("no-get", cache.get(key)); - assertNull("remove", cache.remove(key)); - assertTrue("is-empty", cache.isEmpty()); - assertEquals("size", 0, cache.size()); - assertEquals("keys", Collections.emptySet(), cache.getCacheLineKeys()); - assertEquals("values", Collections.emptyList(), cache.values()); - } - - private static void basicTest(UtilCache<String, String> cache) throws Exception { - Listener<String, String> gotListener = createListener(cache); - Listener<String, String> wantedListener = new Listener<String, String>(); - for (int i = 0; i < 2; i++) { - assertTrue("UtilCacheTable.keySet", UtilCache.getUtilCacheTableKeySet().contains(cache.getName())); - assertSame("UtilCache.findCache", cache, UtilCache.findCache(cache.getName())); - assertSame("UtilCache.getOrCreateUtilCache", cache, UtilCache.getOrCreateUtilCache(cache.getName(), cache.getSizeLimit(), cache.getMaxInMemory(), cache.getExpireTime(), cache.getUseSoftReference(), cache.getUseFileSystemStore())); - - assertNoSingleKey(cache, "one"); - long origByteSize = cache.getSizeInBytes(); - - wantedListener.noteKeyAddition(cache, null, "null"); - assertNull("put", cache.put(null, "null")); - assertHasSingleKey(cache, null, "null"); - long nullByteSize = cache.getSizeInBytes(); - assertThat(nullByteSize, greaterThan(origByteSize)); - - wantedListener.noteKeyRemoval(cache, null, "null"); - assertEquals("remove", "null", cache.remove(null)); - assertNoSingleKey(cache, null); - - wantedListener.noteKeyAddition(cache, "one", "uno"); - assertNull("put", cache.put("one", "uno")); - assertHasSingleKey(cache, "one", "uno"); - long unoByteSize = cache.getSizeInBytes(); - assertThat(unoByteSize, greaterThan(origByteSize)); - - wantedListener.noteKeyUpdate(cache, "one", "single", "uno"); - assertEquals("replace", "uno", cache.put("one", "single")); - assertHasSingleKey(cache, "one", "single"); - long singleByteSize = cache.getSizeInBytes(); - assertThat(singleByteSize, greaterThan(origByteSize)); - assertThat(singleByteSize, greaterThan(unoByteSize)); - - wantedListener.noteKeyRemoval(cache, "one", "single"); - assertEquals("remove", "single", cache.remove("one")); - assertNoSingleKey(cache, "one"); - assertEquals("byteSize", origByteSize, cache.getSizeInBytes()); - - wantedListener.noteKeyAddition(cache, "one", "uno"); - assertNull("put", cache.put("one", "uno")); - assertHasSingleKey(cache, "one", "uno"); - - wantedListener.noteKeyUpdate(cache, "one", "only", "uno"); - assertEquals("replace", "uno", cache.put("one", "only")); - assertHasSingleKey(cache, "one", "only"); - - wantedListener.noteKeyRemoval(cache, "one", "only"); - cache.erase(); - assertNoSingleKey(cache, "one"); - assertEquals("byteSize", origByteSize, cache.getSizeInBytes()); - - cache.setExpireTime(100); - wantedListener.noteKeyAddition(cache, "one", "uno"); - assertNull("put", cache.put("one", "uno")); - assertHasSingleKey(cache, "one", "uno"); - - wantedListener.noteKeyRemoval(cache, "one", "uno"); - Thread.sleep(200); - assertNoSingleKey(cache, "one"); - } - - assertEquals("get-miss", 10, cache.getMissCountNotFound()); - assertEquals("get-miss-total", 10, cache.getMissCountTotal()); - assertEquals("get-hit", 12, cache.getHitCount()); - assertEquals("remove-hit", 6, cache.getRemoveHitCount()); - assertEquals("remove-miss", 10, cache.getRemoveMissCount()); - cache.removeListener(gotListener); - assertEquals("listener", wantedListener, gotListener); - UtilCache.clearCache(cache.getName()); - UtilCache.clearCache(":::" + cache.getName()); - } - - public void testBasicDisk() throws Exception { - UtilCache<String, String> cache = createUtilCache(5, 0, 0, false, true); - basicTest(cache); - } - - public void testSimple() throws Exception { - UtilCache<String, String> cache = createUtilCache(5, 0, 0, false, false); - basicTest(cache); - } - - public void testPutIfAbsent() throws Exception { - UtilCache<String, String> cache = createUtilCache(5, 5, 2000, false, false); - Listener<String, String> gotListener = createListener(cache); - Listener<String, String> wantedListener = new Listener<String, String>(); - wantedListener.noteKeyAddition(cache, "two", "dos"); - assertNull("putIfAbsent", cache.putIfAbsent("two", "dos")); - assertHasSingleKey(cache, "two", "dos"); - assertEquals("putIfAbsent", "dos", cache.putIfAbsent("two", "double")); - assertHasSingleKey(cache, "two", "dos"); - cache.removeListener(gotListener); - assertEquals("listener", wantedListener, gotListener); - } - - public void testPutIfAbsentAndGet() throws Exception { - UtilCache<String, String> cache = createUtilCache(5, 5, 2000, false, false); - Listener<String, String> gotListener = createListener(cache); - Listener<String, String> wantedListener = new Listener<String, String>(); - wantedListener.noteKeyAddition(cache, "key", "value"); - wantedListener.noteKeyAddition(cache, "anotherKey", "anotherValue"); - assertNull("no-get", cache.get("key")); - assertEquals("putIfAbsentAndGet", "value", cache.putIfAbsentAndGet("key", "value")); - assertHasSingleKey(cache, "key", "value"); - assertEquals("putIfAbsentAndGet", "value", cache.putIfAbsentAndGet("key", "newValue")); - assertHasSingleKey(cache, "key", "value"); - String anotherValueAddedToCache = new String("anotherValue"); - String anotherValueNotAddedToCache = new String("anotherValue"); - assertEquals(anotherValueAddedToCache, anotherValueNotAddedToCache); - assertNotSame(anotherValueAddedToCache, anotherValueNotAddedToCache); - String cachedValue = cache.putIfAbsentAndGet("anotherKey", anotherValueAddedToCache); - assertSame(cachedValue, anotherValueAddedToCache); - cachedValue = cache.putIfAbsentAndGet("anotherKey", anotherValueNotAddedToCache); - assertNotSame(cachedValue, anotherValueNotAddedToCache); - assertSame(cachedValue, anotherValueAddedToCache); - cache.removeListener(gotListener); - assertEquals("listener", wantedListener, gotListener); - } - - public void testChangeMemSize() throws Exception { - int size = 5; - long ttl = 2000; - UtilCache<String, Serializable> cache = createUtilCache(size, size, ttl, false, false); - Map<String, Serializable> map = new HashMap<String, Serializable>(); - for (int i = 0; i < size; i++) { - String s = Integer.toString(i); - assertKey(s, cache, s, new String(s), new String(":" + s), i + 1, map); - } - cache.setMaxInMemory(2); - assertEquals("cache.size", 2, cache.size()); - map.keySet().retainAll(cache.getCacheLineKeys()); - assertEquals("map-keys", map.keySet(), cache.getCacheLineKeys()); - assertEquals("map-values", map.values(), cache.values()); - cache.setMaxInMemory(0); - assertEquals("map-keys", map.keySet(), cache.getCacheLineKeys()); - assertEquals("map-values", map.values(), cache.values()); - for (int i = size * 2; i < size * 3; i++) { - String s = Integer.toString(i); - assertKey(s, cache, s, new String(s), new String(":" + s), i - size * 2 + 3, map); - } - cache.setMaxInMemory(0); - assertEquals("map-keys", map.keySet(), cache.getCacheLineKeys()); - assertEquals("map-values", map.values(), cache.values()); - cache.setMaxInMemory(size); - for (int i = 0; i < size * 2; i++) { - map.remove(Integer.toString(i)); - } - // Can't compare the contents of these collections, as setting LRU after not - // having one, means the items that get evicted are essentially random. - assertEquals("map-keys", map.keySet().size(), cache.getCacheLineKeys().size()); - assertEquals("map-values", map.values().size(), cache.values().size()); - } - - private void expireTest(UtilCache<String, Serializable> cache, int size, long ttl) throws Exception { - Map<String, Serializable> map = new HashMap<String, Serializable>(); - for (int i = 0; i < size; i++) { - String s = Integer.toString(i); - assertKey(s, cache, s, new String(s), new String(":" + s), i + 1, map); - } - Thread.sleep(ttl + 500); - map.clear(); - for (int i = 0; i < size; i++) { - String s = Integer.toString(i); - assertNull("no-key(" + s + ")", cache.get(s)); - } - assertEquals("map-keys", map.keySet(), cache.getCacheLineKeys()); - assertEquals("map-values", map.values(), cache.values()); - for (int i = 0; i < size; i++) { - String s = Integer.toString(i); - assertKey(s, cache, s, new String(s), new String(":" + s), i + 1, map); - } - assertEquals("map-keys", map.keySet(), cache.getCacheLineKeys()); - assertEquals("map-values", map.values(), cache.values()); - } - - public void testExpire() throws Exception { - UtilCache<String, Serializable> cache = createUtilCache(5, 5, 2000, false, false); - expireTest(cache, 5, 2000); - long start = System.currentTimeMillis(); - useAllMemory(); - long end = System.currentTimeMillis(); - long ttl = end - start + 1000; - cache = createUtilCache(1, 1, ttl, true, false); - expireTest(cache, 1, ttl); - assertFalse("not empty", cache.isEmpty()); - useAllMemory(); - assertNull("not-key(0)", cache.get("0")); - assertTrue("empty", cache.isEmpty()); - } -} +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + *******************************************************************************/ +package org.ofbiz.base.util.cache.test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.greaterThan; + +import java.io.Serializable; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.ofbiz.base.test.GenericTestCaseBase; +import org.ofbiz.base.util.UtilMisc; +import org.ofbiz.base.util.UtilObject; +import org.ofbiz.base.util.cache.CacheListener; +import org.ofbiz.base.util.cache.UtilCache; + +@SuppressWarnings("serial") +public class UtilCacheTests extends GenericTestCaseBase implements Serializable { + public static final String module = UtilCacheTests.class.getName(); + + protected static abstract class Change<V> { + protected int count = 1; + } + + protected static final class Removal<V> extends Change<V> { + protected final V oldValue; + + protected Removal(V oldValue) { + this.oldValue = oldValue; + } + + @Override + public int hashCode() { + return UtilObject.doHashCode(oldValue); + } + + @Override + public boolean equals(Object o) { + if (o instanceof Removal<?>) { + Removal<?> other = (Removal<?>) o; + return UtilObject.equalsHelper(oldValue, other.oldValue); + } + return false; + } + } + + protected static final class Addition<V> extends Change<V> { + protected final V newValue; + + protected Addition(V newValue) { + this.newValue = newValue; + } + + @Override + public int hashCode() { + return UtilObject.doHashCode(newValue); + } + + @Override + public boolean equals(Object o) { + if (o instanceof Addition<?>) { + Addition<?> other = (Addition<?>) o; + return UtilObject.equalsHelper(newValue, other.newValue); + } + return false; + } + } + + protected static final class Update<V> extends Change<V> { + protected final V newValue; + protected final V oldValue; + + protected Update(V newValue, V oldValue) { + this.newValue = newValue; + this.oldValue = oldValue; + } + + @Override + public int hashCode() { + return UtilObject.doHashCode(newValue) ^ UtilObject.doHashCode(oldValue); + } + + @Override + public boolean equals(Object o) { + if (o instanceof Update<?>) { + Update<?> other = (Update<?>) o; + if (!UtilObject.equalsHelper(newValue, other.newValue)) { + return false; + } + return UtilObject.equalsHelper(oldValue, other.oldValue); + } + return false; + } + } + + protected static class Listener<K, V> implements CacheListener<K, V> { + protected Map<K, Set<Change<V>>> changeMap = new HashMap<K, Set<Change<V>>>(); + + private void add(K key, Change<V> change) { + Set<Change<V>> changeSet = changeMap.get(key); + if (changeSet == null) { + changeSet = new HashSet<Change<V>>(); + changeMap.put(key, changeSet); + } + for (Change<V> checkChange: changeSet) { + if (checkChange.equals(change)) { + checkChange.count++; + return; + } + } + changeSet.add(change); + } + + public synchronized void noteKeyRemoval(UtilCache<K, V> cache, K key, V oldValue) { + add(key, new Removal<V>(oldValue)); + } + + public synchronized void noteKeyAddition(UtilCache<K, V> cache, K key, V newValue) { + add(key, new Addition<V>(newValue)); + } + + public synchronized void noteKeyUpdate(UtilCache<K, V> cache, K key, V newValue, V oldValue) { + add(key, new Update<V>(newValue, oldValue)); + } + + @Override + public boolean equals(Object o) { + Listener<?, ?> other = (Listener<?, ?>) o; + return changeMap.equals(other.changeMap); + } + } + + private static <K, V> Listener<K, V> createListener(UtilCache<K, V> cache) { + Listener<K, V> listener = new Listener<K, V>(); + cache.addListener(listener); + return listener; + } + + public UtilCacheTests(String name) { + super(name); + } + + private <K, V> UtilCache<K, V> createUtilCache(int sizeLimit, int maxInMemory, long ttl, boolean useSoftReference, boolean useFileSystemStore) { + return UtilCache.createUtilCache(getClass().getName() + "." + getName(), sizeLimit, maxInMemory, ttl, useSoftReference, useFileSystemStore); + } + + private static <K, V> void assertUtilCacheSettings(UtilCache<K, V> cache, Integer sizeLimit, Integer maxInMemory, Long expireTime, Boolean useSoftReference, Boolean useFileSystemStore) { + if (sizeLimit != null) { + assertEquals(cache.getName() + ":sizeLimit", sizeLimit.intValue(), cache.getSizeLimit()); + } + if (maxInMemory != null) { + assertEquals(cache.getName() + ":maxInMemory", maxInMemory.intValue(), cache.getMaxInMemory()); + } + if (expireTime != null) { + assertEquals(cache.getName() + ":expireTime", expireTime.longValue(), cache.getExpireTime()); + } + if (useSoftReference != null) { + assertEquals(cache.getName() + ":useSoftReference", useSoftReference.booleanValue(), cache.getUseSoftReference()); + } + if (useFileSystemStore != null) { + assertEquals(cache.getName() + ":useFileSystemStore", useFileSystemStore.booleanValue(), cache.getUseFileSystemStore()); + } + assertEquals("initial empty", true, cache.isEmpty()); + assertEquals("empty keys", Collections.emptySet(), cache.getCacheLineKeys()); + assertEquals("empty values", Collections.emptyList(), cache.values()); + assertSame("find cache", cache, UtilCache.findCache(cache.getName())); + assertNotSame("new cache", cache, UtilCache.createUtilCache()); + } + + public void testCreateUtilCache() { + String name = getClass().getName() + "." + getName(); + assertUtilCacheSettings(UtilCache.createUtilCache(), null, null, null, null, null); + assertUtilCacheSettings(UtilCache.createUtilCache(name), null, null, null, null, null); + assertUtilCacheSettings(UtilCache.createUtilCache(name, false), null, null, null, Boolean.FALSE, null); + assertUtilCacheSettings(UtilCache.createUtilCache(name, true), null, null, null, Boolean.TRUE, null); + assertUtilCacheSettings(UtilCache.createUtilCache(5, 15000), 5, null, 15000L, null, null); + assertUtilCacheSettings(UtilCache.createUtilCache(name, 6, 16000), 6, null, 16000L, null, null); + assertUtilCacheSettings(UtilCache.createUtilCache(name, 7, 17000, false), 7, null, 17000L, Boolean.FALSE, null); + assertUtilCacheSettings(UtilCache.createUtilCache(name, 8, 18000, true), 8, null, 18000L, Boolean.TRUE, null); + assertUtilCacheSettings(UtilCache.createUtilCache(name, 9, 5, 19000, false, false), 9, 5, 19000L, Boolean.FALSE, null); + assertUtilCacheSettings(UtilCache.createUtilCache(name, 10, 6, 20000, false, true), 10, 6, 20000L, Boolean.FALSE, null); + assertUtilCacheSettings(UtilCache.createUtilCache(name, 11, 7, 21000, false, false, "a", "b"), 11, 7, 21000L, Boolean.FALSE, Boolean.FALSE); + assertUtilCacheSettings(UtilCache.createUtilCache(name, 12, 8, 22000, false, true, "c", "d"), 12, 8, 22000L, Boolean.FALSE, Boolean.TRUE); + } + + public static <K, V> void assertKey(String label, UtilCache<K, V> cache, K key, V value, V other, int size, Map<K, V> map) { + assertNull(label + ":get-empty", cache.get(key)); + assertFalse(label + ":containsKey-empty", cache.containsKey(key)); + V oldValue = cache.put(key, other); + assertTrue(label + ":containsKey-class", cache.containsKey(key)); + assertEquals(label + ":get-class", other, cache.get(key)); + assertNull(label + ":oldValue-class", oldValue); + assertEquals(label + ":size-class", size, cache.size()); + oldValue = cache.put(key, value); + assertTrue(label + ":containsKey-value", cache.containsKey(key)); + assertEquals(label + ":get-value", value, cache.get(key)); + assertEquals(label + ":oldValue-value", other, oldValue); + assertEquals(label + ":size-value", size, cache.size()); + map.put(key, value); + assertEquals(label + ":map-keys", map.keySet(), cache.getCacheLineKeys()); + assertEquals(label + ":map-values", map.values(), cache.values()); + } + + private static <K, V> void assertHasSingleKey(UtilCache<K, V> cache, K key, V value) { + assertFalse("is-empty", cache.isEmpty()); + assertEquals("size", 1, cache.size()); + assertTrue("found", cache.containsKey(key)); + assertTrue("validKey", UtilCache.validKey(cache.getName(), key)); + assertFalse("validKey", UtilCache.validKey(":::" + cache.getName(), key)); + assertEquals("get", value, cache.get(key)); + assertEquals("keys", new HashSet<K>(UtilMisc.toList(key)), cache.getCacheLineKeys()); + assertEquals("values", UtilMisc.toList(value), cache.values()); + } + + private static <K, V> void assertNoSingleKey(UtilCache<K, V> cache, K key) { + assertFalse("not-found", cache.containsKey(key)); + assertFalse("validKey", UtilCache.validKey(cache.getName(), key)); + assertNull("no-get", cache.get(key)); + assertNull("remove", cache.remove(key)); + assertTrue("is-empty", cache.isEmpty()); + assertEquals("size", 0, cache.size()); + assertEquals("keys", Collections.emptySet(), cache.getCacheLineKeys()); + assertEquals("values", Collections.emptyList(), cache.values()); + } + + private static void basicTest(UtilCache<String, String> cache) throws Exception { + Listener<String, String> gotListener = createListener(cache); + Listener<String, String> wantedListener = new Listener<String, String>(); + for (int i = 0; i < 2; i++) { + assertTrue("UtilCacheTable.keySet", UtilCache.getUtilCacheTableKeySet().contains(cache.getName())); + assertSame("UtilCache.findCache", cache, UtilCache.findCache(cache.getName())); + assertSame("UtilCache.getOrCreateUtilCache", cache, UtilCache.getOrCreateUtilCache(cache.getName(), cache.getSizeLimit(), cache.getMaxInMemory(), cache.getExpireTime(), cache.getUseSoftReference(), cache.getUseFileSystemStore())); + + assertNoSingleKey(cache, "one"); + long origByteSize = cache.getSizeInBytes(); + + wantedListener.noteKeyAddition(cache, null, "null"); + assertNull("put", cache.put(null, "null")); + assertHasSingleKey(cache, null, "null"); + long nullByteSize = cache.getSizeInBytes(); + assertThat(nullByteSize, greaterThan(origByteSize)); + + wantedListener.noteKeyRemoval(cache, null, "null"); + assertEquals("remove", "null", cache.remove(null)); + assertNoSingleKey(cache, null); + + wantedListener.noteKeyAddition(cache, "one", "uno"); + assertNull("put", cache.put("one", "uno")); + assertHasSingleKey(cache, "one", "uno"); + long unoByteSize = cache.getSizeInBytes(); + assertThat(unoByteSize, greaterThan(origByteSize)); + + wantedListener.noteKeyUpdate(cache, "one", "single", "uno"); + assertEquals("replace", "uno", cache.put("one", "single")); + assertHasSingleKey(cache, "one", "single"); + long singleByteSize = cache.getSizeInBytes(); + assertThat(singleByteSize, greaterThan(origByteSize)); + assertThat(singleByteSize, greaterThan(unoByteSize)); + + wantedListener.noteKeyRemoval(cache, "one", "single"); + assertEquals("remove", "single", cache.remove("one")); + assertNoSingleKey(cache, "one"); + assertEquals("byteSize", origByteSize, cache.getSizeInBytes()); + + wantedListener.noteKeyAddition(cache, "one", "uno"); + assertNull("put", cache.put("one", "uno")); + assertHasSingleKey(cache, "one", "uno"); + + wantedListener.noteKeyUpdate(cache, "one", "only", "uno"); + assertEquals("replace", "uno", cache.put("one", "only")); + assertHasSingleKey(cache, "one", "only"); + + wantedListener.noteKeyRemoval(cache, "one", "only"); + cache.erase(); + assertNoSingleKey(cache, "one"); + assertEquals("byteSize", origByteSize, cache.getSizeInBytes()); + + cache.setExpireTime(100); + wantedListener.noteKeyAddition(cache, "one", "uno"); + assertNull("put", cache.put("one", "uno")); + assertHasSingleKey(cache, "one", "uno"); + + wantedListener.noteKeyRemoval(cache, "one", "uno"); + Thread.sleep(200); + assertNoSingleKey(cache, "one"); + } + + assertEquals("get-miss", 10, cache.getMissCountNotFound()); + assertEquals("get-miss-total", 10, cache.getMissCountTotal()); + assertEquals("get-hit", 12, cache.getHitCount()); + assertEquals("remove-hit", 6, cache.getRemoveHitCount()); + assertEquals("remove-miss", 10, cache.getRemoveMissCount()); + cache.removeListener(gotListener); + assertEquals("listener", wantedListener, gotListener); + UtilCache.clearCache(cache.getName()); + UtilCache.clearCache(":::" + cache.getName()); + } + + public void testBasicDisk() throws Exception { + UtilCache<String, String> cache = createUtilCache(5, 0, 0, false, true); + basicTest(cache); + } + + public void testSimple() throws Exception { + UtilCache<String, String> cache = createUtilCache(5, 0, 0, false, false); + basicTest(cache); + } + + public void testPutIfAbsent() throws Exception { + UtilCache<String, String> cache = createUtilCache(5, 5, 2000, false, false); + Listener<String, String> gotListener = createListener(cache); + Listener<String, String> wantedListener = new Listener<String, String>(); + wantedListener.noteKeyAddition(cache, "two", "dos"); + assertNull("putIfAbsent", cache.putIfAbsent("two", "dos")); + assertHasSingleKey(cache, "two", "dos"); + assertEquals("putIfAbsent", "dos", cache.putIfAbsent("two", "double")); + assertHasSingleKey(cache, "two", "dos"); + cache.removeListener(gotListener); + assertEquals("listener", wantedListener, gotListener); + } + + public void testPutIfAbsentAndGet() throws Exception { + UtilCache<String, String> cache = createUtilCache(5, 5, 2000, false, false); + Listener<String, String> gotListener = createListener(cache); + Listener<String, String> wantedListener = new Listener<String, String>(); + wantedListener.noteKeyAddition(cache, "key", "value"); + wantedListener.noteKeyAddition(cache, "anotherKey", "anotherValue"); + assertNull("no-get", cache.get("key")); + assertEquals("putIfAbsentAndGet", "value", cache.putIfAbsentAndGet("key", "value")); + assertHasSingleKey(cache, "key", "value"); + assertEquals("putIfAbsentAndGet", "value", cache.putIfAbsentAndGet("key", "newValue")); + assertHasSingleKey(cache, "key", "value"); + String anotherValueAddedToCache = new String("anotherValue"); + String anotherValueNotAddedToCache = new String("anotherValue"); + assertEquals(anotherValueAddedToCache, anotherValueNotAddedToCache); + assertNotSame(anotherValueAddedToCache, anotherValueNotAddedToCache); + String cachedValue = cache.putIfAbsentAndGet("anotherKey", anotherValueAddedToCache); + assertSame(cachedValue, anotherValueAddedToCache); + cachedValue = cache.putIfAbsentAndGet("anotherKey", anotherValueNotAddedToCache); + assertNotSame(cachedValue, anotherValueNotAddedToCache); + assertSame(cachedValue, anotherValueAddedToCache); + cache.removeListener(gotListener); + assertEquals("listener", wantedListener, gotListener); + } + + public void testChangeMemSize() throws Exception { + int size = 5; + long ttl = 2000; + UtilCache<String, Serializable> cache = createUtilCache(size, size, ttl, false, false); + Map<String, Serializable> map = new HashMap<String, Serializable>(); + for (int i = 0; i < size; i++) { + String s = Integer.toString(i); + assertKey(s, cache, s, new String(s), new String(":" + s), i + 1, map); + } + cache.setMaxInMemory(2); + assertEquals("cache.size", 2, cache.size()); + map.keySet().retainAll(cache.getCacheLineKeys()); + assertEquals("map-keys", map.keySet(), cache.getCacheLineKeys()); + assertEquals("map-values", map.values(), cache.values()); + cache.setMaxInMemory(0); + assertEquals("map-keys", map.keySet(), cache.getCacheLineKeys()); + assertEquals("map-values", map.values(), cache.values()); + for (int i = size * 2; i < size * 3; i++) { + String s = Integer.toString(i); + assertKey(s, cache, s, new String(s), new String(":" + s), i - size * 2 + 3, map); + } + cache.setMaxInMemory(0); + assertEquals("map-keys", map.keySet(), cache.getCacheLineKeys()); + assertEquals("map-values", map.values(), cache.values()); + cache.setMaxInMemory(size); + for (int i = 0; i < size * 2; i++) { + map.remove(Integer.toString(i)); + } + // Can't compare the contents of these collections, as setting LRU after not + // having one, means the items that get evicted are essentially random. + assertEquals("map-keys", map.keySet().size(), cache.getCacheLineKeys().size()); + assertEquals("map-values", map.values().size(), cache.values().size()); + } + + private void expireTest(UtilCache<String, Serializable> cache, int size, long ttl) throws Exception { + Map<String, Serializable> map = new HashMap<String, Serializable>(); + for (int i = 0; i < size; i++) { + String s = Integer.toString(i); + assertKey(s, cache, s, new String(s), new String(":" + s), i + 1, map); + } + Thread.sleep(ttl + 500); + map.clear(); + for (int i = 0; i < size; i++) { + String s = Integer.toString(i); + assertNull("no-key(" + s + ")", cache.get(s)); + } + assertEquals("map-keys", map.keySet(), cache.getCacheLineKeys()); + assertEquals("map-values", map.values(), cache.values()); + for (int i = 0; i < size; i++) { + String s = Integer.toString(i); + assertKey(s, cache, s, new String(s), new String(":" + s), i + 1, map); + } + assertEquals("map-keys", map.keySet(), cache.getCacheLineKeys()); + assertEquals("map-values", map.values(), cache.values()); + } + + public void testExpire() throws Exception { + UtilCache<String, Serializable> cache = createUtilCache(5, 5, 2000, false, false); + expireTest(cache, 5, 2000); + long start = System.currentTimeMillis(); + useAllMemory(); + long end = System.currentTimeMillis(); + long ttl = end - start + 1000; + cache = createUtilCache(1, 1, ttl, true, false); + expireTest(cache, 1, ttl); + assertFalse("not empty", cache.isEmpty()); + useAllMemory(); + assertNull("not-key(0)", cache.get("0")); + assertTrue("empty", cache.isEmpty()); + } +} Propchange: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/cache/test/UtilCacheTests.java ('svn:eol-style' removed) Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMap.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMap.java?rev=1695126&r1=1695125&r2=1695126&view=diff ============================================================================== --- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMap.java (original) +++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMap.java Mon Aug 10 16:15:37 2015 @@ -1,253 +1,253 @@ -/*******n*********************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - *******************************************************************************/ -package org.ofbiz.base.util.collections; - -import java.io.Serializable; -import java.util.ConcurrentModificationException; -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; -import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; - -import org.ofbiz.base.lang.Appender; -import org.ofbiz.base.util.UtilGenerics; -import org.ofbiz.base.util.UtilObject; - -@SuppressWarnings("serial") -public abstract class GenericMap<K, V> implements Appender<StringBuilder>, Map<K, V>, Serializable { - private static final AtomicReferenceFieldUpdater<GenericMap<?, ?>, Set<?>> keySetUpdater = UtilGenerics.cast(AtomicReferenceFieldUpdater.newUpdater(GenericMap.class, Set.class, "keySet")); - private static final AtomicReferenceFieldUpdater<GenericMap<?, ?>, Set<?>> entrySetUpdater = UtilGenerics.cast(AtomicReferenceFieldUpdater.newUpdater(GenericMap.class, Set.class, "entrySet")); - private static final AtomicReferenceFieldUpdater<GenericMap<?, ?>, Collection<?>> valuesUpdater = UtilGenerics.cast(AtomicReferenceFieldUpdater.newUpdater(GenericMap.class, Collection.class, "values")); - private static final AtomicIntegerFieldUpdater<GenericMap<?, ?>> modCountUpdater = UtilGenerics.cast(AtomicIntegerFieldUpdater.newUpdater(GenericMap.class, "modCount")); - - private volatile Set<K> keySet; - private volatile Set<Map.Entry<K, V>> entrySet; - private volatile Collection<V> values; - private volatile int modCount; - - public int getModCount() { - return modCount; - } - - protected void incrementModCount() { - modCountUpdater.getAndIncrement(this); - } - - public final void clear() { - if (isEmpty()) return; - incrementModCount(); - clearInternal(); - } - - protected abstract void clearInternal(); - - public boolean containsValue(Object value) { - return values().contains(value); - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof Map<?, ?>)) return false; - if (this == o) return true; - Map<?, ?> map = (Map<?, ?>) o; - if (size() != map.size()) return false; - if (o instanceof GenericMap<?, ?>) return equalsGenericMap((GenericMap<?, ?>) o); - return equalsMap(map); - } - - protected boolean equalsGenericMap(GenericMap<?, ?> map) { - Iterator<Map.Entry<K, V>> it = iterator(false); - while (it.hasNext()) { - Map.Entry<K, V> entry = it.next(); - K key = entry.getKey(); - V value = entry.getValue(); - if (value != null) { - if (!value.equals(map.get(key, false))) return false; - } else { - Object otherValue = map.get(key, false); - if (otherValue != null) return false; - if (!map.containsKey(key)) return false; - } - } - return true; - } - - protected boolean equalsMap(Map<?, ?> map) { - Iterator<Map.Entry<K, V>> it = iterator(false); - while (it.hasNext()) { - Map.Entry<K, V> entry = it.next(); - K key = entry.getKey(); - V value = entry.getValue(); - if (value != null) { - if (!value.equals(map.get(key))) return false; - } else { - Object otherValue = map.get(key); - if (otherValue != null) return false; - if (!map.containsKey(key)) return false; - } - } - return true; - } - - public final V get(Object key) { - return get(key, true); - } - - protected abstract V get(Object key, boolean noteAccess); - - protected abstract class GenericMapIterator<DEST> extends IteratorWrapper<DEST, Map.Entry<K, V>> { - private final int currentModCount = getModCount(); - - protected GenericMapIterator(boolean noteAccess) { - super(iterator(noteAccess)); - } - - protected boolean isValid(Map.Entry<K, V> src) { - if (currentModCount != getModCount()) throw new ConcurrentModificationException(); - return true; - } - } - - public final Set<Map.Entry<K, V>> entrySet() { - if (entrySet == null) { - entrySetUpdater.compareAndSet(this, null, new GenericMapEntrySet<K, V, GenericMap<K, V>>(this) { - @Override - protected boolean contains(Object key, Object value) { - return UtilObject.equalsHelper(get(key, false), value); - } - - @Override - public Iterator<Map.Entry<K, V>> iterator(boolean noteAccess) { - return new GenericMapIterator<Map.Entry<K, V>>(noteAccess) { - @Override - protected void noteRemoval(Map.Entry<K, V> dest, Map.Entry<K, V> src) { - // No need to note the remove, the wrapped iterator does that for us - // evictionPolicy.remove(evictionDeque, dest); - // if (diskStore != null) diskStore.remove(dest); - } - - @Override - protected Map.Entry<K, V> convert(Map.Entry<K, V> src) { - return src; - } - }; - } - }); - } - return entrySet; - } - - protected abstract Iterator<Map.Entry<K, V>> iterator(boolean noteAccess); - - public final Set<K> keySet() { - if (keySet == null) { - keySetUpdater.compareAndSet(this, null, new GenericMapKeySet<K, V, GenericMap<K, V>>(this) { - public boolean contains(Object key) { - return containsKey(key); - } - - @Override - public Iterator<K> iterator(boolean noteAccess) { - return new GenericMapIterator<K>(noteAccess) { - @Override - protected void noteRemoval(K dest, Map.Entry<K, V> src) { - // No need to note the remove, the wrapped iterator does that for us - // evictionPolicy.remove(evictionDeque, dest); - // if (diskStore != null) diskStore.remove(dest); - } - - @Override - protected K convert(Map.Entry<K, V> src) { - return src.getKey(); - } - }; - } - }); - } - return keySet; - } - - public final Collection<V> values() { - if (values == null) { - valuesUpdater.compareAndSet(this, null, new GenericMapValues<K, V, GenericMap<K, V>>(this) { - @Override - public Iterator<V> iterator(boolean noteAccess) { - return new GenericMapIterator<V>(noteAccess) { - @Override - protected void noteRemoval(V dest, Map.Entry<K, V> src) { - // No need to note the remove, the wrapped iterator does that for us - // evictionPolicy.remove(evictionDeque, src.getKey()); - // if (diskStore != null) diskStore.remove(src.getKey()); - } - - @Override - protected V convert(Map.Entry<K, V> src) { - return src.getValue(); - } - }; - } - }); - } - return values; - } - - public final V remove(Object key) { - return removeInternal(key, true); - } - - protected abstract V removeInternal(Object key, boolean incrementModCount); - - public final void putAll(Map<? extends K, ? extends V> map) { - putAllInternal(map); - } - - private <KE extends K, VE extends V> void putAllInternal(Map<KE, VE> map) { - if (map.isEmpty()) return; - incrementModCount(); - Iterator<Map.Entry<KE, VE>> it; - if (map instanceof GenericMap<?, ?>) { - GenericMap<KE, VE> otherMap = UtilGenerics.cast(map); - it = otherMap.iterator(false); - } else { - it = map.entrySet().iterator(); - } - putAllIterator(it); - } - - protected abstract <KE extends K, VE extends V> void putAllIterator(Iterator<Map.Entry<KE, VE>> it); - - @Override - public String toString() { - return appendTo(new StringBuilder()).toString(); - } - - public StringBuilder appendTo(StringBuilder sb) { - sb.append("{"); - Iterator<Map.Entry<K, V>> it = iterator(false); - while (it.hasNext()) { - Map.Entry<K, V> entry = it.next(); - sb.append(entry.getKey()).append("=").append(entry.getValue()); - if (it.hasNext()) sb.append(","); - } - return sb.append("}"); - } -} - +/*******n*********************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + *******************************************************************************/ +package org.ofbiz.base.util.collections; + +import java.io.Serializable; +import java.util.ConcurrentModificationException; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; + +import org.ofbiz.base.lang.Appender; +import org.ofbiz.base.util.UtilGenerics; +import org.ofbiz.base.util.UtilObject; + +@SuppressWarnings("serial") +public abstract class GenericMap<K, V> implements Appender<StringBuilder>, Map<K, V>, Serializable { + private static final AtomicReferenceFieldUpdater<GenericMap<?, ?>, Set<?>> keySetUpdater = UtilGenerics.cast(AtomicReferenceFieldUpdater.newUpdater(GenericMap.class, Set.class, "keySet")); + private static final AtomicReferenceFieldUpdater<GenericMap<?, ?>, Set<?>> entrySetUpdater = UtilGenerics.cast(AtomicReferenceFieldUpdater.newUpdater(GenericMap.class, Set.class, "entrySet")); + private static final AtomicReferenceFieldUpdater<GenericMap<?, ?>, Collection<?>> valuesUpdater = UtilGenerics.cast(AtomicReferenceFieldUpdater.newUpdater(GenericMap.class, Collection.class, "values")); + private static final AtomicIntegerFieldUpdater<GenericMap<?, ?>> modCountUpdater = UtilGenerics.cast(AtomicIntegerFieldUpdater.newUpdater(GenericMap.class, "modCount")); + + private volatile Set<K> keySet; + private volatile Set<Map.Entry<K, V>> entrySet; + private volatile Collection<V> values; + private volatile int modCount; + + public int getModCount() { + return modCount; + } + + protected void incrementModCount() { + modCountUpdater.getAndIncrement(this); + } + + public final void clear() { + if (isEmpty()) return; + incrementModCount(); + clearInternal(); + } + + protected abstract void clearInternal(); + + public boolean containsValue(Object value) { + return values().contains(value); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Map<?, ?>)) return false; + if (this == o) return true; + Map<?, ?> map = (Map<?, ?>) o; + if (size() != map.size()) return false; + if (o instanceof GenericMap<?, ?>) return equalsGenericMap((GenericMap<?, ?>) o); + return equalsMap(map); + } + + protected boolean equalsGenericMap(GenericMap<?, ?> map) { + Iterator<Map.Entry<K, V>> it = iterator(false); + while (it.hasNext()) { + Map.Entry<K, V> entry = it.next(); + K key = entry.getKey(); + V value = entry.getValue(); + if (value != null) { + if (!value.equals(map.get(key, false))) return false; + } else { + Object otherValue = map.get(key, false); + if (otherValue != null) return false; + if (!map.containsKey(key)) return false; + } + } + return true; + } + + protected boolean equalsMap(Map<?, ?> map) { + Iterator<Map.Entry<K, V>> it = iterator(false); + while (it.hasNext()) { + Map.Entry<K, V> entry = it.next(); + K key = entry.getKey(); + V value = entry.getValue(); + if (value != null) { + if (!value.equals(map.get(key))) return false; + } else { + Object otherValue = map.get(key); + if (otherValue != null) return false; + if (!map.containsKey(key)) return false; + } + } + return true; + } + + public final V get(Object key) { + return get(key, true); + } + + protected abstract V get(Object key, boolean noteAccess); + + protected abstract class GenericMapIterator<DEST> extends IteratorWrapper<DEST, Map.Entry<K, V>> { + private final int currentModCount = getModCount(); + + protected GenericMapIterator(boolean noteAccess) { + super(iterator(noteAccess)); + } + + protected boolean isValid(Map.Entry<K, V> src) { + if (currentModCount != getModCount()) throw new ConcurrentModificationException(); + return true; + } + } + + public final Set<Map.Entry<K, V>> entrySet() { + if (entrySet == null) { + entrySetUpdater.compareAndSet(this, null, new GenericMapEntrySet<K, V, GenericMap<K, V>>(this) { + @Override + protected boolean contains(Object key, Object value) { + return UtilObject.equalsHelper(get(key, false), value); + } + + @Override + public Iterator<Map.Entry<K, V>> iterator(boolean noteAccess) { + return new GenericMapIterator<Map.Entry<K, V>>(noteAccess) { + @Override + protected void noteRemoval(Map.Entry<K, V> dest, Map.Entry<K, V> src) { + // No need to note the remove, the wrapped iterator does that for us + // evictionPolicy.remove(evictionDeque, dest); + // if (diskStore != null) diskStore.remove(dest); + } + + @Override + protected Map.Entry<K, V> convert(Map.Entry<K, V> src) { + return src; + } + }; + } + }); + } + return entrySet; + } + + protected abstract Iterator<Map.Entry<K, V>> iterator(boolean noteAccess); + + public final Set<K> keySet() { + if (keySet == null) { + keySetUpdater.compareAndSet(this, null, new GenericMapKeySet<K, V, GenericMap<K, V>>(this) { + public boolean contains(Object key) { + return containsKey(key); + } + + @Override + public Iterator<K> iterator(boolean noteAccess) { + return new GenericMapIterator<K>(noteAccess) { + @Override + protected void noteRemoval(K dest, Map.Entry<K, V> src) { + // No need to note the remove, the wrapped iterator does that for us + // evictionPolicy.remove(evictionDeque, dest); + // if (diskStore != null) diskStore.remove(dest); + } + + @Override + protected K convert(Map.Entry<K, V> src) { + return src.getKey(); + } + }; + } + }); + } + return keySet; + } + + public final Collection<V> values() { + if (values == null) { + valuesUpdater.compareAndSet(this, null, new GenericMapValues<K, V, GenericMap<K, V>>(this) { + @Override + public Iterator<V> iterator(boolean noteAccess) { + return new GenericMapIterator<V>(noteAccess) { + @Override + protected void noteRemoval(V dest, Map.Entry<K, V> src) { + // No need to note the remove, the wrapped iterator does that for us + // evictionPolicy.remove(evictionDeque, src.getKey()); + // if (diskStore != null) diskStore.remove(src.getKey()); + } + + @Override + protected V convert(Map.Entry<K, V> src) { + return src.getValue(); + } + }; + } + }); + } + return values; + } + + public final V remove(Object key) { + return removeInternal(key, true); + } + + protected abstract V removeInternal(Object key, boolean incrementModCount); + + public final void putAll(Map<? extends K, ? extends V> map) { + putAllInternal(map); + } + + private <KE extends K, VE extends V> void putAllInternal(Map<KE, VE> map) { + if (map.isEmpty()) return; + incrementModCount(); + Iterator<Map.Entry<KE, VE>> it; + if (map instanceof GenericMap<?, ?>) { + GenericMap<KE, VE> otherMap = UtilGenerics.cast(map); + it = otherMap.iterator(false); + } else { + it = map.entrySet().iterator(); + } + putAllIterator(it); + } + + protected abstract <KE extends K, VE extends V> void putAllIterator(Iterator<Map.Entry<KE, VE>> it); + + @Override + public String toString() { + return appendTo(new StringBuilder()).toString(); + } + + public StringBuilder appendTo(StringBuilder sb) { + sb.append("{"); + Iterator<Map.Entry<K, V>> it = iterator(false); + while (it.hasNext()) { + Map.Entry<K, V> entry = it.next(); + sb.append(entry.getKey()).append("=").append(entry.getValue()); + if (it.hasNext()) sb.append(","); + } + return sb.append("}"); + } +} + Propchange: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMap.java ('svn:eol-style' removed) Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapCollection.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapCollection.java?rev=1695126&r1=1695125&r2=1695126&view=diff ============================================================================== --- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapCollection.java (original) +++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapCollection.java Mon Aug 10 16:15:37 2015 @@ -1,121 +1,121 @@ -/******************************************************************************* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - *******************************************************************************/ -package org.ofbiz.base.util.collections; - -import java.util.Collection; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -public abstract class GenericMapCollection<K, V, M extends Map<K, V>, I> implements Collection<I> { - protected final M source; - - public GenericMapCollection(M source) { - this.source = source; - } - - public boolean add(I item) { - throw new UnsupportedOperationException(); - } - - public boolean addAll(Collection<? extends I> collection) { - throw new UnsupportedOperationException(); - } - - public void clear() { - source.clear(); - } - - public boolean containsAll(Collection<?> collection) { - for (Object item: collection) { - if (!contains(item)) return false; - } - return true; - } - - public boolean isEmpty() { - return source.isEmpty(); - } - - public final Iterator<I> iterator() { - return iterator(true); - } - - protected abstract Iterator<I> iterator(boolean noteAccess); - - public boolean removeAll(Collection<?> collection) { - int count = 0; - for (Object item: collection) { - if (remove(item)) count++; - } - return count > 0; - } - - public boolean retainAll(Collection<?> collection) { - int count = 0; - Iterator<I> it = iterator(false); - while (it.hasNext()) { - I item = it.next(); - if (!collection.contains(item)) { - it.remove(); - count++; - } - } - return count > 0; - } - - public int size() { - return source.size(); - } - - public Object[] toArray() { - List<I> list = new LinkedList<I>(); - Iterator<I> it = iterator(false); - while (it.hasNext()) { - list.add(it.next()); - } - return list.toArray(); - } - - public <T> T[] toArray(T[] array) { - List<Object> list = new LinkedList<Object>(); - Iterator<I> it = iterator(false); - while (it.hasNext()) { - list.add(it.next()); - } - return list.toArray(array); - } - - @Override - public String toString() { - return appendTo(new StringBuilder()).toString(); - } - - public StringBuilder appendTo(StringBuilder sb) { - sb.append("["); - Iterator<I> it = iterator(false); - while (it.hasNext()) { - sb.append(it.next()); - if (it.hasNext()) sb.append(", "); - } - return sb.append("]"); - } -} - +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + *******************************************************************************/ +package org.ofbiz.base.util.collections; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +public abstract class GenericMapCollection<K, V, M extends Map<K, V>, I> implements Collection<I> { + protected final M source; + + public GenericMapCollection(M source) { + this.source = source; + } + + public boolean add(I item) { + throw new UnsupportedOperationException(); + } + + public boolean addAll(Collection<? extends I> collection) { + throw new UnsupportedOperationException(); + } + + public void clear() { + source.clear(); + } + + public boolean containsAll(Collection<?> collection) { + for (Object item: collection) { + if (!contains(item)) return false; + } + return true; + } + + public boolean isEmpty() { + return source.isEmpty(); + } + + public final Iterator<I> iterator() { + return iterator(true); + } + + protected abstract Iterator<I> iterator(boolean noteAccess); + + public boolean removeAll(Collection<?> collection) { + int count = 0; + for (Object item: collection) { + if (remove(item)) count++; + } + return count > 0; + } + + public boolean retainAll(Collection<?> collection) { + int count = 0; + Iterator<I> it = iterator(false); + while (it.hasNext()) { + I item = it.next(); + if (!collection.contains(item)) { + it.remove(); + count++; + } + } + return count > 0; + } + + public int size() { + return source.size(); + } + + public Object[] toArray() { + List<I> list = new LinkedList<I>(); + Iterator<I> it = iterator(false); + while (it.hasNext()) { + list.add(it.next()); + } + return list.toArray(); + } + + public <T> T[] toArray(T[] array) { + List<Object> list = new LinkedList<Object>(); + Iterator<I> it = iterator(false); + while (it.hasNext()) { + list.add(it.next()); + } + return list.toArray(array); + } + + @Override + public String toString() { + return appendTo(new StringBuilder()).toString(); + } + + public StringBuilder appendTo(StringBuilder sb) { + sb.append("["); + Iterator<I> it = iterator(false); + while (it.hasNext()) { + sb.append(it.next()); + if (it.hasNext()) sb.append(", "); + } + return sb.append("]"); + } +} + Propchange: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapCollection.java ('svn:eol-style' removed) Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapEntry.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapEntry.java?rev=1695126&r1=1695125&r2=1695126&view=diff ============================================================================== --- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapEntry.java (original) +++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapEntry.java Mon Aug 10 16:15:37 2015 @@ -1,60 +1,60 @@ -/******************************************************************************* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - *******************************************************************************/ -package org.ofbiz.base.util.collections; - -import java.util.Map; - -import org.ofbiz.base.util.UtilObject; - -public class GenericMapEntry<K, V> implements Map.Entry<K, V> { - protected final GenericMap<K, V> map; - protected final K key; - protected final boolean noteAccess; - - public GenericMapEntry(GenericMap<K, V> map, K key, boolean noteAccess) { - this.map = map; - this.key = key; - this.noteAccess = noteAccess; - } - - public K getKey() { - return key; - } - - public V getValue() { - return map.get(key, noteAccess); - } - - public V setValue(V value) { - return map.put(key, value); - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof Map.Entry<?, ?>)) return false; - if (this == o) return true; - Map.Entry<?, ?> other = (Map.Entry<?, ?>) o; - return UtilObject.equalsHelper(getKey(), other.getKey()) && UtilObject.equalsHelper(getValue(), other.getValue()); - } - - @Override - public int hashCode() { - return UtilObject.doHashCode(getKey()) ^ UtilObject.doHashCode(getValue()); - } -} +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + *******************************************************************************/ +package org.ofbiz.base.util.collections; + +import java.util.Map; + +import org.ofbiz.base.util.UtilObject; + +public class GenericMapEntry<K, V> implements Map.Entry<K, V> { + protected final GenericMap<K, V> map; + protected final K key; + protected final boolean noteAccess; + + public GenericMapEntry(GenericMap<K, V> map, K key, boolean noteAccess) { + this.map = map; + this.key = key; + this.noteAccess = noteAccess; + } + + public K getKey() { + return key; + } + + public V getValue() { + return map.get(key, noteAccess); + } + + public V setValue(V value) { + return map.put(key, value); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Map.Entry<?, ?>)) return false; + if (this == o) return true; + Map.Entry<?, ?> other = (Map.Entry<?, ?>) o; + return UtilObject.equalsHelper(getKey(), other.getKey()) && UtilObject.equalsHelper(getValue(), other.getValue()); + } + + @Override + public int hashCode() { + return UtilObject.doHashCode(getKey()) ^ UtilObject.doHashCode(getValue()); + } +} Propchange: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapEntry.java ('svn:eol-style' removed) Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapEntrySet.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapEntrySet.java?rev=1695126&r1=1695125&r2=1695126&view=diff ============================================================================== --- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapEntrySet.java (original) +++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapEntrySet.java Mon Aug 10 16:15:37 2015 @@ -1,47 +1,47 @@ -/******************************************************************************* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - *******************************************************************************/ -package org.ofbiz.base.util.collections; - -import java.util.Map; - -public abstract class GenericMapEntrySet<K, V, M extends GenericMap<K, V>> extends GenericMapSet<K, V, M, Map.Entry<K, V>> { - public GenericMapEntrySet(M source) { - super(source); - } - - public boolean contains(Object item) { - if (item == null) return false; - if (!(item instanceof Map.Entry<?, ?>)) return false; - Map.Entry<?, ?> other = (Map.Entry<?, ?>) item; - return contains(other.getKey(), other.getValue()); - } - - protected abstract boolean contains(Object key, Object value); - - public boolean remove(Object item) { - if (item == null) return false; - if (!(item instanceof Map.Entry<?, ?>)) return false; - Map.Entry<?, ?> other = (Map.Entry<?, ?>) item; - Object key = other.getKey(); - if (!source.containsKey(key)) return false; - source.remove(key); - return true; - } -} - +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + *******************************************************************************/ +package org.ofbiz.base.util.collections; + +import java.util.Map; + +public abstract class GenericMapEntrySet<K, V, M extends GenericMap<K, V>> extends GenericMapSet<K, V, M, Map.Entry<K, V>> { + public GenericMapEntrySet(M source) { + super(source); + } + + public boolean contains(Object item) { + if (item == null) return false; + if (!(item instanceof Map.Entry<?, ?>)) return false; + Map.Entry<?, ?> other = (Map.Entry<?, ?>) item; + return contains(other.getKey(), other.getValue()); + } + + protected abstract boolean contains(Object key, Object value); + + public boolean remove(Object item) { + if (item == null) return false; + if (!(item instanceof Map.Entry<?, ?>)) return false; + Map.Entry<?, ?> other = (Map.Entry<?, ?>) item; + Object key = other.getKey(); + if (!source.containsKey(key)) return false; + source.remove(key); + return true; + } +} + Propchange: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapEntrySet.java ('svn:eol-style' removed) Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapKeySet.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapKeySet.java?rev=1695126&r1=1695125&r2=1695126&view=diff ============================================================================== --- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapKeySet.java (original) +++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapKeySet.java Mon Aug 10 16:15:37 2015 @@ -1,32 +1,32 @@ -/******************************************************************************* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - *******************************************************************************/ -package org.ofbiz.base.util.collections; - -import java.util.Map; - -public abstract class GenericMapKeySet<K, V, M extends Map<K, V>> extends GenericMapSet<K, V, M, K> { - public GenericMapKeySet(M source) { - super(source); - } - - public boolean remove(Object item) { - return source.remove(item) != null; - } -} - +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + *******************************************************************************/ +package org.ofbiz.base.util.collections; + +import java.util.Map; + +public abstract class GenericMapKeySet<K, V, M extends Map<K, V>> extends GenericMapSet<K, V, M, K> { + public GenericMapKeySet(M source) { + super(source); + } + + public boolean remove(Object item) { + return source.remove(item) != null; + } +} + Propchange: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapKeySet.java ('svn:eol-style' removed) Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapSet.java URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapSet.java?rev=1695126&r1=1695125&r2=1695126&view=diff ============================================================================== --- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapSet.java (original) +++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapSet.java Mon Aug 10 16:15:37 2015 @@ -1,50 +1,50 @@ -/******************************************************************************* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - *******************************************************************************/ -package org.ofbiz.base.util.collections; - -import java.util.Map; -import java.util.Set; - -public abstract class GenericMapSet<K, V, M extends Map<K, V>, I> extends GenericMapCollection<K, V, M, I> implements Set<I> { - public GenericMapSet(M source) { - super(source); - } - - @Override - public final boolean equals(Object o) { - if (!(o instanceof Set<?>)) return false; - Set<?> other = (Set<?>) o; - if (source.size() != other.size()) return false; - for (I item: this) { - if (!other.contains(item)) return false; - } - return true; - } - - @Override - public final int hashCode() { - int h = 0; - for (I item: this) { - if (item == null) continue; - h += item.hashCode(); - } - return h; - } -} - +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + *******************************************************************************/ +package org.ofbiz.base.util.collections; + +import java.util.Map; +import java.util.Set; + +public abstract class GenericMapSet<K, V, M extends Map<K, V>, I> extends GenericMapCollection<K, V, M, I> implements Set<I> { + public GenericMapSet(M source) { + super(source); + } + + @Override + public final boolean equals(Object o) { + if (!(o instanceof Set<?>)) return false; + Set<?> other = (Set<?>) o; + if (source.size() != other.size()) return false; + for (I item: this) { + if (!other.contains(item)) return false; + } + return true; + } + + @Override + public final int hashCode() { + int h = 0; + for (I item: this) { + if (item == null) continue; + h += item.hashCode(); + } + return h; + } +} + Propchange: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/collections/GenericMapSet.java ('svn:eol-style' removed) |
Free forum by Nabble | Edit this page |