io.warp10.continuum.gts.GTSEncoderTest.java Source code

Java tutorial

Introduction

Here is the source code for io.warp10.continuum.gts.GTSEncoderTest.java

Source

//
//   Copyright 2016  Cityzen Data
//
//   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 io.warp10.continuum.gts;

import io.warp10.continuum.TimeSource;
import io.warp10.continuum.gts.GTSDecoder;
import io.warp10.continuum.gts.GTSEncoder;
import io.warp10.continuum.gts.GTSHelper;
import io.warp10.continuum.gts.GeoTimeSerie;

import java.io.IOException;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.util.Arrays;

import org.bouncycastle.crypto.engines.AESWrapEngine;
import org.bouncycastle.crypto.paddings.PKCS7Padding;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.encoders.Hex;
import org.junit.Assert;
import org.junit.Test;

import com.geoxp.GeoXPLib;

public class GTSEncoderTest {

    @Test
    public void testAddValue_encrypted() throws Exception {
        long now = System.currentTimeMillis() * 1000L;

        byte[] key = new byte[32];

        GTSEncoder encoder = new GTSEncoder(now - 1000000L, key);

        encoder.addValue(now, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION, 1L);
        encoder.addValue(now + 1000000L, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION, 2L);

        byte[] encrypted = encoder.getBytes();
        Assert.assertEquals(GTSEncoder.FLAGS_ENCRYPTED, encrypted[0] & GTSEncoder.FLAGS_MASK_ENCRYPTED);
        Assert.assertEquals(26, encrypted.length);

        //
        // Now check that we can decrypt the payload
        // We can't use n offset different than 0 in unwrap due to BJA-461
        // so we have to copy the data prior to decrypting it.
        //

        AESWrapEngine engine = new AESWrapEngine();
        KeyParameter params = new KeyParameter(key);
        engine.init(false, params);
        byte[] enc = new byte[24];
        System.arraycopy(encrypted, 2, enc, 0, 24);
        byte[] decrypted = engine.unwrap(enc, 0, 24);

        //
        // Now decode the decrypted data
        //

        PKCS7Padding padding = new PKCS7Padding();
        GTSDecoder decoder = new GTSDecoder(now - 1000000L,
                ByteBuffer.wrap(decrypted, 0, decrypted.length - padding.padCount(decrypted)));

        decoder.next();
        Assert.assertEquals(now, decoder.getTimestamp());
        Assert.assertEquals(GeoTimeSerie.NO_LOCATION, decoder.getLocation());
        Assert.assertEquals(GeoTimeSerie.NO_ELEVATION, decoder.getElevation());
        Assert.assertEquals(1L, decoder.getValue());

        decoder.next();
        Assert.assertEquals(now + 1000000L, decoder.getTimestamp());
        Assert.assertEquals(GeoTimeSerie.NO_LOCATION, decoder.getLocation());
        Assert.assertEquals(GeoTimeSerie.NO_ELEVATION, decoder.getElevation());
        Assert.assertEquals(2L, decoder.getValue());
    }

    @Test
    public void testGetDecoder() throws Exception {
        long now = System.currentTimeMillis() * 1000L;
        byte[] key = new byte[32];
        GTSEncoder encoder = new GTSEncoder(now - 1000000L, key);

        encoder.addValue(now, 111L, 11L, new BigDecimal("1.11"));
        encoder.addValue(now + 1000000L, 222L, 22L, new BigDecimal("2.22"));

        GTSDecoder decoder = encoder.getDecoder();

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(now, decoder.getTimestamp());
        Assert.assertEquals(111L, decoder.getLocation());
        Assert.assertEquals(11L, decoder.getElevation());
        Assert.assertEquals(new BigDecimal("1.11"), decoder.getValue());

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(now + 1000000L, decoder.getTimestamp());
        Assert.assertEquals(222L, decoder.getLocation());
        Assert.assertEquals(22L, decoder.getElevation());
        Assert.assertEquals(new BigDecimal("2.22"), decoder.getValue());

        Assert.assertFalse(decoder.next());
    }

