org.simpleflatmapper.map.mapper.MapperCache Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sfm-map Show documentation
Show all versions of sfm-map Show documentation
Java library to map flat record - ResultSet, csv - to java object with minimum configuration and low footprint.
package org.simpleflatmapper.map.mapper;
import org.simpleflatmapper.map.FieldKey;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicReference;
public final class MapperCache, M> {
private static final int SIZE_THRESHOLD = 60;
@SuppressWarnings("unchecked")
private final AtomicReference> sortedEntries;
public MapperCache(MapperKeyComparator comparator) {
this.sortedEntries =
new AtomicReference>(
new SortedEntries(0, comparator));
}
@SuppressWarnings("unchecked")
public void add(final MapperKey key, final M mapper) {
SortedEntries sortedEntries;
SortedEntries newSortedEntries;
do {
sortedEntries = this.sortedEntries.get();
final int i = sortedEntries.findInsertionPoint(key);
if (i >= 0) {
if (!key.equals(sortedEntries.keys[i])) {
throw new IllegalStateException("Comparator find key " + key + " to be equal to " + sortedEntries.keys[i] + " but is not");
}
return;
}
int insertionPoint = -1 - i;
newSortedEntries = sortedEntries.insertEntry(key, mapper, insertionPoint);
} while(!this.sortedEntries.compareAndSet(sortedEntries, newSortedEntries));
}
@SuppressWarnings("unchecked")
public M get(MapperKey key) {
return (M) sortedEntries.get().search(key);
}
private static final class SortedEntries> {
private final MapperKey[] keys;
private final Object[] values;
private final boolean bsearch;
private final MapperKeyComparator comparator;
@SuppressWarnings("unchecked")
SortedEntries(int size, MapperKeyComparator comparator) {
this.comparator = comparator;
this.keys = new MapperKey[size];
this.values = new Object[size];
this.bsearch = size > SIZE_THRESHOLD;
}
SortedEntries(MapperKey[] keys, Object[] values, MapperKeyComparator comparator) {
this.keys = keys;
this.values = values;
this.comparator = comparator;
this.bsearch = keys.length > SIZE_THRESHOLD;
}
Object search(MapperKey key) {
final int i = findKey(key);
if (i >= 0) {
return values[i];
}
return null;
}
int findKey(MapperKey key) {
if (bsearch) {
return Arrays.binarySearch(keys, key, comparator);
} else {
return iFindKey(key);
}
}
private int iFindKey(MapperKey key) {
for(int i = 0; i < keys.length; i++) {
if (key.equals(keys[i])) {
return i;
}
}
return - keys.length - 1;
}
private int findInsertionPoint(MapperKey key) {
if (comparator == null) {
return iFindKey(key);
} else {
return Arrays.binarySearch(keys, key, comparator);
}
}
SortedEntries insertEntry(MapperKey key, Object mapper, int insertionPoint) {
SortedEntries newEntries =
new SortedEntries(
Arrays.copyOf(keys, keys.length + 1),
Arrays.copyOf(values, values.length + 1),
comparator);
System.arraycopy(newEntries.keys, insertionPoint, newEntries.keys, insertionPoint + 1, keys.length - insertionPoint);
System.arraycopy(newEntries.values, insertionPoint, newEntries.values, insertionPoint + 1, values.length - insertionPoint);
newEntries.keys[insertionPoint] = key;
newEntries.values[insertionPoint] = mapper;
return newEntries;
}
}
@Override
public String toString() {
return "MapperCache{" +
"sortedEntries=" + Arrays.toString(sortedEntries.get().keys) +
'}';
}
}