Reduced accessability of multimaps

This commit is contained in:
leventov
2014-11-10 18:12:47 +03:00
parent 3e0644c0dd
commit 9be0d58baf
10 changed files with 71 additions and 150 deletions
@@ -26,7 +26,7 @@ import net.openhft.chronicle.hash.serialization.SizeMarshaller;
import net.openhft.chronicle.hash.serialization.internal.MetaBytesInterop;
import net.openhft.chronicle.hash.serialization.internal.MetaBytesWriter;
import net.openhft.chronicle.hash.serialization.internal.MetaProvider;
import net.openhft.chronicle.map.utils.MultiMapFactory;
import net.openhft.chronicle.map.MultiMapFactory;
import net.openhft.chronicle.set.ChronicleSetBuilder;
import net.openhft.lang.Maths;
import net.openhft.lang.io.ByteBufferBytes;
@@ -439,6 +439,17 @@ public abstract class AbstractChronicleMapBuilder<K, V,
return segments <= maxSegments ? segments : -segments;
}
int segmentHeaderSize() {
int segments = actualSegments();
// reduce false sharing unless we have a lot of segments.
return segments <= 8192 ? 64 : 16;
}
MultiMapFactory multiMapFactory() {
return MultiMapFactory.forCapacity(actualEntriesPerSegment());
}
public B lockTimeOut(long lockTimeOut, TimeUnit unit) {
this.lockTimeOut = lockTimeOut;
lockTimeOutUnit = unit;
@@ -933,15 +944,5 @@ public abstract class AbstractChronicleMapBuilder<K, V,
return (int) Math.min(Math.max(2L, entries() >> 10),
VanillaChronicleMap.MAX_ENTRY_OVERSIZE_FACTOR);
}
int segmentHeaderSize() {
int segments = actualSegments();
// reduce false sharing unless we have a lot of segments.
return segments <= 8192 ? 64 : 16;
}
public MultiMapFactory multiMapFactory() {
return MultiMapFactory.forCapacity(actualEntriesPerSegment());
}
}
@@ -16,7 +16,7 @@
* limitations under the License.
*/
package net.openhft.chronicle.map.utils;
package net.openhft.chronicle.map;
import net.openhft.lang.collection.ATSDirectBitSet;
import net.openhft.lang.collection.DirectBitSet;
@@ -28,7 +28,7 @@ import static net.openhft.lang.Maths.isPowerOf2;
/**
* Supports a simple interface for int -> int[] off heap.
*/
class VanillaI24I24MultiMap implements MultiMap {
class Int24Int24MultiMap implements MultiMap {
static final int MAX_CAPACITY = (1 << 24);
@@ -48,8 +48,8 @@ class VanillaI24I24MultiMap implements MultiMap {
private int searchHash = -1;
private int searchPos = -1;
public VanillaI24I24MultiMap(long minCapacity) {
capacity = (int) VanillaIntIntMultiMap.multiMapCapacity(minCapacity);
public Int24Int24MultiMap(long minCapacity) {
capacity = (int) IntIntMultiMap.multiMapCapacity(minCapacity);
capacityMask = capacity - 1;
capacityMod2 = indexToPos(capacity - 1);
bytes = DirectStore.allocateLazy(indexToPos(capacity)).bytes();
@@ -57,7 +57,7 @@ class VanillaI24I24MultiMap implements MultiMap {
clear();
}
public VanillaI24I24MultiMap(Bytes multiMapBytes, Bytes multiMapBitSetBytes) {
public Int24Int24MultiMap(Bytes multiMapBytes, Bytes multiMapBitSetBytes) {
capacity = (int) Math.min(MAX_CAPACITY, (multiMapBytes.capacity() / ENTRY_SIZE));
assert capacity <= MAX_CAPACITY;
capacityMask = capacity - 1;
@@ -67,21 +67,21 @@ class VanillaI24I24MultiMap implements MultiMap {
}
/**
* @param minCapacity as in {@link #VanillaI24I24MultiMap(long)} constructor
* @return size of {@link Bytes} to provide to {@link #VanillaI24I24MultiMap(Bytes, Bytes)}
* @param minCapacity as in {@link #Int24Int24MultiMap(long)} constructor
* @return size of {@link Bytes} to provide to {@link #Int24Int24MultiMap(Bytes, Bytes)}
* constructor as the first argument
*/
public static long sizeInBytes(long minCapacity) {
return indexToPos((int) VanillaIntIntMultiMap.multiMapCapacity(minCapacity));
return indexToPos((int) IntIntMultiMap.multiMapCapacity(minCapacity));
}
/**
* @param minCapacity as in {@link #VanillaI24I24MultiMap(long)} constructor
* @return size of {@link Bytes} to provide to {@link #VanillaI24I24MultiMap(Bytes, Bytes)}
* @param minCapacity as in {@link #Int24Int24MultiMap(long)} constructor
* @return size of {@link Bytes} to provide to {@link #Int24Int24MultiMap(Bytes, Bytes)}
* constructor as the second argument
*/
public static long sizeOfBitSetInBytes(long minCapacity) {
return (int) (Math.max(VanillaIntIntMultiMap.multiMapCapacity(minCapacity), 64L) * 6L + 63) / 64;
return (int) (Math.max(IntIntMultiMap.multiMapCapacity(minCapacity), 64L) * 6L + 63) / 64;
}
public static ATSDirectBitSet newPositions(int capacity) {
@@ -16,7 +16,7 @@
* limitations under the License.
*/
package net.openhft.chronicle.map.utils;
package net.openhft.chronicle.map;
import net.openhft.lang.Maths;
import net.openhft.lang.collection.ATSDirectBitSet;
@@ -29,7 +29,7 @@ import static net.openhft.lang.Maths.isPowerOf2;
/**
* Supports a simple interface for int -> int[] off heap.
*/
class VanillaIntIntMultiMap implements MultiMap {
class IntIntMultiMap implements MultiMap {
static final long MAX_CAPACITY = (1L << 32);
@@ -59,7 +59,7 @@ class VanillaIntIntMultiMap implements MultiMap {
private long searchHash = -1L;
private long searchPos = -1L;
public VanillaIntIntMultiMap(long minCapacity) {
public IntIntMultiMap(long minCapacity) {
capacity = multiMapCapacity(minCapacity);
capacityMask = capacity - 1L;
capacityMask2 = indexToPos(capacity - 1L);
@@ -68,7 +68,7 @@ class VanillaIntIntMultiMap implements MultiMap {
clear();
}
public VanillaIntIntMultiMap(Bytes multiMapBytes, Bytes multiMapBitSetBytes) {
public IntIntMultiMap(Bytes multiMapBytes, Bytes multiMapBitSetBytes) {
capacity = multiMapBytes.capacity() / ENTRY_SIZE;
assert capacity == Maths.nextPower2(capacity, 16L);
capacityMask = capacity - 1L;
@@ -78,8 +78,8 @@ class VanillaIntIntMultiMap implements MultiMap {
}
/**
* @param minCapacity as in {@link #VanillaIntIntMultiMap(long)} constructor
* @return size of {@link Bytes} to provide to {@link #VanillaIntIntMultiMap(Bytes, Bytes)}
* @param minCapacity as in {@link #IntIntMultiMap(long)} constructor
* @return size of {@link Bytes} to provide to {@link #IntIntMultiMap(Bytes, Bytes)}
* constructor as the first argument
*/
public static long sizeInBytes(long minCapacity) {
@@ -87,8 +87,8 @@ class VanillaIntIntMultiMap implements MultiMap {
}
/**
* @param minCapacity as in {@link #VanillaIntIntMultiMap(long)} constructor
* @return size of {@link Bytes} to provide to {@link #VanillaIntIntMultiMap(Bytes, Bytes)}
* @param minCapacity as in {@link #IntIntMultiMap(long)} constructor
* @return size of {@link Bytes} to provide to {@link #IntIntMultiMap(Bytes, Bytes)}
* constructor as the second argument
*/
public static long sizeOfBitSetInBytes(long minCapacity) {
@@ -14,14 +14,14 @@
* limitations under the License.
*/
package net.openhft.chronicle.map.utils;
package net.openhft.chronicle.map;
import net.openhft.lang.collection.DirectBitSet;
/**
* This is only used to store keys and positions, but it could store int/int key/values for another purpose.
*/
public interface MultiMap {
interface MultiMap {
/**
* @return gets all the active positions as a bitset
@@ -16,7 +16,7 @@
* limitations under the License.
*/
package net.openhft.chronicle.map.utils;
package net.openhft.chronicle.map;
import net.openhft.lang.io.NativeBytes;
@@ -25,65 +25,65 @@ import net.openhft.lang.io.NativeBytes;
*
* In future we might support I32 -> I16 or similar.
*/
public enum MultiMapFactory {
enum MultiMapFactory {
I16 {
@Override
public long sizeInBytes(long minCapacity) {
return VanillaShortShortMultiMap.sizeInBytes(minCapacity);
return ShortShortMultiMap.sizeInBytes(minCapacity);
}
@Override
public long sizeOfBitSetInBytes(long minCapacity) {
return VanillaShortShortMultiMap.sizeOfBitSetInBytes(minCapacity);
return ShortShortMultiMap.sizeOfBitSetInBytes(minCapacity);
}
@Override
public MultiMap create(NativeBytes bytes, NativeBytes bitSetBytes) {
return new VanillaShortShortMultiMap(bytes, bitSetBytes);
return new ShortShortMultiMap(bytes, bitSetBytes);
}
},
I24 {
@Override
public long sizeInBytes(long minCapacity) {
return VanillaI24I24MultiMap.sizeInBytes(minCapacity);
return Int24Int24MultiMap.sizeInBytes(minCapacity);
}
@Override
public long sizeOfBitSetInBytes(long minCapacity) {
return VanillaI24I24MultiMap.sizeOfBitSetInBytes(minCapacity);
return Int24Int24MultiMap.sizeOfBitSetInBytes(minCapacity);
}
@Override
public MultiMap create(NativeBytes bytes, NativeBytes bitSetBytes) {
return new VanillaI24I24MultiMap(bytes, bitSetBytes);
return new Int24Int24MultiMap(bytes, bitSetBytes);
}
},
I32 {
@Override
public long sizeInBytes(long minCapacity) {
return VanillaIntIntMultiMap.sizeInBytes(minCapacity);
return IntIntMultiMap.sizeInBytes(minCapacity);
}
@Override
public long sizeOfBitSetInBytes(long minCapacity) {
return VanillaIntIntMultiMap.sizeOfBitSetInBytes(minCapacity);
return IntIntMultiMap.sizeOfBitSetInBytes(minCapacity);
}
@Override
public MultiMap create(NativeBytes bytes, NativeBytes bitSetBytes) {
return new VanillaIntIntMultiMap(bytes, bitSetBytes);
return new IntIntMultiMap(bytes, bitSetBytes);
}
};
public static final long I16_MAX_CAPACITY = VanillaShortShortMultiMap.MAX_CAPACITY;
public static final long MAX_CAPACITY = VanillaIntIntMultiMap.MAX_CAPACITY;
public static final long I16_MAX_CAPACITY = ShortShortMultiMap.MAX_CAPACITY;
public static final long MAX_CAPACITY = IntIntMultiMap.MAX_CAPACITY;
public static MultiMapFactory forCapacity(long capacity) {
if (capacity <= VanillaShortShortMultiMap.MAX_CAPACITY)
if (capacity <= ShortShortMultiMap.MAX_CAPACITY)
return I16;
// if (capacity <= VanillaI24I24MultiMap.MAX_CAPACITY)
// if (capacity <= Int24Int24MultiMap.MAX_CAPACITY)
// return I24;
if (capacity <= VanillaIntIntMultiMap.MAX_CAPACITY)
if (capacity <= IntIntMultiMap.MAX_CAPACITY)
return I32;
throw new IllegalArgumentException("Capacity " + capacity + " not supported");
}
@@ -23,7 +23,7 @@ import net.openhft.chronicle.hash.replication.TimeProvider;
import net.openhft.chronicle.hash.serialization.BytesReader;
import net.openhft.chronicle.hash.serialization.internal.MetaBytesInterop;
import net.openhft.chronicle.hash.serialization.internal.MetaBytesWriter;
import net.openhft.chronicle.map.utils.MultiMap;
import net.openhft.chronicle.map.MultiMap;
import net.openhft.lang.Maths;
import net.openhft.lang.collection.ATSDirectBitSet;
import net.openhft.lang.io.Bytes;
@@ -16,7 +16,7 @@
* limitations under the License.
*/
package net.openhft.chronicle.map.utils;
package net.openhft.chronicle.map;
import net.openhft.lang.collection.ATSDirectBitSet;
@@ -24,13 +24,13 @@ import net.openhft.lang.collection.DirectBitSet;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.io.DirectStore;
import static net.openhft.chronicle.map.utils.VanillaIntIntMultiMap.multiMapCapacity;
import static net.openhft.chronicle.map.IntIntMultiMap.multiMapCapacity;
import static net.openhft.lang.Maths.isPowerOf2;
/**
* Supports a simple interface for int -> int[] off heap.
*/
class VanillaShortShortMultiMap implements MultiMap {
class ShortShortMultiMap implements MultiMap {
static final long MAX_CAPACITY = (1L << 16);
@@ -47,7 +47,7 @@ class VanillaShortShortMultiMap implements MultiMap {
private long searchHash = -1L;
private long searchPos = -1L;
public VanillaShortShortMultiMap(long minCapacity) {
public ShortShortMultiMap(long minCapacity) {
assert minCapacity <= MAX_CAPACITY;
long capacity = multiMapCapacity(minCapacity);
assert isPowerOf2(capacity);
@@ -55,11 +55,11 @@ class VanillaShortShortMultiMap implements MultiMap {
capacityMask = capacity - 1L;
capacityMask2 = (capacity - 1L) * ENTRY_SIZE;
bytes = DirectStore.allocateLazy(capacity * ENTRY_SIZE).bytes();
positions = VanillaIntIntMultiMap.newPositions(capacity);
positions = IntIntMultiMap.newPositions(capacity);
clear();
}
public VanillaShortShortMultiMap(Bytes multiMapBytes, Bytes multiMapBitSetBytes) {
public ShortShortMultiMap(Bytes multiMapBytes, Bytes multiMapBitSetBytes) {
long capacity = multiMapBytes.capacity() / ENTRY_SIZE;
assert isPowerOf2(capacity);
assert (capacity / 2L) <= MAX_CAPACITY;
@@ -71,8 +71,8 @@ class VanillaShortShortMultiMap implements MultiMap {
}
/**
* @param minCapacity as in {@link #VanillaShortShortMultiMap(long)} constructor
* @return size of {@link Bytes} to provide to {@link #VanillaShortShortMultiMap(Bytes, Bytes)}
* @param minCapacity as in {@link #ShortShortMultiMap(long)} constructor
* @return size of {@link Bytes} to provide to {@link #ShortShortMultiMap(Bytes, Bytes)}
* constructor as the first argument
*/
public static long sizeInBytes(long minCapacity) {
@@ -80,14 +80,14 @@ class VanillaShortShortMultiMap implements MultiMap {
}
/**
* @param minCapacity as in {@link #VanillaShortShortMultiMap(long)} constructor
* @return size of {@link Bytes} to provide to {@link #VanillaShortShortMultiMap(Bytes, Bytes)}
* @param minCapacity as in {@link #ShortShortMultiMap(long)} constructor
* @return size of {@link Bytes} to provide to {@link #ShortShortMultiMap(Bytes, Bytes)}
* constructor as the second argument
*/
public static long sizeOfBitSetInBytes(long minCapacity) {
return VanillaIntIntMultiMap.sizeOfBitSetInBytes(minCapacity);
return IntIntMultiMap.sizeOfBitSetInBytes(minCapacity);
}
private void checkValueForPut(long value) {
@@ -183,7 +183,7 @@ class VanillaShortShortMultiMap implements MultiMap {
if (entryToShift == UNSET_ENTRY)
break;
long insertPos = pos(key(entryToShift));
// see comment in VanillaIntIntMultiMap
// see comment in IntIntMultiMap
boolean cond1 = insertPos <= posToRemove;
boolean cond2 = posToRemove <= posToShift;
if ((cond1 && cond2) ||
@@ -25,8 +25,8 @@ import net.openhft.chronicle.hash.serialization.SizeMarshaller;
import net.openhft.chronicle.hash.serialization.internal.MetaBytesInterop;
import net.openhft.chronicle.hash.serialization.internal.MetaBytesWriter;
import net.openhft.chronicle.hash.serialization.internal.MetaProvider;
import net.openhft.chronicle.map.utils.MultiMap;
import net.openhft.chronicle.map.utils.MultiMapFactory;
import net.openhft.chronicle.map.MultiMap;
import net.openhft.chronicle.map.MultiMapFactory;
import net.openhft.lang.collection.DirectBitSet;
import net.openhft.lang.collection.SingleThreadedDirectBitSet;
import net.openhft.lang.io.*;
@@ -1,83 +0,0 @@
/*
* Copyright 2014 Higher Frequency Trading
*
* http://www.higherfrequencytrading.com
*
* Licensed 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 net.openhft.chronicle.map.utils;
import net.openhft.lang.collection.DirectBitSet;
/**
* This is only used to store keys and positions, but it could store int/int key/values for another purpose.
*/
interface IntIntMultiMap {
/**
* @return gets all the active positions as a bitset
*/
DirectBitSet getPositions();
/**
* Add an entry. Allow duplicate hashes, but not key/position pairs.
*
* @param key to add
* @param value to add
*/
void put(int key, int value);
/**
* Remove a key/value pair.
*
* @param key to remove
* @param value to remove
* @return whether a match was found.
*/
boolean remove(int key, int value);
boolean replace(int key, int oldValue, int newValue);
/**
* Used for start a search for a given key
*
* @return normalized key value, better to be used in subsequent calls
*/
int startSearch(int key);
int getSearchHash();
/**
* Used for getting the next position for a given key
*
* @return the next position for the last search or negative value
*/
int nextPos();
void removePrevPos();
void replacePrevPos(int newValue);
void putAfterFailedSearch(int value);
void clear();
void forEach(EntryConsumer action);
static interface EntryConsumer {
void accept(int key, int value);
}
}