    @Test
    public void testMerge() throws Exception {
        long now = System.currentTimeMillis() * 1000L;
        byte[] key = new byte[32];
        GTSEncoder encoder1 = new GTSEncoder(now - 1000000L, key);

        encoder1.addValue(now, 111L, 11L, new BigDecimal("1.11"));
        encoder1.addValue(now + 1000000L, 222L, 22L, new BigDecimal("2.22"));

        GTSEncoder encoder2 = new GTSEncoder(now - 500000L);

        encoder2.addValue(now, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION, new BigDecimal("3.33"));
        encoder2.addValue(now + 500000L, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION,
                new BigDecimal("4.44"));

        encoder1.merge(encoder2);

        GTSDecoder decoder = encoder1.getDecoder();

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(now, decoder.getTimestamp());
        Assert.assertEquals(111L, decoder.getLocation());
        Assert.assertEquals(11L, decoder.getElevation());
        Assert.assertEquals(new BigDecimal("1.11"), decoder.getValue());

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(now + 1000000L, decoder.getTimestamp());
        Assert.assertEquals(222L, decoder.getLocation());
        Assert.assertEquals(22L, decoder.getElevation());
        Assert.assertEquals(new BigDecimal("2.22"), decoder.getValue());

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(now, decoder.getTimestamp());
        Assert.assertEquals(GeoTimeSerie.NO_LOCATION, decoder.getLocation());
        Assert.assertEquals(GeoTimeSerie.NO_ELEVATION, decoder.getElevation());
        Assert.assertEquals(new BigDecimal("3.33"), decoder.getValue());

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(now + 500000L, decoder.getTimestamp());
        Assert.assertEquals(GeoTimeSerie.NO_LOCATION, decoder.getLocation());
        Assert.assertEquals(GeoTimeSerie.NO_ELEVATION, decoder.getElevation());
        Assert.assertEquals(new BigDecimal("4.44"), decoder.getValue());

        Assert.assertFalse(decoder.next());

        //
        // Now do the same with encoders which have the same base, triggering the use of the fastpath
        //

        encoder1 = new GTSEncoder(now - 1000000L, key);
        encoder1.addValue(now, 111L, 11L, new BigDecimal("1.11"));
        encoder1.addValue(now + 1000000L, 222L, 22L, new BigDecimal("2.22"));

        encoder2 = new GTSEncoder(now - 1000000L, key);
        encoder2.addValue(now, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION, new BigDecimal("3.33"));
        encoder2.addValue(now + 500000L, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION,
                new BigDecimal("4.44"));

        encoder1.merge(encoder2);

        decoder = encoder1.getDecoder();

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(now, decoder.getTimestamp());
        Assert.assertEquals(111L, decoder.getLocation());
        Assert.assertEquals(11L, decoder.getElevation());
        Assert.assertEquals(new BigDecimal("1.11"), decoder.getValue());

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(now + 1000000L, decoder.getTimestamp());
        Assert.assertEquals(222L, decoder.getLocation());
        Assert.assertEquals(22L, decoder.getElevation());
        Assert.assertEquals(new BigDecimal("2.22"), decoder.getValue());

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(now, decoder.getTimestamp());
        Assert.assertEquals(GeoTimeSerie.NO_LOCATION, decoder.getLocation());
        Assert.assertEquals(GeoTimeSerie.NO_ELEVATION, decoder.getElevation());
        Assert.assertEquals(new BigDecimal("3.33"), decoder.getValue());

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(now + 500000L, decoder.getTimestamp());
        Assert.assertEquals(GeoTimeSerie.NO_LOCATION, decoder.getLocation());
        Assert.assertEquals(GeoTimeSerie.NO_ELEVATION, decoder.getElevation());
        Assert.assertEquals(new BigDecimal("4.44"), decoder.getValue());

        Assert.assertFalse(decoder.next());

    }

