mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-14 17:43:34 +08:00
Add more tests for compression
Unit tests for different data sequences, and SQL test for float4.
This commit is contained in:
parent
f5db023152
commit
e92d5ba748
@ -155,8 +155,6 @@ deltadelta_compressor_append_null_value(Compressor *compressor)
|
||||
delta_delta_compressor_append_null(extended->internal);
|
||||
}
|
||||
|
||||
static void *delta_delta_compressor_finish(DeltaDeltaCompressor *compressor);
|
||||
|
||||
static void *
|
||||
deltadelta_compressor_finish_and_reset(Compressor *compressor)
|
||||
{
|
||||
@ -331,7 +329,7 @@ delta_delta_from_parts(uint64 last_value, uint64 last_delta, Simple8bRleSerializ
|
||||
return compressed;
|
||||
}
|
||||
|
||||
static void *
|
||||
void *
|
||||
delta_delta_compressor_finish(DeltaDeltaCompressor *compressor)
|
||||
{
|
||||
Simple8bRleSerialized *deltas = simple8brle_compressor_finish(&compressor->delta_delta);
|
||||
|
@ -32,6 +32,7 @@ extern Compressor *delta_delta_compressor_for_type(Oid element_type);
|
||||
extern DeltaDeltaCompressor *delta_delta_compressor_alloc(void);
|
||||
extern void delta_delta_compressor_append_null(DeltaDeltaCompressor *compressor);
|
||||
extern void delta_delta_compressor_append_value(DeltaDeltaCompressor *compressor, int64 next_val);
|
||||
extern void *delta_delta_compressor_finish(DeltaDeltaCompressor *compressor);
|
||||
|
||||
extern DecompressionIterator *
|
||||
delta_delta_decompression_iterator_from_datum_forward(Datum deltadelta_compressed,
|
||||
|
@ -262,13 +262,13 @@ gorilla_compressor_alloc(void)
|
||||
return compressor;
|
||||
}
|
||||
|
||||
/* This function is used for testing only. */
|
||||
Datum
|
||||
tsl_gorilla_compressor_append(PG_FUNCTION_ARGS)
|
||||
{
|
||||
MemoryContext old_context;
|
||||
MemoryContext agg_context;
|
||||
GorillaCompressor *compressor =
|
||||
(GorillaCompressor *) (PG_ARGISNULL(0) ? NULL : PG_GETARG_POINTER(0));
|
||||
Compressor *compressor = (Compressor *) (PG_ARGISNULL(0) ? NULL : PG_GETARG_POINTER(0));
|
||||
|
||||
if (!AggCheckCallContext(fcinfo, &agg_context))
|
||||
{
|
||||
@ -279,20 +279,38 @@ tsl_gorilla_compressor_append(PG_FUNCTION_ARGS)
|
||||
old_context = MemoryContextSwitchTo(agg_context);
|
||||
|
||||
if (compressor == NULL)
|
||||
compressor = gorilla_compressor_alloc();
|
||||
{
|
||||
compressor = gorilla_compressor_for_type(get_fn_expr_argtype(fcinfo->flinfo, 1));
|
||||
}
|
||||
|
||||
if (PG_ARGISNULL(1))
|
||||
gorilla_compressor_append_null(compressor);
|
||||
compressor->append_null(compressor);
|
||||
else
|
||||
{
|
||||
double next_val = PG_GETARG_FLOAT8(1);
|
||||
gorilla_compressor_append_value(compressor, double_get_bits(next_val));
|
||||
compressor->append_val(compressor, PG_GETARG_DATUM(1));
|
||||
}
|
||||
|
||||
MemoryContextSwitchTo(old_context);
|
||||
PG_RETURN_POINTER(compressor);
|
||||
}
|
||||
|
||||
/* This function is used for testing only. */
|
||||
Datum
|
||||
tsl_gorilla_compressor_finish(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Compressor *compressor = (Compressor *) (PG_ARGISNULL(0) ? NULL : PG_GETARG_POINTER(0));
|
||||
|
||||
if (compressor == NULL)
|
||||
PG_RETURN_NULL();
|
||||
|
||||
void *compressed = compressor->finish(compressor);
|
||||
|
||||
if (compressed == NULL)
|
||||
PG_RETURN_NULL();
|
||||
|
||||
PG_RETURN_POINTER(compressed);
|
||||
}
|
||||
|
||||
void
|
||||
gorilla_compressor_append_null(GorillaCompressor *compressor)
|
||||
{
|
||||
@ -440,22 +458,6 @@ gorilla_compressor_finish(GorillaCompressor *compressor)
|
||||
return compressed_gorilla_data_serialize(&data);
|
||||
}
|
||||
|
||||
Datum
|
||||
tsl_gorilla_compressor_finish(PG_FUNCTION_ARGS)
|
||||
{
|
||||
GorillaCompressor *compressor =
|
||||
(GorillaCompressor *) (PG_ARGISNULL(0) ? NULL : PG_GETARG_POINTER(0));
|
||||
void *compressed;
|
||||
if (compressor == NULL)
|
||||
PG_RETURN_NULL();
|
||||
|
||||
compressed = gorilla_compressor_finish(compressor);
|
||||
if (compressed == NULL)
|
||||
PG_RETURN_NULL();
|
||||
|
||||
PG_RETURN_POINTER(compressed);
|
||||
}
|
||||
|
||||
/*******************************
|
||||
*** DecompressionIterator ***
|
||||
*******************************/
|
||||
|
File diff suppressed because one or more lines are too long
@ -9,14 +9,16 @@ AS :TSL_MODULE_PATHNAME LANGUAGE C VOLATILE;
|
||||
\ir include/compression_utils.sql
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
||||
|
||||
-- helper function: float -> pseudorandom float [0..1].
|
||||
create or replace function mix(x float4) returns float4 as $$ select ((hashfloat4(x) / (pow(2., 31) - 1) + 1) / 2)::float4 $$ language sql;
|
||||
create or replace function mix(x timestamptz) returns float4 as $$ select mix(extract(epoch from x)::float4) $$ language sql;
|
||||
|
||||
------------------
|
||||
-- C unit tests --
|
||||
------------------
|
||||
|
||||
SELECT ts_test_compression();
|
||||
|
||||
\ir include/rand_generator.sql
|
||||
|
||||
------------------------
|
||||
-- BIGINT Compression --
|
||||
------------------------
|
||||
@ -32,7 +34,7 @@ SELECT
|
||||
\set DECOMPRESS_REVERSE_CMD _timescaledb_internal.decompress_reverse(c::_timescaledb_internal.compressed_data, NULL::BIGINT)
|
||||
|
||||
-- random order
|
||||
CREATE TABLE base_ints AS SELECT row_number() OVER() as rn, item::bigint FROM (select sub.item from (SELECT generate_series(1, 1000) item) as sub ORDER BY gen_rand_minstd()) sub;
|
||||
CREATE TABLE base_ints AS SELECT row_number() OVER() as rn, item::bigint FROM (select sub.item from (SELECT generate_series(1, 1000) item) as sub ORDER BY mix(item)) sub;
|
||||
\ir include/compression_test.sql
|
||||
DROP TABLE base_ints;
|
||||
|
||||
@ -90,7 +92,7 @@ DROP TABLE base_ints;
|
||||
-- INT Compression --
|
||||
------------------------
|
||||
|
||||
CREATE TABLE base_ints AS SELECT row_number() OVER() as rn, item::int FROM (select sub.item from (SELECT generate_series(1, 1000) item) as sub ORDER BY gen_rand_minstd()) sub;
|
||||
CREATE TABLE base_ints AS SELECT row_number() OVER() as rn, item::int FROM (select sub.item from (SELECT generate_series(1, 1000) item) as sub ORDER BY mix(item)) sub;
|
||||
SELECT
|
||||
$$
|
||||
select item::bigint from base_ints order by rn
|
||||
@ -117,11 +119,74 @@ SELECT
|
||||
\set DECOMPRESS_REVERSE_CMD _timescaledb_internal.decompress_reverse(c::_timescaledb_internal.compressed_data, NULL::TIMESTAMPTZ)
|
||||
|
||||
CREATE TABLE base_time AS SELECT row_number() OVER() as rn, item FROM
|
||||
(select sub.item from (SELECT generate_series('2018-03-02 1:00'::TIMESTAMPTZ, '2018-03-28 1:00', '1 hour') item) as sub ORDER BY gen_rand_minstd()) sub;
|
||||
(select sub.item from (SELECT generate_series('2018-03-02 1:00'::TIMESTAMPTZ, '2018-03-28 1:00', '1 hour') item) as sub ORDER BY mix(item)) sub;
|
||||
\ir include/compression_test.sql
|
||||
DROP TABLE base_time;
|
||||
|
||||
|
||||
------------------------
|
||||
-- FLOAT4 Compression --
|
||||
------------------------
|
||||
SELECT
|
||||
$$
|
||||
select item from base_floats order by rn
|
||||
$$ AS "QUERY"
|
||||
\gset
|
||||
\set TABLE_NAME base_floats
|
||||
SELECT 'real' as "TYPE" \gset
|
||||
\set COMPRESSION_CMD _timescaledb_internal.compress_gorilla(item)
|
||||
SELECT '_timescaledb_internal.decompress_forward(c::_timescaledb_internal.compressed_data, NULL::float4)' AS "DECOMPRESS_FORWARD_CMD" \gset
|
||||
SELECT '_timescaledb_internal.decompress_reverse(c::_timescaledb_internal.compressed_data, NULL::float4)' AS "DECOMPRESS_REVERSE_CMD" \gset
|
||||
|
||||
CREATE TABLE base_floats AS SELECT row_number() OVER() as rn, item::float4 FROM
|
||||
(select sub.item from (SELECT generate_series(1, 1000) item) as sub ORDER BY mix(item)) sub;
|
||||
\ir include/compression_test.sql
|
||||
SELECT c gorilla_text FROM compressed;
|
||||
DROP TABLE base_floats;
|
||||
|
||||
-- single element
|
||||
CREATE TABLE base_floats AS SELECT row_number() OVER() as rn, item::float4 FROM (SELECT generate_series(1, 1) item) sub;
|
||||
\ir include/compression_test.sql
|
||||
DROP TABLE base_floats;
|
||||
|
||||
--special values
|
||||
CREATE TABLE base_floats AS SELECT row_number() over () as rn, item FROM
|
||||
(
|
||||
VALUES
|
||||
--special
|
||||
(0::float4), ('Infinity'), ('-Infinity'), ('NaN'),
|
||||
--big deltas
|
||||
(0), ('Infinity'), ('-Infinity'), ('Infinity'), ('-Infinity'),
|
||||
(0), ('-Infinity'), (32), (5), ('-Infinity'), (-52), ('Infinity'),
|
||||
(1000),
|
||||
--big delta_deltas
|
||||
(0), ('Infinity'), ('Infinity'), ('-Infinity'), ('-Infinity'), ('Infinity'), ('Infinity')
|
||||
) as t(item);
|
||||
\ir include/compression_test.sql
|
||||
DROP TABLE base_floats;
|
||||
|
||||
-- all 0s
|
||||
CREATE TABLE base_floats AS SELECT row_number() over () as rn, 0::float4 as item FROM (SELECT generate_series(1, 1000) ) j;
|
||||
\ir include/compression_test.sql
|
||||
DROP TABLE base_floats;
|
||||
|
||||
-- NULLs
|
||||
CREATE TABLE base_floats AS SELECT row_number() OVER() as rn, NULLIF(i, 5)::float4 item FROM generate_series(1, 10) i;
|
||||
\ir include/compression_test.sql
|
||||
DROP TABLE base_floats;
|
||||
|
||||
CREATE TABLE base_floats AS SELECT row_number() OVER() as rn, NULLIF(i, 1)::float4 item FROM generate_series(1, 10) i;
|
||||
\ir include/compression_test.sql
|
||||
DROP TABLE base_floats;
|
||||
|
||||
CREATE TABLE base_floats AS SELECT row_number() OVER() as rn, NULLIF(i, 10)::float4 item FROM generate_series(1, 10) i;
|
||||
\ir include/compression_test.sql
|
||||
DROP TABLE base_floats;
|
||||
|
||||
CREATE TABLE base_floats AS SELECT row_number() OVER() as rn, NULLIF(NULLIF(NULLIF(NULLIF(i, 2), 4), 5), 8)::float4 item FROM generate_series(1, 10) i;
|
||||
\ir include/compression_test.sql
|
||||
DROP TABLE base_floats;
|
||||
|
||||
------------------------
|
||||
-- DOUBLE Compression --
|
||||
------------------------
|
||||
@ -138,7 +203,7 @@ SELECT '_timescaledb_internal.decompress_forward(c::_timescaledb_internal.compre
|
||||
SELECT '_timescaledb_internal.decompress_reverse(c::_timescaledb_internal.compressed_data, NULL::DOUBLE PRECISION)' AS "DECOMPRESS_REVERSE_CMD" \gset
|
||||
|
||||
CREATE TABLE base_doubles AS SELECT row_number() OVER() as rn, item::double precision FROM
|
||||
(select sub.item from (SELECT generate_series(1, 1000) item) as sub ORDER BY gen_rand_minstd()) sub;
|
||||
(select sub.item from (SELECT generate_series(1, 1000) item) as sub ORDER BY mix(item)) sub;
|
||||
\ir include/compression_test.sql
|
||||
SELECT c gorilla_text FROM compressed;
|
||||
DROP TABLE base_doubles;
|
||||
@ -204,7 +269,7 @@ SELECT 'TEXT' as "TYPE" \gset
|
||||
|
||||
-- high cardinality
|
||||
CREATE TABLE base_texts AS SELECT row_number() OVER() as rn, item::text FROM
|
||||
(select sub.item from (SELECT generate_series(1, 1000) item) as sub ORDER BY gen_rand_minstd()) sub;
|
||||
(select sub.item from (SELECT generate_series(1, 1000) item) as sub ORDER BY mix(item)) sub;
|
||||
\ir include/compression_test.sql
|
||||
SELECT c from compressed;
|
||||
DROP TABLE base_texts;
|
||||
@ -212,7 +277,7 @@ DROP TABLE base_texts;
|
||||
|
||||
-- low cardinality
|
||||
CREATE TABLE base_texts AS SELECT row_number() OVER() as rn, item::text FROM
|
||||
(SELECT i as item FROM generate_series(1, 10) i, generate_series(1, 100) j ORDER BY gen_rand_minstd()) sub;
|
||||
(SELECT i as item FROM generate_series(1, 10) i, generate_series(1, 100) j ORDER BY mix(i + j)) sub;
|
||||
\ir include/compression_test.sql
|
||||
|
||||
DROP TABLE base_texts;
|
||||
@ -224,7 +289,7 @@ DROP TABLE base_texts;
|
||||
|
||||
-- high cardinality with toasted values
|
||||
CREATE TABLE base_texts AS SELECT row_number() OVER() as rn, repeat(item::text, 100000) as item FROM
|
||||
(select sub.item from (SELECT generate_series(1, 10) item) as sub ORDER BY gen_rand_minstd()) sub;
|
||||
(select sub.item from (SELECT generate_series(1, 10) item) as sub ORDER BY mix(item)) sub;
|
||||
--make sure it's toasted
|
||||
SELECT pg_total_relation_size(reltoastrelid)
|
||||
FROM pg_class c
|
||||
@ -267,7 +332,7 @@ SELECT 'TEXT' as "TYPE" \gset
|
||||
|
||||
--basic test
|
||||
CREATE TABLE base_texts AS SELECT row_number() OVER() as rn, item::text FROM
|
||||
(select sub.item from (SELECT generate_series(1, 100) item) as sub ORDER BY gen_rand_minstd()) sub;
|
||||
(select sub.item from (SELECT generate_series(1, 100) item) as sub ORDER BY mix(item)) sub;
|
||||
\ir include/compression_test.sql
|
||||
SELECT c from compressed;
|
||||
DROP TABLE base_texts;
|
||||
@ -279,7 +344,7 @@ DROP TABLE base_texts;
|
||||
|
||||
-- toasted values
|
||||
CREATE TABLE base_texts AS SELECT row_number() OVER() as rn, repeat(item::text, 100000) as item FROM
|
||||
(select sub.item from (SELECT generate_series(1, 10) item) as sub ORDER BY gen_rand_minstd()) sub;
|
||||
(select sub.item from (SELECT generate_series(1, 10) item) as sub ORDER BY mix(item)) sub;
|
||||
--make sure it's toasted
|
||||
SELECT pg_total_relation_size(reltoastrelid)
|
||||
FROM pg_class c
|
||||
|
@ -34,7 +34,7 @@ CREATE OR REPLACE FUNCTION _timescaledb_internal.deltadelta_compressor_finish(in
|
||||
AS :MODULE_PATHNAME, 'ts_deltadelta_compressor_finish'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.gorilla_compressor_append(internal, DOUBLE PRECISION)
|
||||
CREATE OR REPLACE FUNCTION _timescaledb_internal.gorilla_compressor_append(internal, ANYELEMENT)
|
||||
RETURNS internal
|
||||
AS :MODULE_PATHNAME, 'ts_gorilla_compressor_append'
|
||||
LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
||||
@ -86,7 +86,7 @@ CREATE AGGREGATE _timescaledb_internal.compress_deltadelta(timestamptz) (
|
||||
FINALFUNC = _timescaledb_internal.timestamptz_compress_finish
|
||||
);
|
||||
|
||||
CREATE AGGREGATE _timescaledb_internal.compress_gorilla(DOUBLE PRECISION) (
|
||||
CREATE AGGREGATE _timescaledb_internal.compress_gorilla(ANYELEMENT) (
|
||||
STYPE = internal,
|
||||
SFUNC = _timescaledb_internal.gorilla_compressor_append,
|
||||
FINALFUNC = _timescaledb_internal.gorilla_compressor_finish
|
||||
|
@ -38,6 +38,8 @@
|
||||
#define VEC_SCOPE static inline
|
||||
#include <adts/vec.h>
|
||||
|
||||
#define TEST_ELEMENTS 1015
|
||||
|
||||
TS_FUNCTION_INFO_V1(ts_test_compression);
|
||||
TS_FUNCTION_INFO_V1(ts_compress_table);
|
||||
TS_FUNCTION_INFO_V1(ts_decompress_table);
|
||||
@ -49,7 +51,7 @@ test_int_array()
|
||||
ArrayCompressed *compressed;
|
||||
DecompressionIterator *iter;
|
||||
int i;
|
||||
for (i = 0; i < 1015; i++)
|
||||
for (i = 0; i < TEST_ELEMENTS; i++)
|
||||
array_compressor_append(compressor, Int32GetDatum(i));
|
||||
|
||||
compressed = array_compressor_finish(compressor);
|
||||
@ -65,7 +67,7 @@ test_int_array()
|
||||
TestAssertInt64Eq(DatumGetInt32(r.val), i);
|
||||
i += 1;
|
||||
}
|
||||
TestAssertInt64Eq(i, 1015);
|
||||
TestAssertInt64Eq(i, TEST_ELEMENTS);
|
||||
|
||||
iter =
|
||||
tsl_array_decompression_iterator_from_datum_reverse(PointerGetDatum(compressed), INT4OID);
|
||||
@ -91,7 +93,7 @@ test_string_array()
|
||||
for (i = 0; i < 5; i++)
|
||||
texts[i] = cstring_to_text(strings[i]);
|
||||
|
||||
for (i = 0; i < 1015; i++)
|
||||
for (i = 0; i < TEST_ELEMENTS; i++)
|
||||
array_compressor_append(compressor, PointerGetDatum(texts[i % 5]));
|
||||
|
||||
compressed = array_compressor_finish(compressor);
|
||||
@ -113,7 +115,7 @@ test_string_array()
|
||||
__LINE__);
|
||||
i += 1;
|
||||
}
|
||||
TestAssertInt64Eq(i, 1015);
|
||||
TestAssertInt64Eq(i, TEST_ELEMENTS);
|
||||
|
||||
iter =
|
||||
tsl_array_decompression_iterator_from_datum_reverse(PointerGetDatum(compressed), TEXTOID);
|
||||
@ -140,7 +142,7 @@ test_int_dictionary()
|
||||
DictionaryCompressed *compressed;
|
||||
DecompressionIterator *iter;
|
||||
int i;
|
||||
for (i = 0; i < 1015; i++)
|
||||
for (i = 0; i < TEST_ELEMENTS; i++)
|
||||
dictionary_compressor_append(compressor, Int32GetDatum(i % 15));
|
||||
|
||||
compressed = dictionary_compressor_finish(compressor);
|
||||
@ -156,7 +158,7 @@ test_int_dictionary()
|
||||
TestAssertInt64Eq(DatumGetInt32(r.val), i % 15);
|
||||
i += 1;
|
||||
}
|
||||
TestAssertInt64Eq(i, 1015);
|
||||
TestAssertInt64Eq(i, TEST_ELEMENTS);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -222,7 +224,7 @@ test_gorilla_int()
|
||||
GorillaCompressed *compressed;
|
||||
DecompressionIterator *iter;
|
||||
uint32 i;
|
||||
for (i = 0; i < 1015; i++)
|
||||
for (i = 0; i < TEST_ELEMENTS; i++)
|
||||
gorilla_compressor_append_value(compressor, i);
|
||||
|
||||
compressed = gorilla_compressor_finish(compressor);
|
||||
@ -238,7 +240,7 @@ test_gorilla_int()
|
||||
TestAssertInt64Eq(DatumGetInt64(r.val), i);
|
||||
i += 1;
|
||||
}
|
||||
TestAssertInt64Eq(i, 1015);
|
||||
TestAssertInt64Eq(i, TEST_ELEMENTS);
|
||||
|
||||
iter = gorilla_decompression_iterator_from_datum_reverse(PointerGetDatum(compressed), INT8OID);
|
||||
for (DecompressResult r = gorilla_decompression_iterator_try_next_reverse(iter); !r.is_done;
|
||||
@ -277,7 +279,7 @@ test_gorilla_int()
|
||||
TestAssertInt64Eq(DatumGetInt64(r.val), i);
|
||||
i += 1;
|
||||
}
|
||||
TestAssertInt64Eq(i, 1015);
|
||||
TestAssertInt64Eq(i, TEST_ELEMENTS);
|
||||
}
|
||||
}
|
||||
|
||||
@ -288,7 +290,7 @@ test_gorilla_float()
|
||||
GorillaCompressed *compressed;
|
||||
DecompressionIterator *iter;
|
||||
float i;
|
||||
for (i = 0.0; i < 1015.0; i++)
|
||||
for (i = 0.0; i < TEST_ELEMENTS; i++)
|
||||
gorilla_compressor_append_value(compressor, float_get_bits(i));
|
||||
|
||||
compressed = gorilla_compressor_finish(compressor);
|
||||
@ -305,7 +307,7 @@ test_gorilla_float()
|
||||
TestAssertDoubleEq(DatumGetFloat4(r.val), i);
|
||||
i += 1.0;
|
||||
}
|
||||
TestAssertInt64Eq(i, 1015);
|
||||
TestAssertInt64Eq(i, TEST_ELEMENTS);
|
||||
|
||||
iter =
|
||||
gorilla_decompression_iterator_from_datum_reverse(PointerGetDatum(compressed), FLOAT4OID);
|
||||
@ -319,42 +321,112 @@ test_gorilla_float()
|
||||
TestAssertInt64Eq(i, 0);
|
||||
}
|
||||
|
||||
static uint64
|
||||
test_hash64(uint64 x)
|
||||
{
|
||||
x ^= x >> 30;
|
||||
x *= 0xbf58476d1ce4e5b9U;
|
||||
x ^= x >> 27;
|
||||
x *= 0x94d049bb133111ebU;
|
||||
x ^= x >> 31;
|
||||
return x;
|
||||
}
|
||||
|
||||
static void
|
||||
test_gorilla_double()
|
||||
test_gorilla_double(bool have_nulls, bool have_random)
|
||||
{
|
||||
GorillaCompressor *compressor = gorilla_compressor_alloc();
|
||||
GorillaCompressed *compressed;
|
||||
DecompressionIterator *iter;
|
||||
double i;
|
||||
for (i = 0.0; i < 1015.0; i++)
|
||||
gorilla_compressor_append_value(compressor, double_get_bits(i));
|
||||
|
||||
double values[TEST_ELEMENTS];
|
||||
bool nulls[TEST_ELEMENTS];
|
||||
for (int i = 0; i < TEST_ELEMENTS; i++)
|
||||
{
|
||||
if (have_random)
|
||||
{
|
||||
/* Also add some stretches of equal numbers. */
|
||||
int base = i;
|
||||
if (i % 37 < 3)
|
||||
{
|
||||
base = 1;
|
||||
}
|
||||
else if (i % 53 < 2)
|
||||
{
|
||||
base = 2;
|
||||
}
|
||||
|
||||
values[i] = (test_hash64(base) / (double) PG_UINT64_MAX) * 100.;
|
||||
}
|
||||
else
|
||||
{
|
||||
values[i] = i;
|
||||
}
|
||||
|
||||
if (have_nulls && i % 29 == 0)
|
||||
{
|
||||
nulls[i] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
nulls[i] = false;
|
||||
}
|
||||
|
||||
if (nulls[i])
|
||||
{
|
||||
gorilla_compressor_append_null(compressor);
|
||||
}
|
||||
else
|
||||
{
|
||||
gorilla_compressor_append_value(compressor, double_get_bits(values[i]));
|
||||
}
|
||||
}
|
||||
|
||||
compressed = gorilla_compressor_finish(compressor);
|
||||
TestAssertTrue(compressed != NULL);
|
||||
TestAssertInt64Eq(VARSIZE(compressed), 1200);
|
||||
|
||||
i = 0;
|
||||
iter =
|
||||
gorilla_decompression_iterator_from_datum_forward(PointerGetDatum(compressed), FLOAT8OID);
|
||||
for (DecompressResult r = gorilla_decompression_iterator_try_next_forward(iter); !r.is_done;
|
||||
r = gorilla_decompression_iterator_try_next_forward(iter))
|
||||
if (!have_nulls && !have_random)
|
||||
{
|
||||
TestAssertTrue(!r.is_null);
|
||||
TestAssertDoubleEq(DatumGetFloat8(r.val), i);
|
||||
i += 1.0;
|
||||
TestAssertInt64Eq(VARSIZE(compressed), 1200);
|
||||
}
|
||||
TestAssertInt64Eq(i, 1015);
|
||||
|
||||
/* Forward decompression. */
|
||||
DecompressionIterator *iter =
|
||||
gorilla_decompression_iterator_from_datum_forward(PointerGetDatum(compressed), FLOAT8OID);
|
||||
for (int i = 0; i < TEST_ELEMENTS; i++)
|
||||
{
|
||||
DecompressResult r = gorilla_decompression_iterator_try_next_forward(iter);
|
||||
TestAssertTrue(!r.is_done);
|
||||
if (r.is_null)
|
||||
{
|
||||
TestAssertTrue(nulls[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
TestAssertTrue(!nulls[i]);
|
||||
TestAssertTrue(values[i] == DatumGetFloat8(r.val));
|
||||
}
|
||||
}
|
||||
DecompressResult r = gorilla_decompression_iterator_try_next_forward(iter);
|
||||
TestAssertTrue(r.is_done);
|
||||
|
||||
/* Reverse decompression. */
|
||||
iter =
|
||||
gorilla_decompression_iterator_from_datum_reverse(PointerGetDatum(compressed), FLOAT8OID);
|
||||
for (DecompressResult r = gorilla_decompression_iterator_try_next_reverse(iter); !r.is_done;
|
||||
r = gorilla_decompression_iterator_try_next_reverse(iter))
|
||||
for (int i = TEST_ELEMENTS - 1; i >= 0; i--)
|
||||
{
|
||||
TestAssertTrue(!r.is_null);
|
||||
TestAssertDoubleEq(DatumGetFloat8(r.val), i - 1);
|
||||
i -= 1;
|
||||
DecompressResult r = gorilla_decompression_iterator_try_next_reverse(iter);
|
||||
TestAssertTrue(!r.is_done);
|
||||
if (r.is_null)
|
||||
{
|
||||
TestAssertTrue(nulls[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
TestAssertTrue(!nulls[i]);
|
||||
TestAssertTrue(values[i] == DatumGetFloat8(r.val));
|
||||
}
|
||||
}
|
||||
TestAssertInt64Eq(i, 0);
|
||||
r = gorilla_decompression_iterator_try_next_reverse(iter);
|
||||
TestAssertTrue(r.is_done);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -364,7 +436,7 @@ test_delta()
|
||||
Datum compressed;
|
||||
DecompressionIterator *iter;
|
||||
int i;
|
||||
for (i = 0; i < 1015; i++)
|
||||
for (i = 0; i < TEST_ELEMENTS; i++)
|
||||
delta_delta_compressor_append_value(compressor, i);
|
||||
|
||||
compressed = DirectFunctionCall1(tsl_deltadelta_compressor_finish, PointerGetDatum(compressor));
|
||||
@ -380,7 +452,7 @@ test_delta()
|
||||
TestAssertInt64Eq(DatumGetInt64(r.val), i);
|
||||
i += 1;
|
||||
}
|
||||
TestAssertInt64Eq(i, 1015);
|
||||
TestAssertInt64Eq(i, TEST_ELEMENTS);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -390,7 +462,7 @@ test_delta2()
|
||||
Datum compressed;
|
||||
DecompressionIterator *iter;
|
||||
int i;
|
||||
for (i = 0; i < 1015; i++)
|
||||
for (i = 0; i < TEST_ELEMENTS; i++)
|
||||
{
|
||||
/* prevent everything from being rle'd away */
|
||||
if (i % 2 != 0)
|
||||
@ -415,7 +487,100 @@ test_delta2()
|
||||
TestAssertInt64Eq(DatumGetInt64(r.val), i);
|
||||
i += 1;
|
||||
}
|
||||
TestAssertInt64Eq(i, 1015);
|
||||
TestAssertInt64Eq(i, TEST_ELEMENTS);
|
||||
}
|
||||
|
||||
static void
|
||||
test_delta3(bool have_nulls, bool have_random)
|
||||
{
|
||||
DeltaDeltaCompressor *compressor = delta_delta_compressor_alloc();
|
||||
Datum compressed;
|
||||
|
||||
int64 values[TEST_ELEMENTS];
|
||||
bool nulls[TEST_ELEMENTS];
|
||||
for (int i = 0; i < TEST_ELEMENTS; i++)
|
||||
{
|
||||
if (have_random)
|
||||
{
|
||||
/* Also add some stretches of equal numbers. */
|
||||
int base = i;
|
||||
if (i % 37 < 4)
|
||||
{
|
||||
base = 1;
|
||||
}
|
||||
else if (i % 53 < 2)
|
||||
{
|
||||
base = 2;
|
||||
}
|
||||
|
||||
values[i] = test_hash64(base);
|
||||
}
|
||||
else
|
||||
{
|
||||
values[i] = i;
|
||||
}
|
||||
|
||||
if (have_nulls && i % 29 == 0)
|
||||
{
|
||||
nulls[i] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
nulls[i] = false;
|
||||
}
|
||||
|
||||
if (nulls[i])
|
||||
{
|
||||
delta_delta_compressor_append_null(compressor);
|
||||
}
|
||||
else
|
||||
{
|
||||
delta_delta_compressor_append_value(compressor, values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
compressed = PointerGetDatum(delta_delta_compressor_finish(compressor));
|
||||
TestAssertTrue(DatumGetPointer(compressed) != NULL);
|
||||
|
||||
/* Forward decompression. */
|
||||
DecompressionIterator *iter =
|
||||
delta_delta_decompression_iterator_from_datum_forward(PointerGetDatum(compressed), INT8OID);
|
||||
for (int i = 0; i < TEST_ELEMENTS; i++)
|
||||
{
|
||||
DecompressResult r = delta_delta_decompression_iterator_try_next_forward(iter);
|
||||
TestAssertTrue(!r.is_done);
|
||||
if (r.is_null)
|
||||
{
|
||||
TestAssertTrue(nulls[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
TestAssertTrue(!nulls[i]);
|
||||
TestAssertTrue(values[i] == DatumGetInt64(r.val));
|
||||
}
|
||||
}
|
||||
DecompressResult r = delta_delta_decompression_iterator_try_next_forward(iter);
|
||||
TestAssertTrue(r.is_done);
|
||||
|
||||
/* Reverse decompression. */
|
||||
iter =
|
||||
delta_delta_decompression_iterator_from_datum_reverse(PointerGetDatum(compressed), INT8OID);
|
||||
for (int i = TEST_ELEMENTS - 1; i >= 0; i--)
|
||||
{
|
||||
DecompressResult r = delta_delta_decompression_iterator_try_next_reverse(iter);
|
||||
TestAssertTrue(!r.is_done);
|
||||
if (r.is_null)
|
||||
{
|
||||
TestAssertTrue(nulls[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
TestAssertTrue(!nulls[i]);
|
||||
TestAssertTrue(values[i] == DatumGetInt64(r.val));
|
||||
}
|
||||
}
|
||||
r = delta_delta_decompression_iterator_try_next_reverse(iter);
|
||||
TestAssertTrue(r.is_done);
|
||||
}
|
||||
|
||||
Datum
|
||||
@ -427,9 +592,16 @@ ts_test_compression(PG_FUNCTION_ARGS)
|
||||
test_string_dictionary();
|
||||
test_gorilla_int();
|
||||
test_gorilla_float();
|
||||
test_gorilla_double();
|
||||
test_gorilla_double(/* have_nulls = */ false, /* have_random = */ false);
|
||||
test_gorilla_double(/* have_nulls = */ false, /* have_random = */ true);
|
||||
test_gorilla_double(/* have_nulls = */ true, /* have_random = */ false);
|
||||
test_gorilla_double(/* have_nulls = */ true, /* have_random = */ true);
|
||||
test_delta();
|
||||
test_delta2();
|
||||
test_delta3(/* have_nulls = */ false, /* have_random = */ false);
|
||||
test_delta3(/* have_nulls = */ false, /* have_random = */ true);
|
||||
test_delta3(/* have_nulls = */ true, /* have_random = */ false);
|
||||
test_delta3(/* have_nulls = */ true, /* have_random = */ true);
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user