package org.simpleflatmapper.map; import org.simpleflatmapper.map.mapper.MapperKey; import java.util.Arrays; import java.util.concurrent.atomic.AtomicReference; public final class ArrayMapperCache<K extends FieldKey<K>, M> implements IMapperCache<K, M> { @SuppressWarnings("unchecked") private final AtomicReference<CacheEntry<K, M>[]> mapperCache = new AtomicReference<CacheEntry<K, M>[]>(new CacheEntry[0]); private static final class CacheEntry<K extends FieldKey<K>, M> { final MapperKey<K> key; final M mapper; CacheEntry(final MapperKey<K> key, final M mapper) { this.key = key; this.mapper = mapper; } @Override public String toString() { return "{" + key + "," + mapper + '}'; } } @Override @SuppressWarnings("unchecked") public void add(final MapperKey<K> key, final M mapper) { CacheEntry<K, M>[] entries; CacheEntry<K, M>[] newEntries; do { entries = mapperCache.get(); for (CacheEntry<K, M> entry : entries) { if (entry.key.equals(key)) { // already added return; } } newEntries = new CacheEntry[entries.length + 1]; System.arraycopy(entries, 0, newEntries, 0, entries.length); newEntries[entries.length] = new CacheEntry<K, M>(key, mapper); } while(!mapperCache.compareAndSet(entries, newEntries)); } @Override public M get(MapperKey<K> key) { final CacheEntry<K, M>[] entries = mapperCache.get(); for (final CacheEntry<K, M> entry : entries) { if (entry.key.equals(key)) { return entry.mapper; } } return null; } @Override public int size() { return mapperCache.get().length; } @Override public String toString() { return "MapperCache{" + Arrays.toString(mapperCache.get()) + '}'; } }