    @Test
    public void testMerge_FastPath() throws Exception {
        //
        // This test is here to ensure we correctly copy the last value/ts/loc/elev when merging using
        // the fast path, if we don't, the next value entered might get delta encoded with the wrong
        // reference thus leading to an incorrect value when decoding.
        //

        GTSEncoder encoder1 = new GTSEncoder(0L);
        GTSEncoder encoder2 = new GTSEncoder(0L);

        encoder1.addValue(1L, 1L, 1L, 100);
        encoder1.addValue(2L, 2L, 2L, 101);

        encoder2.addValue(3L, 3L, 3L, 102);

        // Merge encoder2 into encoder1
        encoder1.merge(encoder2);

        // Now add a value to encoder1
        encoder1.addValue(4L, 4L, 4L, 103);

        // Decode values, ensuring they are all correct
        GTSDecoder decoder = encoder1.getDecoder();

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(1L, decoder.getTimestamp());
        Assert.assertEquals(1L, decoder.getLocation());
        Assert.assertEquals(1L, decoder.getElevation());
        Assert.assertEquals(100L, decoder.getValue());

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(2L, decoder.getTimestamp());
        Assert.assertEquals(2L, decoder.getLocation());
        Assert.assertEquals(2L, decoder.getElevation());
        Assert.assertEquals(101L, decoder.getValue());

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(3L, decoder.getTimestamp());
        Assert.assertEquals(3L, decoder.getLocation());
        Assert.assertEquals(3L, decoder.getElevation());
        Assert.assertEquals(102L, decoder.getValue());

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(4L, decoder.getTimestamp());
        Assert.assertEquals(4L, decoder.getLocation());
        Assert.assertEquals(4L, decoder.getElevation());
        Assert.assertEquals(103L, decoder.getValue());

    }

    @Test
    public void testDelete() throws Exception {
        GTSEncoder encoder = new GTSEncoder(0L);

        encoder.addValue(1L, 2L, 3L, null);

        GTSDecoder decoder = encoder.getDecoder();

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(1L, decoder.getTimestamp());
        Assert.assertEquals(GeoTimeSerie.NO_LOCATION, decoder.getLocation());
        Assert.assertEquals(GeoTimeSerie.NO_ELEVATION, decoder.getElevation());
        Assert.assertNull(decoder.getValue());
        Assert.assertFalse(decoder.next());
    }

    @Test
    public void testAddValue_IntermittentLocation() throws Exception {
        GTSEncoder encoder = new GTSEncoder(0L);

        encoder.addValue(1L, 1L, 10L, 1L);
        encoder.addValue(2L, 2L, 20L, 2L);
        encoder.addValue(3L, GeoTimeSerie.NO_LOCATION, 30L, 3L);
        encoder.addValue(4L, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION, 4L);
        encoder.addValue(5L, 5L, 50L, 5L);

        GTSDecoder decoder = encoder.getDecoder();

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(1L, decoder.getLocation());
        Assert.assertEquals(10L, decoder.getElevation());
        Assert.assertTrue(decoder.next());
        Assert.assertEquals(2L, decoder.getLocation());
        Assert.assertEquals(20L, decoder.getElevation());
        Assert.assertTrue(decoder.next());
        Assert.assertEquals(GeoTimeSerie.NO_LOCATION, decoder.getLocation());
        Assert.assertEquals(30L, decoder.getElevation());
        Assert.assertTrue(decoder.next());
        Assert.assertEquals(GeoTimeSerie.NO_LOCATION, decoder.getLocation());
        Assert.assertEquals(GeoTimeSerie.NO_ELEVATION, decoder.getElevation());
        Assert.assertTrue(decoder.next());
        Assert.assertEquals(5L, decoder.getLocation());
        Assert.assertEquals(50L, decoder.getElevation());
    }

