blob: c70aa602c50b1d5844aef3d305608e7f4df8b7ce [file] [log] [blame]
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include "cmockery.h"
#include "postgres.h"
#include "utils/memutils.h"
#include "../bitmap_compression.c"
static void
test__BitmapCompression__ZeroBitmap(void **state)
{
uint32 bitmap[4];
memset(bitmap, 0, sizeof(uint32) * 4);
unsigned char output[20];
memset(output, 0, 20);
int onDiskBlockCount = 0;
int bmsWordCount = 0;
/*
* For 64bit bms, bmsWordCount is half of onDiskBlockCount;
* For 32bit bms, bmsWordCount is equal to onDiskBlockCount.
*/
int expectedBmwWordCount = BITS_PER_BITMAPWORD == 64 ? 2 : 4;
Bitmapset *bms;
/* fake a bitmapset with the bitmap data */
bms = (Bitmapset *) palloc(BITMAPSET_SIZE(expectedBmwWordCount));
bms->nwords = expectedBmwWordCount;
memcpy(bms->words, bitmap, sizeof(uint32) * 4);
BitmapCompress_CalculateBlockCounts(bms,
&onDiskBlockCount,
&bmsWordCount);
assert_int_equal(4, onDiskBlockCount);
assert_int_equal(expectedBmwWordCount, bmsWordCount);
int r = Bitmap_Compress(
BITMAP_COMPRESSION_TYPE_DEFAULT,
bitmap, onDiskBlockCount,
output, 20);
assert_true(r < sizeof(uint32) * 4 && r >= 0);
uint32 bitmap2[4];
memset(bitmap2, 1, sizeof(uint32) * 4);
BitmapDecompressState decomp_state;
BitmapDecompress_Init(&decomp_state, output, r);
assert_false(BitmapDecompress_HasError(&decomp_state));
assert_int_equal(BITMAP_COMPRESSION_TYPE_DEFAULT,
BitmapDecompress_GetCompressionType(&decomp_state));
assert_int_equal(4, BitmapDecompress_GetBlockCount(&decomp_state));
BitmapDecompress_CalculateBlockCounts(&decomp_state,
&onDiskBlockCount,
&bmsWordCount);
assert_int_equal(4, onDiskBlockCount);
assert_int_equal(expectedBmwWordCount, bmsWordCount);
BitmapDecompress_Decompress(&decomp_state,
bitmap2, onDiskBlockCount);
assert_memory_equal(bitmap, bitmap2, sizeof(uint32) * 4);
}
static void
test__BitmapCompression__Raw(void **state)
{
int blockCount = 4;
uint32 bitmap[4];
memset(bitmap, 0, sizeof(uint32) * blockCount);
bitmap[0] = 0xFFFFFFFFU; /* one case */
bitmap[1] = 0xFF00FF00U; /* Raw */
bitmap[2] = 0xFF00FF00U; /*One repetition, use RLE */
bitmap[3] = 0xFFFFFFFFU; /* one case */
unsigned char output[sizeof(uint32) * 5];
memset(output, 0, sizeof(uint32) * 5);
int onDiskBlockCount = 0;
int bmsWordCount = 0;
/*
* For 64bit bms, bmsWordCount is half of onDiskBlockCount;
* For 32bit bms, bmsWordCount is equal to onDiskBlockCount.
*/
int expectedBmwWordCount = BITS_PER_BITMAPWORD == 64 ? 2 : 4;
Bitmapset *bms;
/* fake a bitmapset with the bitmap data */
bms = (Bitmapset *) palloc(BITMAPSET_SIZE(expectedBmwWordCount));
bms->nwords = expectedBmwWordCount;
memcpy(bms->words, bitmap, sizeof(uint32) * 4);
BitmapCompress_CalculateBlockCounts(bms,
&onDiskBlockCount,
&bmsWordCount);
assert_int_equal(4, onDiskBlockCount);
assert_int_equal(expectedBmwWordCount, bmsWordCount);
int r = Bitmap_Compress(
BITMAP_COMPRESSION_TYPE_DEFAULT,
bitmap, onDiskBlockCount,
output, sizeof(uint32) * 5);
assert_true(r < sizeof(uint32) * blockCount && r >= 0);
uint32 bitmap2[4];
memset(bitmap2, 1, sizeof(uint32) * blockCount);
BitmapDecompressState decomp_state;
BitmapDecompress_Init(&decomp_state, output, r);
assert_false(BitmapDecompress_HasError(&decomp_state));
assert_int_equal(BITMAP_COMPRESSION_TYPE_DEFAULT,
BitmapDecompress_GetCompressionType(&decomp_state));
assert_int_equal(blockCount, BitmapDecompress_GetBlockCount(&decomp_state));
BitmapDecompress_CalculateBlockCounts(&decomp_state,
&onDiskBlockCount,
&bmsWordCount);
assert_int_equal(blockCount, onDiskBlockCount);
assert_int_equal(expectedBmwWordCount, bmsWordCount);
BitmapDecompress_Decompress(&decomp_state,
bitmap2, onDiskBlockCount);
assert_memory_equal(bitmap, bitmap2, sizeof(uint32) * blockCount);
}
static void
test__BitmapCompression__ExplicitNoCompression(void **state)
{
int blockCount = 4;
uint32 bitmap[4];
memset(bitmap, 0, sizeof(uint32) * blockCount);
bitmap[0] = 0xFFFFFFFFU; /* one case */
bitmap[1] = 0xFF00FF00U; /* Raw */
bitmap[2] = 0xFF00FF00U; /*One repetition, use RLE */
bitmap[3] = 0xFFFFFFFFU; /* one case */
unsigned char output[sizeof(uint32) * 5];
memset(output, 0, sizeof(uint32) * 5);
int onDiskBlockCount = 0;
int bmsWordCount = 0;
/*
* For 64bit bms, bmsWordCount is half of onDiskBlockCount;
* For 32bit bms, bmsWordCount is equal to onDiskBlockCount.
*/
int expectedBmwWordCount = BITS_PER_BITMAPWORD == 64 ? 2 : 4;
Bitmapset *bms;
/* fake a bitmapset with the bitmap data */
bms = (Bitmapset *) palloc(BITMAPSET_SIZE(expectedBmwWordCount));
bms->nwords = expectedBmwWordCount;
memcpy(bms->words, bitmap, sizeof(uint32) * 4);
BitmapCompress_CalculateBlockCounts(bms,
&onDiskBlockCount,
&bmsWordCount);
assert_int_equal(4, onDiskBlockCount);
assert_int_equal(expectedBmwWordCount, bmsWordCount);
int r = Bitmap_Compress(
BITMAP_COMPRESSION_TYPE_NO,
bitmap, onDiskBlockCount,
output, sizeof(uint32) * 5);
assert_int_equal(r, (sizeof(uint32) * 4) + 2);
uint32 bitmap2[4];
memset(bitmap2, 1, sizeof(uint32) * blockCount);
BitmapDecompressState decomp_state;
BitmapDecompress_Init(&decomp_state, output, r);
assert_false(BitmapDecompress_HasError(&decomp_state));
assert_int_equal(BITMAP_COMPRESSION_TYPE_NO,
BitmapDecompress_GetCompressionType(&decomp_state));
assert_int_equal(blockCount, BitmapDecompress_GetBlockCount(&decomp_state));
BitmapDecompress_CalculateBlockCounts(&decomp_state,
&onDiskBlockCount,
&bmsWordCount);
assert_int_equal(blockCount, onDiskBlockCount);
assert_int_equal(expectedBmwWordCount, bmsWordCount);
BitmapDecompress_Decompress(&decomp_state,
bitmap2, onDiskBlockCount);
assert_memory_equal(bitmap, bitmap2, sizeof(uint32) * blockCount);
}
static void
test__BitmapCompression__ExplicitNoCompressionNoBlocks(void **state)
{
int blockCount = 0;
uint32 bitmap[1];
memset(bitmap, 0, sizeof(uint32) * 1);
unsigned char output[sizeof(uint32) * 5];
memset(output, 0, sizeof(uint32) * 5);
int onDiskBlockCount = 0;
int bmsWordCount = 0;
BitmapCompress_CalculateBlockCounts(NULL,
&onDiskBlockCount,
&bmsWordCount);
assert_int_equal(0, onDiskBlockCount);
assert_int_equal(0, bmsWordCount);
int r = Bitmap_Compress(
BITMAP_COMPRESSION_TYPE_NO,
bitmap, onDiskBlockCount,
output, sizeof(uint32) * 5);
assert_int_equal(r, 2);
uint32 bitmap2[1];
memset(bitmap2, 1, sizeof(uint32) * 1);
BitmapDecompressState decomp_state;
BitmapDecompress_Init(&decomp_state, output, r);
assert_false(BitmapDecompress_HasError(&decomp_state));
assert_int_equal(BITMAP_COMPRESSION_TYPE_NO,
BitmapDecompress_GetCompressionType(&decomp_state));
assert_int_equal(blockCount, BitmapDecompress_GetBlockCount(&decomp_state));
BitmapDecompress_CalculateBlockCounts(&decomp_state,
&onDiskBlockCount,
&bmsWordCount);
assert_int_equal(blockCount, onDiskBlockCount);
assert_int_equal(0, bmsWordCount);
BitmapDecompress_Decompress(&decomp_state,
bitmap2, onDiskBlockCount);
}
static void
test__BitmapCompression__ImplicitNoCompression(void **state)
{
int blockCount = 4;
uint32 bitmap[4];
memset(bitmap, 0, sizeof(uint32) * blockCount);
bitmap[0] = 0x00FFFFFFU;
bitmap[1] = 0xFF00FF00U;
bitmap[2] = 0xFFFF00FFU;
bitmap[3] = 0xFFFFFF00U;
unsigned char output[18];
memset(output, 0, 18);
int onDiskBlockCount = 0;
int bmsWordCount = 0;
/*
* For 64bit bms, bmsWordCount is half of onDiskBlockCount;
* For 32bit bms, bmsWordCount is equal to onDiskBlockCount.
*/
int expectedBmwWordCount = BITS_PER_BITMAPWORD == 64 ? 2 : 4;
Bitmapset *bms;
/* fake a bitmapset with the bitmap data */
bms = (Bitmapset *) palloc(BITMAPSET_SIZE(expectedBmwWordCount));
bms->nwords = expectedBmwWordCount;
memcpy(bms->words, bitmap, sizeof(uint32) * 4);
BitmapCompress_CalculateBlockCounts(bms,
&onDiskBlockCount,
&bmsWordCount);
assert_int_equal(4, onDiskBlockCount);
assert_int_equal(expectedBmwWordCount, bmsWordCount);
int r = Bitmap_Compress(
BITMAP_COMPRESSION_TYPE_DEFAULT,
bitmap, onDiskBlockCount,
output, 18);
assert_int_equal(r, (sizeof(uint32) * 4) + 2);
uint32 bitmap2[4];
memset(bitmap2, 1, sizeof(uint32) * blockCount);
BitmapDecompressState decomp_state;
BitmapDecompress_Init(&decomp_state, output, r);
assert_false(BitmapDecompress_HasError(&decomp_state));
assert_int_equal(BITMAP_COMPRESSION_TYPE_NO,
BitmapDecompress_GetCompressionType(&decomp_state));
assert_int_equal(blockCount, BitmapDecompress_GetBlockCount(&decomp_state));
BitmapDecompress_CalculateBlockCounts(&decomp_state,
&onDiskBlockCount,
&bmsWordCount);
assert_int_equal(blockCount, onDiskBlockCount);
assert_int_equal(expectedBmwWordCount, bmsWordCount);
BitmapDecompress_Decompress(&decomp_state,
bitmap2, onDiskBlockCount);
assert_memory_equal(bitmap, bitmap2, sizeof(uint32) * blockCount);
}
static void
test__BitmapCompression__MultipleTypeBitmap(void **state)
{
uint32 bitmap[16];
memset(bitmap, 0, sizeof(uint32) * 16);
bitmap[0] = 0xFFFFFFFFU; /* one case */
bitmap[1] = 0xFF00FF00U; /* Raw */
bitmap[2] = 0xFF00FF00U; /*One repetition, use RLE */
bitmap[3] = 0xFFFFFFFFU; /* one case */
bitmap[4] = 0xFFFFFFFFU; /* One repetition, no use RLE */
bitmap[5] = 0x00000000U;
bitmap[6] = 0xFFFFFFFFU; /* one case */
bitmap[7] = 0xFFFFFFFFU;
bitmap[8] = 0xFFFFFFFFU;
bitmap[9] = 0xFFFFFFFFU;
bitmap[10] = 0xFFFFFFFFU;
bitmap[11] = 0xFFFFFFFFU;
bitmap[12] = 0xFFFFFFFFU;
bitmap[13] = 0xFFFFFFFFU; /*use RLE */
bitmap[14] = 0xFF22FF00U; /* Raw */
bitmap[15] = 0xFF11FF00U; /* Raw */
unsigned char output[sizeof(uint32) * 17];
memset(output, 0, sizeof(uint32) * 17);
int onDiskBlockCount = 0;
int bmsWordCount = 0;
/*
* For 64bit bms, bmsWordCount is half of onDiskBlockCount;
* For 32bit bms, bmsWordCount is equal to onDiskBlockCount.
*/
int expectedBmwWordCount = BITS_PER_BITMAPWORD == 64 ? 8 : 16;
Bitmapset *bms;
/* fake a bitmapset with the bitmap data */
bms = (Bitmapset *) palloc(BITMAPSET_SIZE(expectedBmwWordCount));
bms->nwords = expectedBmwWordCount;
memcpy(bms->words, bitmap, sizeof(uint32) * 4);
BitmapCompress_CalculateBlockCounts(bms,
&onDiskBlockCount,
&bmsWordCount);
assert_int_equal(16, onDiskBlockCount);
assert_int_equal(expectedBmwWordCount, bmsWordCount);
int r = Bitmap_Compress(
BITMAP_COMPRESSION_TYPE_DEFAULT,
bitmap, onDiskBlockCount,
output, sizeof(uint32) * 17);
assert_true(r < sizeof(uint32) * 16 && r >= 0);
uint32 bitmap2[16];
memset(bitmap2, 1, sizeof(uint32) * 16);
BitmapDecompressState decomp_state;
BitmapDecompress_Init(&decomp_state, output, r);
assert_false(BitmapDecompress_HasError(&decomp_state));
assert_int_equal(BITMAP_COMPRESSION_TYPE_DEFAULT,
BitmapDecompress_GetCompressionType(&decomp_state));
assert_int_equal(16, BitmapDecompress_GetBlockCount(&decomp_state));
BitmapDecompress_CalculateBlockCounts(&decomp_state,
&onDiskBlockCount,
&bmsWordCount);
assert_int_equal(16, onDiskBlockCount);
assert_int_equal(16, BitmapDecompress_GetBlockCount(&decomp_state));
BitmapDecompress_Decompress(&decomp_state,
bitmap2, onDiskBlockCount);
assert_memory_equal(bitmap, bitmap2, sizeof(uint32) * 16);
}
static void
test__BitmapCompression_ShortDecompress(void **state)
{
uint32 bitmap[16];
memset(bitmap, 0, sizeof(uint32) * 16);
bitmap[0] = 0xFFFFFFFFU; /* one case */
bitmap[1] = 0xFF00FF00U; /* Raw */
bitmap[2] = 0xFF00FF00U; /*One repetition, use RLE */
bitmap[3] = 0xFFFFFFFFU; /* one case */
bitmap[4] = 0xFFFFFFFFU; /* One repetition, no use RLE */
bitmap[5] = 0x00000000U;
bitmap[6] = 0xFFFFFFFFU; /* one case */
bitmap[7] = 0xFFFFFFFFU;
bitmap[8] = 0xFFFFFFFFU;
bitmap[9] = 0xFFFFFFFFU;
bitmap[10] = 0xFFFFFFFFU;
bitmap[11] = 0xFFFFFFFFU;
bitmap[12] = 0xFFFFFFFFU;
bitmap[13] = 0xFFFFFFFFU; /*use RLE */
bitmap[14] = 0xFF22FF00U; /* Raw */
bitmap[15] = 0xFF11FF00U; /* Raw */
unsigned char output[sizeof(uint32) * 17];
memset(output, 0, sizeof(uint32) * 17);
int onDiskBlockCount = 0;
int bmsWordCount = 0;
/*
* For 64bit bms, bmsWordCount is half of onDiskBlockCount;
* For 32bit bms, bmsWordCount is equal to onDiskBlockCount.
*/
int expectedBmwWordCount = BITS_PER_BITMAPWORD == 64 ? 8 : 16;
Bitmapset *bms;
/* fake a bitmapset with the bitmap data */
bms = (Bitmapset *) palloc(BITMAPSET_SIZE(expectedBmwWordCount));
bms->nwords = expectedBmwWordCount;
memcpy(bms->words, bitmap, sizeof(uint32) * 16);
BitmapCompress_CalculateBlockCounts(bms,
&onDiskBlockCount,
&bmsWordCount);
assert_int_equal(16, onDiskBlockCount);
assert_int_equal(expectedBmwWordCount, bmsWordCount);
int r = Bitmap_Compress(
BITMAP_COMPRESSION_TYPE_DEFAULT,
bitmap, onDiskBlockCount,
output, sizeof(uint32) * 17);
assert_true(r < sizeof(uint32) * 16 && r >= 0);
uint32 bitmap2[16];
memset(bitmap2, 1, sizeof(uint32) * 16);
for (int i = 0; i < 2; i++)
{
BitmapDecompressState decomp_state;
assert_false(BitmapDecompress_Init(&decomp_state, output, i));
assert_true(BitmapDecompress_HasError(&decomp_state));
}
for (int i = 2; i < r; i++)
{
BitmapDecompressState decomp_state;
assert_true(BitmapDecompress_Init(&decomp_state, output, i));
assert_false(BitmapDecompress_HasError(&decomp_state));
assert_int_equal(BITMAP_COMPRESSION_TYPE_DEFAULT,
BitmapDecompress_GetCompressionType(&decomp_state));
assert_int_equal(16, BitmapDecompress_GetBlockCount(&decomp_state));
BitmapDecompress_CalculateBlockCounts(
&decomp_state,
&onDiskBlockCount,
&bmsWordCount);
assert_int_equal(16, onDiskBlockCount);
assert_int_equal(expectedBmwWordCount, bmsWordCount);
PG_TRY();
{
BitmapDecompress_Decompress(&decomp_state, bitmap2, onDiskBlockCount);
assert_true(false); /*should not be reached */
}
PG_CATCH();
{
FlushErrorState();
}
PG_END_TRY();
}
}
static void
test__BitmapCompression__IllegalCompressionType(void **state)
{
uint32 bitmap[1];
memset(bitmap, 0, sizeof(uint32) * 1);
unsigned char output[sizeof(uint32) * 5];
memset(output, 0, sizeof(uint32) * 5);
int onDiskBlockCount = 0;
int bmsWordCount = 0;
/*
* When onDiskBlockCount is 1, bmsWordCount is always 1 for
* both 64bit and 32bit bms.
*/
int expectedBmwWordCount = 1;
Bitmapset *bms;
/* fake a bitmapset with the bitmap data */
bms = (Bitmapset *) palloc0(BITMAPSET_SIZE(expectedBmwWordCount));
bms->nwords = expectedBmwWordCount;
memcpy(bms->words, bitmap, sizeof(uint32));
BitmapCompress_CalculateBlockCounts(bms,
&onDiskBlockCount,
&bmsWordCount);
assert_int_equal(1, onDiskBlockCount);
assert_int_equal(expectedBmwWordCount, bmsWordCount);
PG_TRY();
{
Bitmap_Compress(
14,
bitmap, onDiskBlockCount,
output, sizeof(uint32) * 5);
assert_true(false); /*should not be reached */
}
PG_CATCH();
{
FlushErrorState();
}
PG_END_TRY();
}
int
main(int argc, char* argv[])
{
cmockery_parse_arguments(argc, argv);
const UnitTest tests[] = {
unit_test(test__BitmapCompression__ZeroBitmap),
unit_test(test__BitmapCompression__Raw),
unit_test(test__BitmapCompression__ExplicitNoCompression),
unit_test(test__BitmapCompression__ImplicitNoCompression),
unit_test(test__BitmapCompression__MultipleTypeBitmap),
unit_test(test__BitmapCompression_ShortDecompress),
unit_test(test__BitmapCompression__ExplicitNoCompressionNoBlocks),
unit_test(test__BitmapCompression__IllegalCompressionType)
};
MemoryContextInit();
return run_tests(tests);
}