Move ByteBuffer functions to ByteBufferUtil and avoid duplication

This commit is contained in:
Sylvain Lebresne 2014-03-13 09:11:44 +01:00
parent 3e2c610577
commit 8a52f5af4f
10 changed files with 80 additions and 98 deletions

View File

@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
import org.apache.cassandra.db.filter.ColumnSlice;
import org.apache.cassandra.db.marshal.AbstractCompositeType;
import org.apache.cassandra.db.marshal.CompositeType;
import org.apache.cassandra.utils.ByteBufferUtil;
public abstract class AbstractComposite implements Composite
{
@ -75,12 +76,12 @@ public abstract class AbstractComposite implements Composite
// See org.apache.cassandra.db.marshal.CompositeType for details.
ByteBuffer result = ByteBuffer.allocate(dataSize() + 3 * size() + (isStatic() ? 2 : 0));
if (isStatic())
AbstractCompositeType.putShortLength(result, CompositeType.STATIC_MARKER);
ByteBufferUtil.writeShortLength(result, CompositeType.STATIC_MARKER);
for (int i = 0; i < size(); i++)
{
ByteBuffer bb = get(i);
AbstractCompositeType.putShortLength(result, bb.remaining());
ByteBufferUtil.writeShortLength(result, bb.remaining());
result.put(bb.duplicate());
result.put((byte)0);
}

View File

@ -17,15 +17,16 @@
*/
package org.apache.cassandra.db.marshal;
import org.apache.cassandra.serializers.TypeSerializer;
import org.apache.cassandra.serializers.BytesSerializer;
import org.apache.cassandra.serializers.MarshalException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.cassandra.serializers.TypeSerializer;
import org.apache.cassandra.serializers.BytesSerializer;
import org.apache.cassandra.serializers.MarshalException;
import org.apache.cassandra.utils.ByteBufferUtil;
/**
* A class avoiding class duplication between CompositeType and
* DynamicCompositeType.
@ -34,44 +35,6 @@ import java.util.List;
*/
public abstract class AbstractCompositeType extends AbstractType<ByteBuffer>
{
// changes bb position
public static int getShortLength(ByteBuffer bb)
{
int length = (bb.get() & 0xFF) << 8;
return length | (bb.get() & 0xFF);
}
// Doesn't change bb position
protected static int getShortLength(ByteBuffer bb, int position)
{
int length = (bb.get(position) & 0xFF) << 8;
return length | (bb.get(position + 1) & 0xFF);
}
// changes bb position
public static void putShortLength(ByteBuffer bb, int length)
{
bb.put((byte) ((length >> 8) & 0xFF));
bb.put((byte) (length & 0xFF));
}
// changes bb position
public static ByteBuffer getBytes(ByteBuffer bb, int length)
{
ByteBuffer copy = bb.duplicate();
copy.limit(copy.position() + length);
bb.position(bb.position() + length);
return copy;
}
// changes bb position
public static ByteBuffer getWithShortLength(ByteBuffer bb)
{
int length = getShortLength(bb);
return getBytes(bb, length);
}
public int compare(ByteBuffer o1, ByteBuffer o2)
{
if (o1 == null || !o1.hasRemaining())
@ -95,8 +58,8 @@ public abstract class AbstractCompositeType extends AbstractType<ByteBuffer>
{
AbstractType<?> comparator = getComparator(i, bb1, bb2);
ByteBuffer value1 = getWithShortLength(bb1);
ByteBuffer value2 = getWithShortLength(bb2);
ByteBuffer value1 = ByteBufferUtil.readBytesWithShortLength(bb1);
ByteBuffer value2 = ByteBufferUtil.readBytesWithShortLength(bb2);
int cmp = comparator.compareCollectionMembers(value1, value2, previous);
if (cmp != 0)
@ -135,7 +98,7 @@ public abstract class AbstractCompositeType extends AbstractType<ByteBuffer>
while (bb.remaining() > 0)
{
getComparator(i++, bb);
l.add(getWithShortLength(bb));
l.add(ByteBufferUtil.readBytesWithShortLength(bb));
bb.get(); // skip end-of-component
}
return l.toArray(new ByteBuffer[l.size()]);
@ -164,7 +127,7 @@ public abstract class AbstractCompositeType extends AbstractType<ByteBuffer>
while (bb.remaining() > 0)
{
AbstractType comparator = getComparator(i, bb);
ByteBuffer value = getWithShortLength(bb);
ByteBuffer value = ByteBufferUtil.readBytesWithShortLength(bb);
list.add( new CompositeComponent(comparator,value) );
@ -237,7 +200,7 @@ public abstract class AbstractCompositeType extends AbstractType<ByteBuffer>
sb.append(":");
AbstractType<?> comparator = getAndAppendComparator(i, bb, sb);
ByteBuffer value = getWithShortLength(bb);
ByteBuffer value = ByteBufferUtil.readBytesWithShortLength(bb);
sb.append(escape(comparator.getString(value)));
@ -290,7 +253,7 @@ public abstract class AbstractCompositeType extends AbstractType<ByteBuffer>
for (ByteBuffer component : components)
{
comparators.get(i).serializeComparator(bb);
putShortLength(bb, component.remaining());
ByteBufferUtil.writeShortLength(bb, component.remaining());
bb.put(component); // it's ok to consume component as we won't use it anymore
bb.put((byte)0);
++i;
@ -318,11 +281,11 @@ public abstract class AbstractCompositeType extends AbstractType<ByteBuffer>
if (bb.remaining() < 2)
throw new MarshalException("Not enough bytes to read value size of component " + i);
int length = getShortLength(bb);
int length = ByteBufferUtil.readShortLength(bb);
if (bb.remaining() < length)
throw new MarshalException("Not enough bytes to read value of component " + i);
ByteBuffer value = getBytes(bb, length);
ByteBuffer value = ByteBufferUtil.readBytes(bb, length);
comparator.validateCollectionMember(value, previous);

View File

@ -146,12 +146,6 @@ public abstract class CollectionType<T> extends AbstractType<T>
return pack(buffers, elements, size);
}
protected static int getUnsignedShort(ByteBuffer bb)
{
int length = (bb.get() & 0xFF) << 8;
return length | (bb.get() & 0xFF);
}
public CQL3Type asCQL3Type()
{
return new CQL3Type.Collection(this);

View File

@ -89,11 +89,11 @@ public class CompositeType extends AbstractCompositeType
if (bb.remaining() < 2)
return false;
int header = getShortLength(bb, bb.position());
int header = ByteBufferUtil.getShortLength(bb, bb.position());
if ((header & 0xFFFF) != STATIC_MARKER)
return false;
getShortLength(bb); // Skip header
ByteBufferUtil.readShortLength(bb); // Skip header
return true;
}
@ -179,7 +179,7 @@ public class CompositeType extends AbstractCompositeType
int i = 0;
while (bb.remaining() > 0)
{
l[i++] = getWithShortLength(bb);
l[i++] = ByteBufferUtil.readBytesWithShortLength(bb);
bb.get(); // skip end-of-component
}
return i == l.length ? l : Arrays.copyOfRange(l, 0, i);
@ -193,7 +193,7 @@ public class CompositeType extends AbstractCompositeType
int i = 0;
while (bb.remaining() > 0)
{
ByteBuffer c = getWithShortLength(bb);
ByteBuffer c = ByteBufferUtil.readBytesWithShortLength(bb);
if (i == idx)
return c;
@ -212,7 +212,7 @@ public class CompositeType extends AbstractCompositeType
public static boolean isStaticName(ByteBuffer bb)
{
return bb.remaining() >= 2 && (getShortLength(bb, bb.position()) & 0xFFFF) == STATIC_MARKER;
return bb.remaining() >= 2 && (ByteBufferUtil.getShortLength(bb, bb.position()) & 0xFFFF) == STATIC_MARKER;
}
@Override
@ -324,7 +324,7 @@ public class CompositeType extends AbstractCompositeType
ByteBuffer out = ByteBuffer.allocate(totalLength);
for (ByteBuffer bb : buffers)
{
putShortLength(out, bb.remaining());
ByteBufferUtil.writeShortLength(out, bb.remaining());
out.put(bb.duplicate());
out.put((byte) 0);
}

View File

@ -90,10 +90,10 @@ public class DynamicCompositeType extends AbstractCompositeType
{
try
{
int header = getShortLength(bb);
int header = ByteBufferUtil.readShortLength(bb);
if ((header & 0x8000) == 0)
{
String name = ByteBufferUtil.string(getBytes(bb, header));
String name = ByteBufferUtil.string(ByteBufferUtil.readBytes(bb, header));
return TypeParser.parse(name);
}
else
@ -152,10 +152,10 @@ public class DynamicCompositeType extends AbstractCompositeType
{
try
{
int header = getShortLength(bb);
int header = ByteBufferUtil.readShortLength(bb);
if ((header & 0x8000) == 0)
{
String name = ByteBufferUtil.string(getBytes(bb, header));
String name = ByteBufferUtil.string(ByteBufferUtil.readBytes(bb, header));
sb.append(name).append("@");
return TypeParser.parse(name);
}
@ -189,13 +189,13 @@ public class DynamicCompositeType extends AbstractCompositeType
AbstractType<?> comparator = null;
if (bb.remaining() < 2)
throw new MarshalException("Not enough bytes to header of the comparator part of component " + i);
int header = getShortLength(bb);
int header = ByteBufferUtil.readShortLength(bb);
if ((header & 0x8000) == 0)
{
if (bb.remaining() < header)
throw new MarshalException("Not enough bytes to read comparator name of component " + i);
ByteBuffer value = getBytes(bb, header);
ByteBuffer value = ByteBufferUtil.readBytes(bb, header);
String valueStr = null;
try
{
@ -325,7 +325,7 @@ public class DynamicCompositeType extends AbstractCompositeType
header = 0x8000 | (((byte)comparatorName.charAt(0)) & 0xFF);
else
header = comparatorName.length();
putShortLength(bb, header);
ByteBufferUtil.writeShortLength(bb, header);
if (!isAlias)
bb.put(ByteBufferUtil.bytes(comparatorName));

View File

@ -48,10 +48,4 @@ public abstract class CollectionSerializer<T> implements TypeSerializer<T>
size += 2 + bb.remaining();
return pack(buffers, elements, size);
}
protected static int getUnsignedShort(ByteBuffer bb)
{
int length = (bb.get() & 0xFF) << 8;
return length | (bb.get() & 0xFF);
}
}

View File

@ -22,6 +22,8 @@ import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.util.*;
import org.apache.cassandra.utils.ByteBufferUtil;
public class ListSerializer<T> extends CollectionSerializer<List<T>>
{
// interning instances
@ -50,14 +52,11 @@ public class ListSerializer<T> extends CollectionSerializer<List<T>>
try
{
ByteBuffer input = bytes.duplicate();
int n = getUnsignedShort(input);
int n = ByteBufferUtil.readShortLength(input);
List<T> l = new ArrayList<T>(n);
for (int i = 0; i < n; i++)
{
int s = getUnsignedShort(input);
byte[] data = new byte[s];
input.get(data);
ByteBuffer databb = ByteBuffer.wrap(data);
ByteBuffer databb = ByteBufferUtil.readBytesWithShortLength(input);
elements.validate(databb);
l.add(elements.deserialize(databb));
}

View File

@ -18,12 +18,13 @@
package org.apache.cassandra.serializers;
import org.apache.cassandra.utils.Pair;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.util.*;
import org.apache.cassandra.utils.ByteBufferUtil;
import org.apache.cassandra.utils.Pair;
public class MapSerializer<K, V> extends CollectionSerializer<Map<K, V>>
{
// interning instances
@ -55,20 +56,14 @@ public class MapSerializer<K, V> extends CollectionSerializer<Map<K, V>>
try
{
ByteBuffer input = bytes.duplicate();
int n = getUnsignedShort(input);
int n = ByteBufferUtil.readShortLength(input);
Map<K, V> m = new LinkedHashMap<K, V>(n);
for (int i = 0; i < n; i++)
{
int sk = getUnsignedShort(input);
byte[] datak = new byte[sk];
input.get(datak);
ByteBuffer kbb = ByteBuffer.wrap(datak);
ByteBuffer kbb = ByteBufferUtil.readBytesWithShortLength(input);
keys.validate(kbb);
int sv = getUnsignedShort(input);
byte[] datav = new byte[sv];
input.get(datav);
ByteBuffer vbb = ByteBuffer.wrap(datav);
ByteBuffer vbb = ByteBufferUtil.readBytesWithShortLength(input);
values.validate(vbb);
m.put(keys.deserialize(kbb), values.deserialize(vbb));

View File

@ -22,6 +22,8 @@ import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.util.*;
import org.apache.cassandra.utils.ByteBufferUtil;
public class SetSerializer<T> extends CollectionSerializer<Set<T>>
{
// interning instances
@ -50,14 +52,11 @@ public class SetSerializer<T> extends CollectionSerializer<Set<T>>
try
{
ByteBuffer input = bytes.duplicate();
int n = getUnsignedShort(input);
int n = ByteBufferUtil.readShortLength(input);
Set<T> l = new LinkedHashSet<T>(n);
for (int i = 0; i < n; i++)
{
int s = getUnsignedShort(input);
byte[] data = new byte[s];
input.get(data);
ByteBuffer databb = ByteBuffer.wrap(data);
ByteBuffer databb = ByteBufferUtil.readBytesWithShortLength(input);
elements.validate(databb);
l.add(elements.deserialize(databb));
}

View File

@ -558,4 +558,41 @@ public class ByteBufferUtil
{
return buf.capacity() > buf.remaining() ? ByteBuffer.wrap(getArray(buf)) : buf;
}
// Doesn't change bb position
public static int getShortLength(ByteBuffer bb, int position)
{
int length = (bb.get(position) & 0xFF) << 8;
return length | (bb.get(position + 1) & 0xFF);
}
// changes bb position
public static int readShortLength(ByteBuffer bb)
{
int length = (bb.get() & 0xFF) << 8;
return length | (bb.get() & 0xFF);
}
// changes bb position
public static void writeShortLength(ByteBuffer bb, int length)
{
bb.put((byte) ((length >> 8) & 0xFF));
bb.put((byte) (length & 0xFF));
}
// changes bb position
public static ByteBuffer readBytes(ByteBuffer bb, int length)
{
ByteBuffer copy = bb.duplicate();
copy.limit(copy.position() + length);
bb.position(bb.position() + length);
return copy;
}
// changes bb position
public static ByteBuffer readBytesWithShortLength(ByteBuffer bb)
{
int length = readShortLength(bb);
return readBytes(bb, length);
}
}