    @Test
    public void testEncoding() throws Exception {
        GTSEncoder encoder = new GTSEncoder(0L);

        encoder.addValue(0, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION, 1);

        Assert.assertEquals("2c02", new String(Hex.encode(encoder.getBytes())));

        //
        // Timestamp which will be raw encoded
        //

        encoder = new GTSEncoder(0L);
        encoder.addValue(0x0123456789abcdefL, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION, 1);
        Assert.assertEquals("6c0123456789abcdef02", new String(Hex.encode(encoder.getBytes())));

        //
        // Timestamp which will be delta encoded from base
        //

        encoder = new GTSEncoder(0L);
        encoder.addValue((1L << 48) - 1L, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION, 1);
        Assert.assertEquals("4cfeffffffffff7f02", new String(Hex.encode(encoder.getBytes())));

        //
        // Two values, delta encoding of ts and values
        //

        encoder = new GTSEncoder(0L);
        encoder.addValue(0L, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION, 1);
        encoder.addValue(1L, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION, 2);
        Assert.assertEquals("2c024e0202", new String(Hex.encode(encoder.getBytes())));

        //
        // Two values, delta encoding of ts, identical values
        //

        encoder = new GTSEncoder(0L);
        encoder.addValue(0L, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION, 1);
        encoder.addValue(1L, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION, 1);
        Assert.assertEquals("2c024902", new String(Hex.encode(encoder.getBytes())));

        //
        // Double value, IEEE754
        //

        encoder = new GTSEncoder(0L);
        encoder.addValue(0L, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION, Double.NaN);
        Assert.assertEquals("347ff8000000000000", new String(Hex.encode(encoder.getBytes())));

        //
        // BigDecimal value, custom encoding
        //

        encoder = new GTSEncoder(0L);
        encoder.addValue(0L, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION, new BigDecimal("1.0"));
        Assert.assertEquals("300002", new String(Hex.encode(encoder.getBytes())));

        //
        // Location and delta location
        //

        encoder = new GTSEncoder(0L);
        encoder.addValue(0L, 0xb000000000000001L, GeoTimeSerie.NO_ELEVATION, 0);
        encoder.addValue(1L, 0xb000000000000002L, GeoTimeSerie.NO_ELEVATION, 1);
        Assert.assertEquals("ac40b00000000000000100cc60020202", new String(Hex.encode(encoder.getBytes())));

        //
        // Elevation and delta elevation
        //

        encoder = new GTSEncoder(0L);
        encoder.addValue(0L, GeoTimeSerie.NO_LOCATION, 0x7000000000000001L, 0);
        encoder.addValue(1L, GeoTimeSerie.NO_LOCATION, 0x7000000000000002L, 1);
        Assert.assertEquals("ac08700000000000000100cc0e020202", new String(Hex.encode(encoder.getBytes())));

        //
        // Location + Elevation
        //

        encoder = new GTSEncoder(0L);
        encoder.addValue(0L, 0xb000000000000001L, 0x7000000000000001L, 0);
        encoder.addValue(1L, 0xb000000000000002L, 0x7000000000000002L, 1);
        Assert.assertEquals("ac48b000000000000001700000000000000100cc6e02020202",
                new String(Hex.encode(encoder.getBytes())));

    }

    @Test
    public void testEncodingConsistency() throws Exception {
        GTSEncoder encoder = null;

        for (long base = 0; base < 2; base++) {
            encoder = new GTSEncoder(base);

            for (int i = 0; i < 100000; i++) {
                encoder.addValue(i, i * 10, i * 100, i * 1000);
            }

            GTSDecoder decoder = encoder.getDecoder();

            for (int i = 0; i < encoder.getCount(); i++) {
                Assert.assertTrue(decoder.next());
                Assert.assertEquals(i, decoder.getTimestamp());
                Assert.assertEquals(i * 10L, decoder.getLocation());
                Assert.assertEquals(i * 100L, decoder.getElevation());
                Assert.assertEquals(i * 1000L, decoder.getValue());
            }

            Assert.assertFalse(decoder.next());
        }
    }

