mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
HCOLL-164 added a void marshaller and Map replication test using VOID value
This commit is contained in:
@@ -34,18 +34,16 @@ import static net.openhft.chronicle.map.Objects.builderEquals;
|
||||
|
||||
public class ChronicleSetBuilder<E> implements Cloneable {
|
||||
|
||||
private ChronicleMapBuilder<E, Boolean> chronicleMapBuilder;
|
||||
private ChronicleMapBuilder<E, Void> chronicleMapBuilder;
|
||||
|
||||
ChronicleSetBuilder(Class<E> keyClass) {
|
||||
chronicleMapBuilder = new ChronicleMapBuilder<E, Boolean>(keyClass, Boolean.class);
|
||||
chronicleMapBuilder.constantValueSizeBySample(Boolean.TRUE);
|
||||
chronicleMapBuilder = new ChronicleMapBuilder<E, Void>(keyClass, Void.class);
|
||||
}
|
||||
|
||||
public static <K> ChronicleSetBuilder<K> of(Class<K> keyClass) {
|
||||
return new ChronicleSetBuilder<K>(keyClass);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ChronicleSetBuilder<E> clone() {
|
||||
try {
|
||||
@@ -58,7 +56,6 @@ public class ChronicleSetBuilder<E> implements Cloneable {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public ChronicleSetBuilder<E> actualSegments(int actualSegments) {
|
||||
chronicleMapBuilder.actualSegments(actualSegments);
|
||||
return this;
|
||||
@@ -83,7 +80,6 @@ public class ChronicleSetBuilder<E> implements Cloneable {
|
||||
return chronicleMapBuilder.minSegments();
|
||||
}
|
||||
|
||||
|
||||
public ChronicleSetBuilder<E> actualElementsPerSegment(int actualEntriesPerSegment) {
|
||||
chronicleMapBuilder.actualEntriesPerSegment(actualEntriesPerSegment);
|
||||
return this;
|
||||
@@ -338,22 +334,22 @@ public class ChronicleSetBuilder<E> implements Cloneable {
|
||||
|
||||
|
||||
public ChronicleSet<E> create(File file) throws IOException {
|
||||
final ChronicleMap<E, Boolean> map = chronicleMapBuilder.create(file);
|
||||
final ChronicleMap<E, Void> map = chronicleMapBuilder.create(file);
|
||||
return new SetFromMap<E>(map);
|
||||
}
|
||||
|
||||
public ChronicleSet<E> create() throws IOException {
|
||||
final ChronicleMap<E, Boolean> map = chronicleMapBuilder.create();
|
||||
final ChronicleMap<E, Void> map = chronicleMapBuilder.create();
|
||||
return new SetFromMap<E>(map);
|
||||
}
|
||||
|
||||
private static class SetFromMap<E> extends AbstractSet<E>
|
||||
implements ChronicleSet<E>, Serializable {
|
||||
|
||||
private final ChronicleMap<E, Boolean> m; // The backing map
|
||||
private final ChronicleMap<E, Void> m; // The backing map
|
||||
private transient Set<E> s; // Its keySet
|
||||
|
||||
SetFromMap(ChronicleMap<E, Boolean> map) {
|
||||
SetFromMap(ChronicleMap<E, Void> map) {
|
||||
if (!map.isEmpty())
|
||||
throw new IllegalArgumentException("Map is non-empty");
|
||||
m = map;
|
||||
@@ -381,7 +377,7 @@ public class ChronicleSetBuilder<E> implements Cloneable {
|
||||
}
|
||||
|
||||
public boolean add(E e) {
|
||||
return m.put(e, Boolean.TRUE) == null;
|
||||
return m.put(e, (Void)null) == null;
|
||||
}
|
||||
|
||||
public Iterator<E> iterator() {
|
||||
|
||||
@@ -381,7 +381,6 @@ class ReplicatedChronicleMap<K, KI, MKI extends MetaBytesInterop<K, KI>,
|
||||
long valueSize;
|
||||
if (!isDeleted) {
|
||||
valueSize = valueSizeMarshaller.readSize(entry);
|
||||
assert valueSize > 0;
|
||||
} else {
|
||||
valueSize = 0;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,10 @@ import net.openhft.chronicle.map.serialization.impl.*;
|
||||
import net.openhft.chronicle.map.threadlocal.Provider;
|
||||
import net.openhft.chronicle.map.threadlocal.ThreadLocalCopies;
|
||||
import net.openhft.lang.io.Bytes;
|
||||
import net.openhft.lang.io.serialization.*;
|
||||
import net.openhft.lang.io.serialization.BytesMarshallable;
|
||||
import net.openhft.lang.io.serialization.BytesMarshaller;
|
||||
import net.openhft.lang.io.serialization.ObjectFactory;
|
||||
import net.openhft.lang.io.serialization.ObjectSerializer;
|
||||
import net.openhft.lang.io.serialization.impl.*;
|
||||
import net.openhft.lang.model.Byteable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -40,7 +43,7 @@ final class SerializationBuilder<E> implements Cloneable {
|
||||
private static boolean concreteClass(Class c) {
|
||||
return !c.isInterface() && !Modifier.isAbstract(c.getModifiers());
|
||||
}
|
||||
|
||||
|
||||
private static boolean marshallerUseFactory(Class c) {
|
||||
return Byteable.class.isAssignableFrom(c) ||
|
||||
BytesMarshallable.class.isAssignableFrom(c) ||
|
||||
@@ -52,6 +55,7 @@ final class SerializationBuilder<E> implements Cloneable {
|
||||
}
|
||||
|
||||
enum Role {KEY, VALUE}
|
||||
|
||||
private enum CopyingInterop {FROM_MARSHALLER, FROM_WRITER}
|
||||
|
||||
private final Serializable bufferIdentity;
|
||||
@@ -84,6 +88,8 @@ final class SerializationBuilder<E> implements Cloneable {
|
||||
} else if (eClass == CharSequence.class || eClass == String.class) {
|
||||
reader((BytesReader<E>) CharSequenceReader.of(), factory);
|
||||
writer((BytesWriter<E>) CharSequenceWriter.instance());
|
||||
} else if (eClass == Void.class) {
|
||||
agileMarshaller((AgileBytesMarshaller<E>) VoidMarshaller.INSTANCE, factory);
|
||||
} else if (eClass == Long.class) {
|
||||
agileMarshaller((AgileBytesMarshaller<E>) LongMarshaller.INSTANCE, factory);
|
||||
} else if (eClass == byte[].class) {
|
||||
|
||||
@@ -17,15 +17,16 @@
|
||||
package net.openhft.chronicle.map;
|
||||
|
||||
import net.openhft.chronicle.map.serialization.*;
|
||||
import net.openhft.chronicle.map.threadlocal.Provider;
|
||||
import net.openhft.chronicle.map.threadlocal.ThreadLocalCopies;
|
||||
import net.openhft.lang.Maths;
|
||||
import net.openhft.lang.collection.DirectBitSet;
|
||||
import net.openhft.lang.collection.SingleThreadedDirectBitSet;
|
||||
import net.openhft.lang.io.*;
|
||||
import net.openhft.lang.io.serialization.*;
|
||||
import net.openhft.lang.io.serialization.JDKObjectSerializer;
|
||||
import net.openhft.lang.io.serialization.ObjectFactory;
|
||||
import net.openhft.lang.io.serialization.impl.VanillaBytesMarshallerFactory;
|
||||
import net.openhft.lang.model.Byteable;
|
||||
import net.openhft.chronicle.map.threadlocal.Provider;
|
||||
import net.openhft.chronicle.map.threadlocal.ThreadLocalCopies;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -312,7 +313,7 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, KI>,
|
||||
}
|
||||
|
||||
void checkValue(Object value) {
|
||||
if (!vClass.isInstance(value)) {
|
||||
if (vClass != Void.class && !vClass.isInstance(value)) {
|
||||
throw new ClassCastException("Value must be a " + vClass.getName() +
|
||||
" but was a " + value.getClass());
|
||||
}
|
||||
@@ -692,7 +693,7 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, KI>,
|
||||
* true}, {@code usingValue} or a newly created instance of value class, if {@code usingValue ==
|
||||
* null}, is put into this Segment for the key.</li></ol>
|
||||
*
|
||||
* @param hash2 a hash code related to the {@code keyBytes}
|
||||
* @param hash2 a hash code related to the {@code keyBytes}
|
||||
* @return the value which is finally associated with the given key in this Segment after execution of
|
||||
* this method, or {@code null}.
|
||||
*/
|
||||
@@ -827,13 +828,12 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, KI>,
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts entry. If {@code value} implements {@link Byteable} interface and
|
||||
* {@code usingValue} is {@code true}, the value is backed with the bytes of this entry.
|
||||
* Puts entry. If {@code value} implements {@link Byteable} interface and {@code usingValue} is {@code
|
||||
* true}, the value is backed with the bytes of this entry.
|
||||
*
|
||||
* @param value the value to put
|
||||
* @param usingValue {@code true} if the value should be backed with the bytes of the entry,
|
||||
* if it implements {@link Byteable} interface, {@code false} if it
|
||||
* should put itself
|
||||
* @param usingValue {@code true} if the value should be backed with the bytes of the entry, if it
|
||||
* implements {@link Byteable} interface, {@code false} if it should put itself
|
||||
* @return offset of the written entry in the Segment bytes
|
||||
*/
|
||||
private long putEntry(ThreadLocalCopies copies, MKI metaKeyInterop, KI keyInterop, K key,
|
||||
@@ -958,7 +958,7 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, KI>,
|
||||
* Removes a key (or key-value pair) from the Segment. <p/> The entry will only be removed if {@code
|
||||
* expectedValue} equals to {@code null} or the value previously corresponding to the specified key.
|
||||
*
|
||||
* @param hash2 a hash code related to the {@code keyBytes}
|
||||
* @param hash2 a hash code related to the {@code keyBytes}
|
||||
* @return the value of the entry that was removed if the entry corresponding to the {@code keyBytes}
|
||||
* exists and {@link #removeReturnsNull} is {@code false}, {@code null} otherwise
|
||||
*/
|
||||
@@ -1095,12 +1095,12 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, KI>,
|
||||
* Replaces value in existing entry. May cause entry relocation, because there may be not enough space
|
||||
* for new value in location already allocated for this entry.
|
||||
*
|
||||
* @param pos index of the first block occupied by the entry
|
||||
* @param offset relative offset of the entry in Segment bytes (before, i. e. including
|
||||
* metaData)
|
||||
* @param entry relative pointer in Segment bytes
|
||||
* @param valueSizePos relative position of value size in entry
|
||||
* @param entryEndAddr absolute address of the entry end
|
||||
* @param pos index of the first block occupied by the entry
|
||||
* @param offset relative offset of the entry in Segment bytes (before, i. e. including
|
||||
* metaData)
|
||||
* @param entry relative pointer in Segment bytes
|
||||
* @param valueSizePos relative position of value size in entry
|
||||
* @param entryEndAddr absolute address of the entry end
|
||||
* @return relative offset of the entry in Segment bytes after putting value (that may cause entry
|
||||
* relocation)
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.serialization.impl;
|
||||
|
||||
import net.openhft.chronicle.map.serialization.AgileBytesMarshaller;
|
||||
import net.openhft.lang.io.Bytes;
|
||||
|
||||
public enum VoidMarshaller implements AgileBytesMarshaller<Void> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public long size(Void e) {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int sizeEncodingSize(long size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSize(Bytes bytes, long size) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startsWith(Bytes bytes, Void e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long hash(Void e) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(Bytes bytes, Void e) {
|
||||
// do nothing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long readSize(Bytes bytes) {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void read(Bytes bytes, long size) {
|
||||
// Void nothing;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void read(Bytes bytes, long size, Void aVoid) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user