예제 #1
0
        public static void EncodeValue(PropertyBlock block, int keyId, Value value, DynamicRecordAllocator stringAllocator, DynamicRecordAllocator arrayAllocator, bool allowStorePointsAndTemporal)
        {
            if (value is ArrayValue)
            {
                object asObject = value.AsObject();

                // Try short array first, i.e. inlined in the property block
                if (ShortArray.encode(keyId, asObject, block, PropertyType.PayloadSize))
                {
                    return;
                }

                // Fall back to dynamic array store
                IList <DynamicRecord> arrayRecords = new List <DynamicRecord>();
                AllocateArrayRecords(arrayRecords, asObject, arrayAllocator, allowStorePointsAndTemporal);
                SetSingleBlockValue(block, keyId, PropertyType.Array, Iterables.first(arrayRecords).Id);
                foreach (DynamicRecord valueRecord in arrayRecords)
                {
                    valueRecord.SetType(PropertyType.Array.intValue());
                }
                block.ValueRecords = arrayRecords;
            }
            else
            {
                value.WriteTo(new PropertyBlockValueWriter(block, keyId, stringAllocator, allowStorePointsAndTemporal));
            }
        }
예제 #2
0
        private static sbyte[] CreateBitCompactedArray(ShortArray type, object array, int offsetBytes)
        {
            Type componentType        = array.GetType().GetElementType();
            bool isPrimitiveByteArray = componentType.Equals(Byte.TYPE);
            bool isByteArray          = componentType.Equals(typeof(Byte)) || isPrimitiveByteArray;
            int  arrayLength          = Array.getLength(array);
            int  requiredBits         = isByteArray ? (sizeof(sbyte) * 8) : type.calculateRequiredBitsForArray(array, arrayLength);
            int  totalBits            = requiredBits * arrayLength;
            int  bitsUsedInLastByte   = totalBits % 8;

            bitsUsedInLastByte = bitsUsedInLastByte == 0 ? 8 : bitsUsedInLastByte;
            if (isByteArray)
            {
                return(CreateBitCompactedByteArray(type, isPrimitiveByteArray, array, bitsUsedInLastByte, requiredBits, offsetBytes));
            }
            else
            {
                int numberOfBytes = (totalBits - 1) / 8 + 1;
                numberOfBytes += NUMBER_HEADER_SIZE;                         // type + rest + requiredBits header. TODO no need to use full bytes
                Bits bits = Bits.bits(numberOfBytes);
                bits.Put(( sbyte )type.intValue());
                bits.Put(( sbyte )bitsUsedInLastByte);
                bits.Put(( sbyte )requiredBits);
                type.writeAll(array, arrayLength, requiredBits, bits);
                return(bits.AsBytes(offsetBytes));
            }
        }
예제 #3
0
        private void AssertCanEncodeAndDecodeToSameValue(object value, int payloadSize)
        {
            PropertyBlock target  = new PropertyBlock();
            bool          encoded = ShortArray.encode(0, value, target, payloadSize);

            assertTrue(encoded);
            assertEquals(Values.of(value), ShortArray.decode(target));
        }
예제 #4
0
        public static Value GetRightArray(Pair <sbyte[], sbyte[]> data)
        {
            sbyte[] header = data.First();
            sbyte[] bArray = data.Other();
            sbyte   typeId = header[0];

            if (typeId == PropertyType.String.intValue())
            {
                ByteBuffer headerBuffer = ByteBuffer.wrap(header, 1, header.Length - 1);
                int        arrayLength  = headerBuffer.Int;
                string[]   result       = new string[arrayLength];

                ByteBuffer dataBuffer = ByteBuffer.wrap(bArray);
                for (int i = 0; i < arrayLength; i++)
                {
                    int     byteLength      = dataBuffer.Int;
                    sbyte[] stringByteArray = new sbyte[byteLength];
                    dataBuffer.get(stringByteArray);
                    result[i] = PropertyStore.DecodeString(stringByteArray);
                }
                return(Values.stringArray(result));
            }
            else if (typeId == PropertyType.Geometry.intValue())
            {
                GeometryType.GeometryHeader geometryHeader = GeometryType.GeometryHeader.fromArrayHeaderBytes(header);
                return(GeometryType.decodeGeometryArray(geometryHeader, bArray));
            }
            else if (typeId == PropertyType.Temporal.intValue())
            {
                TemporalType.TemporalHeader temporalHeader = TemporalType.TemporalHeader.fromArrayHeaderBytes(header);
                return(TemporalType.decodeTemporalArray(temporalHeader, bArray));
            }
            else
            {
                ShortArray type = ShortArray.typeOf(typeId);
                int        bitsUsedInLastByte = header[1];
                int        requiredBits       = header[2];
                if (requiredBits == 0)
                {
                    return(type.createEmptyArray());
                }
                if (type == ShortArray.Byte && requiredBits == (sizeof(sbyte) * 8))
                {                         // Optimization for byte arrays (probably large ones)
                    return(Values.byteArray(bArray));
                }
                else
                {                         // Fallback to the generic approach, which is a slower
                    Bits bits   = Bits.bitsFromBytes(bArray);
                    int  length = (bArray.Length * 8 - (8 - bitsUsedInLastByte)) / requiredBits;
                    return(type.createArray(length, bits, requiredBits));
                }
            }
        }