    @Test
    public void testSafeDelta() throws Exception {
        // Create an encoder with a single value
        GTSEncoder encoder = new GTSEncoder(0L);

        encoder.addValue(1L, 2L, 3L, 4L);

        byte[] bytes = encoder.getBytes();

        // Reallocate encoder
        encoder = new GTSEncoder(0L, null, bytes);

        Assert.assertEquals(13, encoder.size());

        // Add values, adding location and elevation progressively

        encoder.addValue(2L, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION, 4L);
        Assert.assertEquals(23, encoder.size());
        encoder.addValue(3L, 4L, GeoTimeSerie.NO_ELEVATION, 4L);
        Assert.assertEquals(34, encoder.size());
        encoder.addValue(4L, GeoTimeSerie.NO_LOCATION, 4L, 4L);
        Assert.assertEquals(38, encoder.size());
        encoder.addValue(5L, 6L, 4L, 9L);
        Assert.assertEquals(50, encoder.size());
        encoder.addValue(6L, 4L, 4L, 9L);
        Assert.assertEquals(54, encoder.size());
        encoder.addValue(7L, 4L, 4L, 9L);
        Assert.assertEquals(57, encoder.size());

        GTSDecoder decoder = encoder.getDecoder();

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(1L, decoder.getTimestamp());
        Assert.assertEquals(2L, decoder.getLocation());
        Assert.assertEquals(3L, decoder.getElevation());
        Assert.assertEquals(4L, decoder.getValue());

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(2L, decoder.getTimestamp());
        Assert.assertEquals(GeoTimeSerie.NO_LOCATION, decoder.getLocation());
        Assert.assertEquals(GeoTimeSerie.NO_ELEVATION, decoder.getElevation());
        Assert.assertEquals(4L, decoder.getValue());

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(3L, decoder.getTimestamp());
        Assert.assertEquals(4L, decoder.getLocation());
        Assert.assertEquals(GeoTimeSerie.NO_ELEVATION, decoder.getElevation());
        Assert.assertEquals(4L, decoder.getValue());

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(4L, decoder.getTimestamp());
        Assert.assertEquals(GeoTimeSerie.NO_LOCATION, decoder.getLocation());
        Assert.assertEquals(4L, decoder.getElevation());
        Assert.assertEquals(4L, decoder.getValue());

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(5L, decoder.getTimestamp());
        Assert.assertEquals(6L, decoder.getLocation());
        Assert.assertEquals(4L, decoder.getElevation());
        Assert.assertEquals(9L, decoder.getValue());

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(6L, decoder.getTimestamp());
        Assert.assertEquals(4L, decoder.getLocation());
        Assert.assertEquals(4L, decoder.getElevation());
        Assert.assertEquals(9L, decoder.getValue());

        Assert.assertTrue(decoder.next());
        Assert.assertEquals(7L, decoder.getTimestamp());
        Assert.assertEquals(4L, decoder.getLocation());
        Assert.assertEquals(4L, decoder.getElevation());
        Assert.assertEquals(9L, decoder.getValue());
    }

    @Test
    public void testToBlock() throws IOException {
        GTSEncoder encoder = new GTSEncoder(12345678);

        int n = 2;

        for (int i = 0; i < n; i++) {
            encoder.addValue(i * 1000, i * 12345678, i * 87654321, i * Math.PI);
        }

        System.out.println(encoder.size());

        long nano = System.nanoTime();
        byte[] block = encoder.toBlock(true);
        System.out.println((System.nanoTime() - nano) / 1000000.0D);
        System.out.println(block.length);

        nano = System.nanoTime();

        GTSDecoder decoder = GTSDecoder.fromBlock(block, null);
        System.out.println((System.nanoTime() - nano) / 1000000.0D);
        GTSDecoder orig = encoder.getDecoder();

        while (true) {
            boolean copy = decoder.next();
            boolean org = orig.next();

            Assert.assertEquals(copy, org);

            if (!copy) {
                break;
            }
            Assert.assertEquals(orig.getTimestamp(), decoder.getTimestamp());
            Assert.assertEquals(orig.getLocation(), decoder.getLocation());
            Assert.assertEquals(orig.getElevation(), decoder.getElevation());
            Assert.assertEquals(orig.getValue(), decoder.getValue());
        }
    }

