package com.jivesoftware.os.jive.utils.collections.lh; /** * * @author jonathan.colt */ public class ConcurrentLHash<V> { private final long capacity; private final long nilKey; private final long skipKey; private final LHash<V>[] maps; @SuppressWarnings("unchecked") public ConcurrentLHash(long capacity, long nilKey, long skipKey, int concurrency) { this.capacity = capacity; this.nilKey = nilKey; this.skipKey = skipKey; this.maps = new LHash[concurrency]; } public void put(long key, V value) { LHash<V> hmap = hmap(key, true); synchronized (hmap) { hmap.put(key, value); } } private LHash<V> hmap(long key, boolean create) { int index = Math.abs((Long.hashCode(key)) % maps.length); if (maps[index] == null && create) { synchronized (maps) { if (maps[index] == null) { maps[index] = new LHash<>(new LHMapState<>(capacity, nilKey, skipKey)); } } } return maps[index]; } public V get(long key) { LHash<V> hmap = hmap(key, false); if (hmap != null) { synchronized (hmap) { return hmap.get(key); } } return null; } public void remove(long key) { LHash<V> hmap = hmap(key, false); if (hmap != null) { synchronized (hmap) { hmap.remove(key); } } } public void clear() { for (LHash<V> hmap : maps) { if (hmap != null) { synchronized (hmap) { hmap.clear(); } } } } public int size() { int size = 0; for (LHash<V> hmap : maps) { if (hmap != null) { size += hmap.size(); } } return size; } public boolean stream(LHashValueStream<V> lHashValueStream) throws Exception { for (LHash<V> hmap : maps) { if (hmap != null) { if (!hmap.stream(lHashValueStream)) { return false; } } } return true; } }