예제 #5
0
        private static sbyte[] CreateUncompactedArray(ShortArray type, object array, int offsetBytes)
        {
            int arrayLength     = Array.getLength(array);
            int bytesPerElement = type.maxBits / 8;

            sbyte[] bytes = new sbyte[NUMBER_HEADER_SIZE + bytesPerElement * arrayLength + offsetBytes];
            bytes[offsetBytes + 0] = ( sbyte )type.intValue();
            bytes[offsetBytes + 1] = ( sbyte )8;
            bytes[offsetBytes + 2] = ( sbyte )type.maxBits;
            type.writeAll(array, bytes, NUMBER_HEADER_SIZE + offsetBytes);
            return(bytes);
        }
예제 #6
0
        public static sbyte[] EncodeFromNumbers(object array, int offsetBytes)
        {
            ShortArray type = ShortArray.typeOf(array);

            if (type == null)
            {
                throw new System.ArgumentException(array + " not a valid array type.");
            }

            if (type == ShortArray.Double || type == ShortArray.Float)
            {
                // Skip array compaction for floating point numbers where compaction makes very little difference
                return(CreateUncompactedArray(type, array, offsetBytes));
            }
            else
            {
                return(CreateBitCompactedArray(type, array, offsetBytes));
            }
        }
예제 #7
0
        private static sbyte[] CreateBitCompactedByteArray(ShortArray type, bool isPrimitiveByteArray, object array, int bitsUsedInLastByte, int requiredBits, int offsetBytes)
        {
            int arrayLength = Array.getLength(array);

            sbyte[] bytes = new sbyte[NUMBER_HEADER_SIZE + arrayLength + offsetBytes];
            bytes[offsetBytes + 0] = ( sbyte )type.intValue();
            bytes[offsetBytes + 1] = ( sbyte )bitsUsedInLastByte;
            bytes[offsetBytes + 2] = ( sbyte )requiredBits;
            if (isPrimitiveByteArray)
            {
                arraycopy(array, 0, bytes, NUMBER_HEADER_SIZE + offsetBytes, arrayLength);
            }
            else
            {
                sbyte?[] source = ( sbyte?[] )array;
                for (int i = 0; i < source.Length; i++)
                {
                    bytes[NUMBER_HEADER_SIZE + offsetBytes + i] = source[i].Value;
                }
            }
            return(bytes);
        }
예제 #8
0
        public static ArrayValue ReadArrayFromBuffer(ByteBuffer buffer)
        {
            if (buffer.limit() <= 0)
            {
                throw new System.InvalidOperationException("Given buffer is empty");
            }

            sbyte typeId = buffer.get();

            buffer.order(ByteOrder.BIG_ENDIAN);
            try
            {
                if (typeId == PropertyType.String.intValue())
                {
                    int      arrayLength = buffer.Int;
                    string[] result      = new string[arrayLength];

                    for (int i = 0; i < arrayLength; i++)
                    {
                        int byteLength = buffer.Int;
                        result[i] = UTF8.decode(buffer.array(), buffer.position(), byteLength);
                        buffer.position(buffer.position() + byteLength);
                    }
                    return(Values.stringArray(result));
                }
                else if (typeId == PropertyType.Geometry.intValue())
                {
                    GeometryType.GeometryHeader header = GeometryType.GeometryHeader.fromArrayHeaderByteBuffer(buffer);
                    sbyte[] byteArray = new sbyte[buffer.limit() - buffer.position()];
                    buffer.get(byteArray);
                    return(GeometryType.decodeGeometryArray(header, byteArray));
                }
                else if (typeId == PropertyType.Temporal.intValue())
                {
                    TemporalType.TemporalHeader header = TemporalType.TemporalHeader.fromArrayHeaderByteBuffer(buffer);
                    sbyte[] byteArray = new sbyte[buffer.limit() - buffer.position()];
                    buffer.get(byteArray);
                    return(TemporalType.decodeTemporalArray(header, byteArray));
                }
                else
                {
                    ShortArray type = ShortArray.typeOf(typeId);
                    int        bitsUsedInLastByte = buffer.get();
                    int        requiredBits       = buffer.get();
                    if (requiredBits == 0)
                    {
                        return(type.createEmptyArray());
                    }
                    if (type == ShortArray.Byte && requiredBits == (sizeof(sbyte) * 8))
                    {                              // Optimization for byte arrays (probably large ones)
                        sbyte[] byteArray = new sbyte[buffer.limit() - buffer.position()];
                        buffer.get(byteArray);
                        return(Values.byteArray(byteArray));
                    }
                    else
                    {                              // Fallback to the generic approach, which is a slower
                        Bits bits   = Bits.bitsFromBytes(buffer.array(), buffer.position());
                        int  length = ((buffer.limit() - buffer.position()) * 8 - (8 - bitsUsedInLastByte)) / requiredBits;
                        return(type.createArray(length, bits, requiredBits));
                    }
                }
            }
            finally
            {
                buffer.order(ByteOrder.LITTLE_ENDIAN);
            }
        }
예제 #9
0
 private void AssertCanNotEncode(object intArray, int payloadSize)
 {
     assertFalse(ShortArray.encode(0, intArray, new PropertyBlock(), payloadSize));
 }