    @Test
    public void testWARP50() throws Exception {
        GTSEncoder encoder = new GTSEncoder(0L);

        encoder = GTSHelper.parse(encoder, "0// gts{} 10000000.000000");
        encoder = GTSHelper.parse(encoder, "0// gts{} -20000000.000000");
        encoder = GTSHelper.parse(encoder, "0// gts{} 10000000.000000");
        encoder = GTSHelper.parse(encoder, "0// gts{} -20000000.000000");

        GTSDecoder decoder = encoder.getDecoder();

        Assert.assertTrue(decoder.next());
        Assert.assertTrue(decoder.getValue() instanceof BigDecimal);
        Assert.assertEquals(10000000.0D, ((BigDecimal) decoder.getValue()).doubleValue(), 0.01D);

        Assert.assertTrue(decoder.next());
        Assert.assertTrue(decoder.getValue() instanceof Double);
        Assert.assertEquals(-20000000.0D, ((Double) decoder.getValue()).doubleValue(), 0.01D);

        Assert.assertTrue(decoder.next());
        Assert.assertTrue(decoder.getValue() instanceof BigDecimal);
        Assert.assertEquals(10000000.0D, ((BigDecimal) decoder.getValue()).doubleValue(), 0.01D);

        Assert.assertTrue(decoder.next());
        Assert.assertTrue(decoder.getValue() instanceof Double);
        Assert.assertEquals(-20000000.0D, ((Double) decoder.getValue()).doubleValue(), 0.01D);
    }

    @Test
    public void testResetLONG() throws Exception {
        GTSEncoder encoder = new GTSEncoder(0L);

        encoder.addValue(0L, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION, 1L);
        encoder.addValue(1L, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION, 1L);

        GTSDecoder decoder = encoder.getDecoder();
        decoder.next();
        decoder.next();

        encoder.reset(decoder.getEncoder());

        decoder = encoder.getDecoder();

        decoder.next();

        Assert.assertEquals(1L, decoder.getTimestamp());
        Assert.assertEquals(1L, decoder.getValue());
    }

    @Test
    public void testResetDOUBLE() throws Exception {
        GTSEncoder encoder = new GTSEncoder(0L);

        encoder.addValue(0L, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION, 1.0D);
        encoder.addValue(1L, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION, 1.0D);

        GTSDecoder decoder = encoder.getDecoder();
        decoder.next();
        decoder.next();

        encoder.reset(decoder.getEncoder());

        decoder = encoder.getDecoder();

        decoder.next();

        Assert.assertEquals(1L, decoder.getTimestamp());
        Assert.assertEquals(1.0D, (double) decoder.getValue(), 0.000000000001D);
    }

    @Test
    public void testResetSTRING() throws Exception {
        GTSEncoder encoder = new GTSEncoder(0L);

        encoder.addValue(0L, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION, "1");
        encoder.addValue(1L, GeoTimeSerie.NO_LOCATION, GeoTimeSerie.NO_ELEVATION, "1");

        GTSDecoder decoder = encoder.getDecoder();
        decoder.next();
        decoder.next();

        encoder.reset(decoder.getEncoder());

        decoder = encoder.getDecoder();

        decoder.next();

        Assert.assertEquals(1.0D, decoder.getTimestamp(), 0.000000000001D);
        Assert.assertEquals("1", decoder.getValue().toString());
    }
}