mirror of
https://github.com/pgpointcloud/pointcloud.git
synced 2025-12-08 20:36:04 +00:00
indentation normalization
This commit is contained in:
parent
2b87e90d49
commit
ef5fc167d8
@ -40,14 +40,14 @@ clean_suite(void)
|
||||
|
||||
static PCBYTES initbytes(uint8_t *bytes, size_t size, uint32_t interp)
|
||||
{
|
||||
PCBYTES pcb;
|
||||
pcb.bytes = bytes;
|
||||
pcb.size = size;
|
||||
pcb.interpretation = interp;
|
||||
pcb.npoints = pcb.size / pc_interpretation_size(pcb.interpretation);
|
||||
pcb.compression = PC_DIM_NONE;
|
||||
pcb.readonly = PC_TRUE;
|
||||
return pcb;
|
||||
PCBYTES pcb;
|
||||
pcb.bytes = bytes;
|
||||
pcb.size = size;
|
||||
pcb.interpretation = interp;
|
||||
pcb.npoints = pcb.size / pc_interpretation_size(pcb.interpretation);
|
||||
pcb.compression = PC_DIM_NONE;
|
||||
pcb.readonly = PC_TRUE;
|
||||
return pcb;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -60,94 +60,94 @@ test_run_length_encoding()
|
||||
{
|
||||
char *bytes;
|
||||
int nr;
|
||||
PCBYTES pcb, epcb, pcb2;
|
||||
PCBYTES pcb, epcb, pcb2;
|
||||
|
||||
/*
|
||||
typedef struct
|
||||
{
|
||||
size_t size;
|
||||
uint32_t npoints;
|
||||
uint32_t interpretation;
|
||||
uint32_t compression;
|
||||
uint8_t *bytes;
|
||||
size_t size;
|
||||
uint32_t npoints;
|
||||
uint32_t interpretation;
|
||||
uint32_t compression;
|
||||
uint8_t *bytes;
|
||||
} PCBYTES;
|
||||
*/
|
||||
|
||||
bytes = "aaaabbbbccdde";
|
||||
pcb = initbytes((uint8_t *)bytes, strlen(bytes), PC_UINT8);
|
||||
bytes = "aaaabbbbccdde";
|
||||
pcb = initbytes((uint8_t *)bytes, strlen(bytes), PC_UINT8);
|
||||
nr = pc_bytes_run_count(&pcb);
|
||||
CU_ASSERT_EQUAL(nr, 5);
|
||||
|
||||
bytes = "a";
|
||||
pcb = initbytes((uint8_t *)bytes, strlen(bytes), PC_UINT8);
|
||||
bytes = "a";
|
||||
pcb = initbytes((uint8_t *)bytes, strlen(bytes), PC_UINT8);
|
||||
nr = pc_bytes_run_count(&pcb);
|
||||
CU_ASSERT_EQUAL(nr, 1);
|
||||
|
||||
bytes = "aa";
|
||||
pcb = initbytes((uint8_t *)bytes, strlen(bytes), PC_UINT8);
|
||||
bytes = "aa";
|
||||
pcb = initbytes((uint8_t *)bytes, strlen(bytes), PC_UINT8);
|
||||
nr = pc_bytes_run_count(&pcb);
|
||||
CU_ASSERT_EQUAL(nr, 1);
|
||||
|
||||
bytes = "ab";
|
||||
pcb = initbytes((uint8_t *)bytes, strlen(bytes), PC_UINT8);
|
||||
bytes = "ab";
|
||||
pcb = initbytes((uint8_t *)bytes, strlen(bytes), PC_UINT8);
|
||||
nr = pc_bytes_run_count(&pcb);
|
||||
CU_ASSERT_EQUAL(nr, 2);
|
||||
|
||||
bytes = "abcdefg";
|
||||
pcb = initbytes((uint8_t *)bytes, strlen(bytes), PC_UINT8);
|
||||
pcb = initbytes((uint8_t *)bytes, strlen(bytes), PC_UINT8);
|
||||
nr = pc_bytes_run_count(&pcb);
|
||||
CU_ASSERT_EQUAL(nr, 7);
|
||||
|
||||
bytes = "aabcdefg";
|
||||
pcb = initbytes((uint8_t *)bytes, strlen(bytes), PC_UINT8);
|
||||
pcb = initbytes((uint8_t *)bytes, strlen(bytes), PC_UINT8);
|
||||
nr = pc_bytes_run_count(&pcb);
|
||||
CU_ASSERT_EQUAL(nr, 7);
|
||||
|
||||
bytes = "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc";
|
||||
pcb = initbytes((uint8_t *)bytes, strlen(bytes), PC_UINT8);
|
||||
pcb = initbytes((uint8_t *)bytes, strlen(bytes), PC_UINT8);
|
||||
nr = pc_bytes_run_count(&pcb);
|
||||
CU_ASSERT_EQUAL(nr, 1);
|
||||
|
||||
epcb = pc_bytes_run_length_encode(pcb);
|
||||
pcb2 = pc_bytes_run_length_decode(epcb);
|
||||
epcb = pc_bytes_run_length_encode(pcb);
|
||||
pcb2 = pc_bytes_run_length_decode(epcb);
|
||||
|
||||
CU_ASSERT_EQUAL(pcb.compression, PC_DIM_NONE);
|
||||
CU_ASSERT_EQUAL(epcb.compression, PC_DIM_RLE);
|
||||
CU_ASSERT_EQUAL(pcb2.compression, PC_DIM_NONE);
|
||||
|
||||
CU_ASSERT_EQUAL(pcb.compression, PC_DIM_NONE);
|
||||
CU_ASSERT_EQUAL(epcb.compression, PC_DIM_RLE);
|
||||
CU_ASSERT_EQUAL(pcb2.compression, PC_DIM_NONE);
|
||||
|
||||
CU_ASSERT_EQUAL(memcmp(pcb.bytes, pcb2.bytes, pcb.size), 0);
|
||||
CU_ASSERT_EQUAL(pcb.size, pcb2.size);
|
||||
CU_ASSERT_EQUAL(pcb.npoints, pcb2.npoints);
|
||||
CU_ASSERT_EQUAL(pcb.size, pcb2.size);
|
||||
CU_ASSERT_EQUAL(pcb.npoints, pcb2.npoints);
|
||||
pc_bytes_free(epcb);
|
||||
pc_bytes_free(pcb2);
|
||||
|
||||
bytes = "aabcdefg";
|
||||
pcb = initbytes((uint8_t *)bytes, strlen(bytes), PC_UINT8);
|
||||
epcb = pc_bytes_run_length_encode(pcb);
|
||||
pcb2 = pc_bytes_run_length_decode(epcb);
|
||||
pcb = initbytes((uint8_t *)bytes, strlen(bytes), PC_UINT8);
|
||||
epcb = pc_bytes_run_length_encode(pcb);
|
||||
pcb2 = pc_bytes_run_length_decode(epcb);
|
||||
CU_ASSERT_EQUAL(memcmp(pcb.bytes, pcb2.bytes, pcb.size), 0);
|
||||
CU_ASSERT_EQUAL(pcb.size, pcb2.size);
|
||||
CU_ASSERT_EQUAL(pcb.npoints, pcb2.npoints);
|
||||
CU_ASSERT_EQUAL(pcb.size, pcb2.size);
|
||||
CU_ASSERT_EQUAL(pcb.npoints, pcb2.npoints);
|
||||
pc_bytes_free(epcb);
|
||||
pc_bytes_free(pcb2);
|
||||
|
||||
bytes = (char *)((uint32_t[]){ 10, 10, 10, 20, 20, 30, 20, 20 });
|
||||
pcb = initbytes((uint8_t *)bytes, 8, PC_UINT32);
|
||||
epcb = pc_bytes_run_length_encode(pcb);
|
||||
pcb2 = pc_bytes_run_length_decode(epcb);
|
||||
bytes = (char *)((uint32_t[]){ 10, 10, 10, 20, 20, 30, 20, 20 });
|
||||
pcb = initbytes((uint8_t *)bytes, 8, PC_UINT32);
|
||||
epcb = pc_bytes_run_length_encode(pcb);
|
||||
pcb2 = pc_bytes_run_length_decode(epcb);
|
||||
CU_ASSERT_EQUAL(memcmp(pcb.bytes, pcb2.bytes, pcb.size), 0);
|
||||
CU_ASSERT_EQUAL(pcb.size, pcb2.size);
|
||||
CU_ASSERT_EQUAL(pcb.npoints, pcb2.npoints);
|
||||
CU_ASSERT_EQUAL(pcb.size, pcb2.size);
|
||||
CU_ASSERT_EQUAL(pcb.npoints, pcb2.npoints);
|
||||
pc_bytes_free(epcb);
|
||||
pc_bytes_free(pcb2);
|
||||
|
||||
bytes = (char*)((uint16_t[]){ 10, 10, 10, 20, 20, 30, 20, 20 });
|
||||
pcb = initbytes((uint8_t *)bytes, 8, PC_UINT16);
|
||||
epcb = pc_bytes_run_length_encode(pcb);
|
||||
pcb2 = pc_bytes_run_length_decode(epcb);
|
||||
bytes = (char*)((uint16_t[]){ 10, 10, 10, 20, 20, 30, 20, 20 });
|
||||
pcb = initbytes((uint8_t *)bytes, 8, PC_UINT16);
|
||||
epcb = pc_bytes_run_length_encode(pcb);
|
||||
pcb2 = pc_bytes_run_length_decode(epcb);
|
||||
CU_ASSERT_EQUAL(memcmp(pcb.bytes, pcb2.bytes, pcb.size), 0);
|
||||
CU_ASSERT_EQUAL(pcb.size, pcb2.size);
|
||||
CU_ASSERT_EQUAL(pcb.npoints, pcb2.npoints);
|
||||
CU_ASSERT_EQUAL(pcb.size, pcb2.size);
|
||||
CU_ASSERT_EQUAL(pcb.npoints, pcb2.npoints);
|
||||
pc_bytes_free(epcb);
|
||||
pc_bytes_free(pcb2);
|
||||
|
||||
@ -162,16 +162,16 @@ static void
|
||||
test_sigbits_encoding()
|
||||
{
|
||||
uint8_t *bytes;
|
||||
uint16_t *bytes16, *ebytes16;
|
||||
uint32_t *bytes32, *ebytes32;
|
||||
uint64_t *bytes64, *ebytes64;
|
||||
uint16_t *bytes16, *ebytes16;
|
||||
uint32_t *bytes32, *ebytes32;
|
||||
uint64_t *bytes64, *ebytes64;
|
||||
|
||||
uint32_t count, nelems;
|
||||
uint8_t common8;
|
||||
uint16_t common16;
|
||||
uint32_t common32;
|
||||
uint64_t common64;
|
||||
PCBYTES pcb, epcb, pcb2;
|
||||
PCBYTES pcb, epcb, pcb2;
|
||||
|
||||
/*
|
||||
01100001 a
|
||||
@ -180,14 +180,14 @@ test_sigbits_encoding()
|
||||
01100000 `
|
||||
*/
|
||||
bytes = (uint8_t *)"abc";
|
||||
pcb = initbytes(bytes, strlen((char *)bytes), PC_UINT8);
|
||||
common8 = pc_bytes_sigbits_count_8(&pcb, &count);
|
||||
pcb = initbytes(bytes, strlen((char *)bytes), PC_UINT8);
|
||||
common8 = pc_bytes_sigbits_count_8(&pcb, &count);
|
||||
CU_ASSERT_EQUAL(count, 6);
|
||||
CU_ASSERT_EQUAL(common8, '`');
|
||||
|
||||
bytes = (uint8_t *)"abcdef";
|
||||
pcb = initbytes(bytes, strlen((char *)bytes), PC_UINT8);
|
||||
common8 = pc_bytes_sigbits_count_8(&pcb, &count);
|
||||
pcb = initbytes(bytes, strlen((char *)bytes), PC_UINT8);
|
||||
common8 = pc_bytes_sigbits_count_8(&pcb, &count);
|
||||
CU_ASSERT_EQUAL(count, 5);
|
||||
CU_ASSERT_EQUAL(common8, '`');
|
||||
|
||||
@ -198,7 +198,7 @@ test_sigbits_encoding()
|
||||
0110000000000000 24576
|
||||
*/
|
||||
bytes = (uint8_t *)"aabbcc";
|
||||
pcb = initbytes(bytes, strlen((char *)bytes), PC_UINT16);
|
||||
pcb = initbytes(bytes, strlen((char *)bytes), PC_UINT16);
|
||||
count = pc_bytes_sigbits_count(&pcb);
|
||||
CU_ASSERT_EQUAL(count, 6);
|
||||
|
||||
@ -208,168 +208,168 @@ test_sigbits_encoding()
|
||||
01100000 01 10 11 01
|
||||
*/
|
||||
bytes = (uint8_t *)"abcaabcaabcbabcc";
|
||||
pcb = initbytes((uint8_t *)bytes, strlen((char *)bytes), PC_INT8);
|
||||
epcb = pc_bytes_sigbits_encode(pcb);
|
||||
CU_ASSERT_EQUAL(epcb.bytes[0], 2); /* unique bit count */
|
||||
CU_ASSERT_EQUAL(epcb.bytes[1], 96); /* common bits */
|
||||
CU_ASSERT_EQUAL(epcb.bytes[2], 109); /* packed byte */
|
||||
CU_ASSERT_EQUAL(epcb.bytes[3], 109); /* packed byte */
|
||||
CU_ASSERT_EQUAL(epcb.bytes[4], 110); /* packed byte */
|
||||
CU_ASSERT_EQUAL(epcb.bytes[5], 111); /* packed byte */
|
||||
pc_bytes_free(epcb);
|
||||
pcb = initbytes((uint8_t *)bytes, strlen((char *)bytes), PC_INT8);
|
||||
epcb = pc_bytes_sigbits_encode(pcb);
|
||||
CU_ASSERT_EQUAL(epcb.bytes[0], 2); /* unique bit count */
|
||||
CU_ASSERT_EQUAL(epcb.bytes[1], 96); /* common bits */
|
||||
CU_ASSERT_EQUAL(epcb.bytes[2], 109); /* packed byte */
|
||||
CU_ASSERT_EQUAL(epcb.bytes[3], 109); /* packed byte */
|
||||
CU_ASSERT_EQUAL(epcb.bytes[4], 110); /* packed byte */
|
||||
CU_ASSERT_EQUAL(epcb.bytes[5], 111); /* packed byte */
|
||||
pc_bytes_free(epcb);
|
||||
|
||||
/*
|
||||
"abca" encoded:
|
||||
base a b c d a b
|
||||
01100000 001 010 011 100 001 010
|
||||
*/
|
||||
bytes = (uint8_t *)"abcdab";
|
||||
pcb = initbytes(bytes, strlen((char *)bytes), PC_INT8);
|
||||
epcb = pc_bytes_sigbits_encode(pcb);
|
||||
CU_ASSERT_EQUAL(epcb.bytes[0], 3); /* unique bit count */
|
||||
CU_ASSERT_EQUAL(epcb.bytes[1], 96); /* common bits */
|
||||
CU_ASSERT_EQUAL(epcb.bytes[2], 41); /* packed byte */
|
||||
CU_ASSERT_EQUAL(epcb.bytes[3], 194); /* packed byte */
|
||||
bytes = (uint8_t *)"abcdab";
|
||||
pcb = initbytes(bytes, strlen((char *)bytes), PC_INT8);
|
||||
epcb = pc_bytes_sigbits_encode(pcb);
|
||||
CU_ASSERT_EQUAL(epcb.bytes[0], 3); /* unique bit count */
|
||||
CU_ASSERT_EQUAL(epcb.bytes[1], 96); /* common bits */
|
||||
CU_ASSERT_EQUAL(epcb.bytes[2], 41); /* packed byte */
|
||||
CU_ASSERT_EQUAL(epcb.bytes[3], 194); /* packed byte */
|
||||
|
||||
pcb2 = pc_bytes_sigbits_decode(epcb);
|
||||
CU_ASSERT_EQUAL(pcb2.bytes[0], 'a');
|
||||
CU_ASSERT_EQUAL(pcb2.bytes[1], 'b');
|
||||
CU_ASSERT_EQUAL(pcb2.bytes[2], 'c');
|
||||
CU_ASSERT_EQUAL(pcb2.bytes[3], 'd');
|
||||
CU_ASSERT_EQUAL(pcb2.bytes[4], 'a');
|
||||
CU_ASSERT_EQUAL(pcb2.bytes[5], 'b');
|
||||
|
||||
CU_ASSERT_EQUAL(pcb.compression, PC_DIM_NONE);
|
||||
CU_ASSERT_EQUAL(epcb.compression, PC_DIM_SIGBITS);
|
||||
CU_ASSERT_EQUAL(pcb2.compression, PC_DIM_NONE);
|
||||
pcb2 = pc_bytes_sigbits_decode(epcb);
|
||||
CU_ASSERT_EQUAL(pcb2.bytes[0], 'a');
|
||||
CU_ASSERT_EQUAL(pcb2.bytes[1], 'b');
|
||||
CU_ASSERT_EQUAL(pcb2.bytes[2], 'c');
|
||||
CU_ASSERT_EQUAL(pcb2.bytes[3], 'd');
|
||||
CU_ASSERT_EQUAL(pcb2.bytes[4], 'a');
|
||||
CU_ASSERT_EQUAL(pcb2.bytes[5], 'b');
|
||||
|
||||
pc_bytes_free(pcb2);
|
||||
pc_bytes_free(epcb);
|
||||
CU_ASSERT_EQUAL(pcb.compression, PC_DIM_NONE);
|
||||
CU_ASSERT_EQUAL(epcb.compression, PC_DIM_SIGBITS);
|
||||
CU_ASSERT_EQUAL(pcb2.compression, PC_DIM_NONE);
|
||||
|
||||
/* Test the 16 bit implementation path */
|
||||
nelems = 6;
|
||||
bytes16 = (uint16_t[]){
|
||||
24929, /* 0110000101100001 */
|
||||
24930, /* 0110000101100010 */
|
||||
24931, /* 0110000101100011 */
|
||||
24932, /* 0110000101100100 */
|
||||
24933, /* 0110000101100101 */
|
||||
24934 /* 0110000101100110 */
|
||||
};
|
||||
/* encoded 0110000101100 001 010 011 100 101 110 */
|
||||
bytes = (uint8_t*)bytes16;
|
||||
pcb = initbytes(bytes, nelems*2, PC_INT16);
|
||||
pc_bytes_free(pcb2);
|
||||
pc_bytes_free(epcb);
|
||||
|
||||
/* Test the 16 bit implementation path */
|
||||
common16 = pc_bytes_sigbits_count_16(&pcb, &count);
|
||||
CU_ASSERT_EQUAL(common16, 24928);
|
||||
CU_ASSERT_EQUAL(count, 13);
|
||||
epcb = pc_bytes_sigbits_encode(pcb);
|
||||
ebytes16 = (uint16_t*)(epcb.bytes);
|
||||
// printf("commonbits %d\n", commonbits);
|
||||
CU_ASSERT_EQUAL(ebytes16[0], 3); /* unique bit count */
|
||||
CU_ASSERT_EQUAL(ebytes16[1], 24928); /* common bits */
|
||||
CU_ASSERT_EQUAL(ebytes16[2], 10699); /* packed uint16 one */
|
||||
/* Test the 16 bit implementation path */
|
||||
nelems = 6;
|
||||
bytes16 = (uint16_t[]){
|
||||
24929, /* 0110000101100001 */
|
||||
24930, /* 0110000101100010 */
|
||||
24931, /* 0110000101100011 */
|
||||
24932, /* 0110000101100100 */
|
||||
24933, /* 0110000101100101 */
|
||||
24934 /* 0110000101100110 */
|
||||
};
|
||||
/* encoded 0110000101100 001 010 011 100 101 110 */
|
||||
bytes = (uint8_t*)bytes16;
|
||||
pcb = initbytes(bytes, nelems*2, PC_INT16);
|
||||
|
||||
/* uint8_t* pc_bytes_sigbits_decode(const uint8_t *bytes, uint32_t interpretation, uint32_t nelems) */
|
||||
pcb2 = pc_bytes_sigbits_decode(epcb);
|
||||
pc_bytes_free(epcb);
|
||||
bytes16 = (uint16_t*)(pcb2.bytes);
|
||||
CU_ASSERT_EQUAL(bytes16[0], 24929);
|
||||
CU_ASSERT_EQUAL(bytes16[1], 24930);
|
||||
CU_ASSERT_EQUAL(bytes16[2], 24931);
|
||||
CU_ASSERT_EQUAL(bytes16[3], 24932);
|
||||
CU_ASSERT_EQUAL(bytes16[4], 24933);
|
||||
CU_ASSERT_EQUAL(bytes16[5], 24934);
|
||||
pc_bytes_free(pcb2);
|
||||
/* Test the 16 bit implementation path */
|
||||
common16 = pc_bytes_sigbits_count_16(&pcb, &count);
|
||||
CU_ASSERT_EQUAL(common16, 24928);
|
||||
CU_ASSERT_EQUAL(count, 13);
|
||||
epcb = pc_bytes_sigbits_encode(pcb);
|
||||
ebytes16 = (uint16_t*)(epcb.bytes);
|
||||
// printf("commonbits %d\n", commonbits);
|
||||
CU_ASSERT_EQUAL(ebytes16[0], 3); /* unique bit count */
|
||||
CU_ASSERT_EQUAL(ebytes16[1], 24928); /* common bits */
|
||||
CU_ASSERT_EQUAL(ebytes16[2], 10699); /* packed uint16 one */
|
||||
|
||||
/* Test the 32 bit implementation path */
|
||||
nelems = 6;
|
||||
/* uint8_t* pc_bytes_sigbits_decode(const uint8_t *bytes, uint32_t interpretation, uint32_t nelems) */
|
||||
pcb2 = pc_bytes_sigbits_decode(epcb);
|
||||
pc_bytes_free(epcb);
|
||||
bytes16 = (uint16_t*)(pcb2.bytes);
|
||||
CU_ASSERT_EQUAL(bytes16[0], 24929);
|
||||
CU_ASSERT_EQUAL(bytes16[1], 24930);
|
||||
CU_ASSERT_EQUAL(bytes16[2], 24931);
|
||||
CU_ASSERT_EQUAL(bytes16[3], 24932);
|
||||
CU_ASSERT_EQUAL(bytes16[4], 24933);
|
||||
CU_ASSERT_EQUAL(bytes16[5], 24934);
|
||||
pc_bytes_free(pcb2);
|
||||
|
||||
bytes32 = (uint32_t[]){
|
||||
103241, /* 0000000000000001 1001 0011 0100 1001 */
|
||||
103251, /* 0000000000000001 1001 0011 0101 0011 */
|
||||
103261, /* 0000000000000001 1001 0011 0101 1101 */
|
||||
103271, /* 0000000000000001 1001 0011 0110 0111 */
|
||||
103281, /* 0000000000000001 1001 0011 0111 0001 */
|
||||
103291 /* 0000000000000001 1001 0011 0111 1011 */
|
||||
};
|
||||
bytes = (uint8_t*)bytes32;
|
||||
pcb = initbytes(bytes, nelems*4, PC_INT32);
|
||||
/* Test the 32 bit implementation path */
|
||||
nelems = 6;
|
||||
|
||||
common32 = pc_bytes_sigbits_count_32(&pcb, &count);
|
||||
CU_ASSERT_EQUAL(count, 26); /* common bits count */
|
||||
CU_ASSERT_EQUAL(common32, 103232);
|
||||
bytes32 = (uint32_t[]){
|
||||
103241, /* 0000000000000001 1001 0011 0100 1001 */
|
||||
103251, /* 0000000000000001 1001 0011 0101 0011 */
|
||||
103261, /* 0000000000000001 1001 0011 0101 1101 */
|
||||
103271, /* 0000000000000001 1001 0011 0110 0111 */
|
||||
103281, /* 0000000000000001 1001 0011 0111 0001 */
|
||||
103291 /* 0000000000000001 1001 0011 0111 1011 */
|
||||
};
|
||||
bytes = (uint8_t*)bytes32;
|
||||
pcb = initbytes(bytes, nelems*4, PC_INT32);
|
||||
|
||||
epcb = pc_bytes_sigbits_encode(pcb);
|
||||
ebytes32 = (uint32_t*)(epcb.bytes);
|
||||
CU_ASSERT_EQUAL(ebytes32[0], 6); /* unique bit count */
|
||||
CU_ASSERT_EQUAL(ebytes32[1], 103232); /* common bits */
|
||||
CU_ASSERT_EQUAL(ebytes32[2], 624388039); /* packed uint32 */
|
||||
common32 = pc_bytes_sigbits_count_32(&pcb, &count);
|
||||
CU_ASSERT_EQUAL(count, 26); /* common bits count */
|
||||
CU_ASSERT_EQUAL(common32, 103232);
|
||||
|
||||
pcb2 = pc_bytes_sigbits_decode(epcb);
|
||||
pc_bytes_free(epcb);
|
||||
bytes32 = (uint32_t*)(pcb2.bytes);
|
||||
CU_ASSERT_EQUAL(bytes32[0], 103241);
|
||||
CU_ASSERT_EQUAL(bytes32[1], 103251);
|
||||
CU_ASSERT_EQUAL(bytes32[2], 103261);
|
||||
CU_ASSERT_EQUAL(bytes32[3], 103271);
|
||||
CU_ASSERT_EQUAL(bytes32[4], 103281);
|
||||
CU_ASSERT_EQUAL(bytes32[5], 103291);
|
||||
pc_bytes_free(pcb2);
|
||||
epcb = pc_bytes_sigbits_encode(pcb);
|
||||
ebytes32 = (uint32_t*)(epcb.bytes);
|
||||
CU_ASSERT_EQUAL(ebytes32[0], 6); /* unique bit count */
|
||||
CU_ASSERT_EQUAL(ebytes32[1], 103232); /* common bits */
|
||||
CU_ASSERT_EQUAL(ebytes32[2], 624388039); /* packed uint32 */
|
||||
|
||||
/* What if all the words are the same? */
|
||||
nelems = 6;
|
||||
bytes16 = (uint16_t[]){
|
||||
24929, /* 0000000000000001 1001 0011 0100 1001 */
|
||||
24929, /* 0000000000000001 1001 0011 0101 0011 */
|
||||
24929, /* 0000000000000001 1001 0011 0101 1101 */
|
||||
24929, /* 0000000000000001 1001 0011 0110 0111 */
|
||||
24929, /* 0000000000000001 1001 0011 0111 0001 */
|
||||
24929 /* 0000000000000001 1001 0011 0111 1011 */
|
||||
};
|
||||
bytes = (uint8_t*)bytes16;
|
||||
pcb = initbytes(bytes, nelems*2, PC_INT16);
|
||||
epcb = pc_bytes_sigbits_encode(pcb);
|
||||
pcb2 = pc_bytes_sigbits_decode(epcb);
|
||||
pc_bytes_free(epcb);
|
||||
pc_bytes_free(pcb2);
|
||||
pcb2 = pc_bytes_sigbits_decode(epcb);
|
||||
pc_bytes_free(epcb);
|
||||
bytes32 = (uint32_t*)(pcb2.bytes);
|
||||
CU_ASSERT_EQUAL(bytes32[0], 103241);
|
||||
CU_ASSERT_EQUAL(bytes32[1], 103251);
|
||||
CU_ASSERT_EQUAL(bytes32[2], 103261);
|
||||
CU_ASSERT_EQUAL(bytes32[3], 103271);
|
||||
CU_ASSERT_EQUAL(bytes32[4], 103281);
|
||||
CU_ASSERT_EQUAL(bytes32[5], 103291);
|
||||
pc_bytes_free(pcb2);
|
||||
|
||||
/* Test the 64 bit implementation path */
|
||||
/* What if all the words are the same? */
|
||||
nelems = 6;
|
||||
bytes16 = (uint16_t[]){
|
||||
24929, /* 0000000000000001 1001 0011 0100 1001 */
|
||||
24929, /* 0000000000000001 1001 0011 0101 0011 */
|
||||
24929, /* 0000000000000001 1001 0011 0101 1101 */
|
||||
24929, /* 0000000000000001 1001 0011 0110 0111 */
|
||||
24929, /* 0000000000000001 1001 0011 0111 0001 */
|
||||
24929 /* 0000000000000001 1001 0011 0111 1011 */
|
||||
};
|
||||
bytes = (uint8_t*)bytes16;
|
||||
pcb = initbytes(bytes, nelems*2, PC_INT16);
|
||||
epcb = pc_bytes_sigbits_encode(pcb);
|
||||
pcb2 = pc_bytes_sigbits_decode(epcb);
|
||||
pc_bytes_free(epcb);
|
||||
pc_bytes_free(pcb2);
|
||||
|
||||
nelems = 6;
|
||||
/* Test the 64 bit implementation path */
|
||||
|
||||
bytes64 = (uint64_t[]){
|
||||
103241, /* 32x0 0000000000000001 1001 0011 0100 1001 */
|
||||
103251, /* 32x0 0000000000000001 1001 0011 0101 0011 */
|
||||
103261, /* 32x0 0000000000000001 1001 0011 0101 1101 */
|
||||
103271, /* 32x0 0000000000000001 1001 0011 0110 0111 */
|
||||
103281, /* 32x0 0000000000000001 1001 0011 0111 0001 */
|
||||
103291 /* 32x0 0000000000000001 1001 0011 0111 1011 */
|
||||
};
|
||||
bytes = (uint8_t*)bytes64;
|
||||
pcb = initbytes(bytes, nelems*8, PC_INT64);
|
||||
nelems = 6;
|
||||
|
||||
common64 = pc_bytes_sigbits_count_64(&pcb, &count);
|
||||
CU_ASSERT_EQUAL(count, 58); /* common bits count */
|
||||
CU_ASSERT_EQUAL(common64, 103232);
|
||||
bytes64 = (uint64_t[]){
|
||||
103241, /* 32x0 0000000000000001 1001 0011 0100 1001 */
|
||||
103251, /* 32x0 0000000000000001 1001 0011 0101 0011 */
|
||||
103261, /* 32x0 0000000000000001 1001 0011 0101 1101 */
|
||||
103271, /* 32x0 0000000000000001 1001 0011 0110 0111 */
|
||||
103281, /* 32x0 0000000000000001 1001 0011 0111 0001 */
|
||||
103291 /* 32x0 0000000000000001 1001 0011 0111 1011 */
|
||||
};
|
||||
bytes = (uint8_t*)bytes64;
|
||||
pcb = initbytes(bytes, nelems*8, PC_INT64);
|
||||
|
||||
epcb = pc_bytes_sigbits_encode(pcb);
|
||||
ebytes64 = (uint64_t*)(epcb.bytes);
|
||||
CU_ASSERT_EQUAL(ebytes64[0], 6); /* unique bit count */
|
||||
CU_ASSERT_EQUAL(ebytes64[1], 103232); /* common bits */
|
||||
CU_ASSERT_EQUAL(ebytes64[2], 2681726210471362560); /* packed uint64 */
|
||||
common64 = pc_bytes_sigbits_count_64(&pcb, &count);
|
||||
CU_ASSERT_EQUAL(count, 58); /* common bits count */
|
||||
CU_ASSERT_EQUAL(common64, 103232);
|
||||
|
||||
pcb2 = pc_bytes_sigbits_decode(epcb);
|
||||
pc_bytes_free(epcb);
|
||||
bytes64 = (uint64_t*)(pcb2.bytes);
|
||||
CU_ASSERT_EQUAL(bytes64[0], 103241);
|
||||
CU_ASSERT_EQUAL(bytes64[1], 103251);
|
||||
CU_ASSERT_EQUAL(bytes64[2], 103261);
|
||||
CU_ASSERT_EQUAL(bytes64[3], 103271);
|
||||
CU_ASSERT_EQUAL(bytes64[4], 103281);
|
||||
CU_ASSERT_EQUAL(bytes64[5], 103291);
|
||||
pc_bytes_free(pcb2);
|
||||
epcb = pc_bytes_sigbits_encode(pcb);
|
||||
ebytes64 = (uint64_t*)(epcb.bytes);
|
||||
CU_ASSERT_EQUAL(ebytes64[0], 6); /* unique bit count */
|
||||
CU_ASSERT_EQUAL(ebytes64[1], 103232); /* common bits */
|
||||
CU_ASSERT_EQUAL(ebytes64[2], 2681726210471362560); /* packed uint64 */
|
||||
|
||||
pcb2 = pc_bytes_sigbits_decode(epcb);
|
||||
pc_bytes_free(epcb);
|
||||
bytes64 = (uint64_t*)(pcb2.bytes);
|
||||
CU_ASSERT_EQUAL(bytes64[0], 103241);
|
||||
CU_ASSERT_EQUAL(bytes64[1], 103251);
|
||||
CU_ASSERT_EQUAL(bytes64[2], 103261);
|
||||
CU_ASSERT_EQUAL(bytes64[3], 103271);
|
||||
CU_ASSERT_EQUAL(bytes64[4], 103281);
|
||||
CU_ASSERT_EQUAL(bytes64[5], 103291);
|
||||
pc_bytes_free(pcb2);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -378,26 +378,26 @@ test_sigbits_encoding()
|
||||
static void
|
||||
test_zlib_encoding()
|
||||
{
|
||||
uint8_t *bytes;
|
||||
PCBYTES pcb, epcb, pcb2;
|
||||
/*
|
||||
uint8_t *
|
||||
pc_bytes_zlib_encode(const uint8_t *bytes, uint32_t interpretation, uint32_t nelems)
|
||||
uint8_t *
|
||||
pc_bytes_zlib_decode(const uint8_t *bytes, uint32_t interpretation)
|
||||
*/
|
||||
bytes = (uint8_t *)"abcaabcaabcbabcc";
|
||||
pcb = initbytes(bytes, strlen((char *)bytes), PC_INT8);
|
||||
epcb = pc_bytes_zlib_encode(pcb);
|
||||
pcb2 = pc_bytes_zlib_decode(epcb);
|
||||
uint8_t *bytes;
|
||||
PCBYTES pcb, epcb, pcb2;
|
||||
/*
|
||||
uint8_t *
|
||||
pc_bytes_zlib_encode(const uint8_t *bytes, uint32_t interpretation, uint32_t nelems)
|
||||
uint8_t *
|
||||
pc_bytes_zlib_decode(const uint8_t *bytes, uint32_t interpretation)
|
||||
*/
|
||||
bytes = (uint8_t *)"abcaabcaabcbabcc";
|
||||
pcb = initbytes(bytes, strlen((char *)bytes), PC_INT8);
|
||||
epcb = pc_bytes_zlib_encode(pcb);
|
||||
pcb2 = pc_bytes_zlib_decode(epcb);
|
||||
|
||||
CU_ASSERT_EQUAL(pcb.compression, PC_DIM_NONE);
|
||||
CU_ASSERT_EQUAL(epcb.compression, PC_DIM_ZLIB);
|
||||
CU_ASSERT_EQUAL(pcb2.compression, PC_DIM_NONE);
|
||||
CU_ASSERT_EQUAL(pcb.compression, PC_DIM_NONE);
|
||||
CU_ASSERT_EQUAL(epcb.compression, PC_DIM_ZLIB);
|
||||
CU_ASSERT_EQUAL(pcb2.compression, PC_DIM_NONE);
|
||||
|
||||
CU_ASSERT_EQUAL(memcmp(pcb.bytes, pcb2.bytes, pcb.size), 0);
|
||||
pc_bytes_free(epcb);
|
||||
pc_bytes_free(pcb2);
|
||||
pc_bytes_free(epcb);
|
||||
pc_bytes_free(pcb2);
|
||||
}
|
||||
|
||||
|
||||
@ -405,81 +405,81 @@ static void
|
||||
test_rle_filter()
|
||||
{
|
||||
char *bytes;
|
||||
PCBYTES pcb, epcb, fpcb;
|
||||
PCBITMAP *map1, *map2;
|
||||
int i;
|
||||
PCBYTES pcb, epcb, fpcb;
|
||||
PCBITMAP *map1, *map2;
|
||||
int i;
|
||||
|
||||
/*
|
||||
typedef struct
|
||||
{
|
||||
size_t size;
|
||||
uint32_t npoints;
|
||||
uint32_t interpretation;
|
||||
uint32_t compression;
|
||||
uint8_t *bytes;
|
||||
} PCBYTES;
|
||||
*/
|
||||
/*
|
||||
typedef struct
|
||||
{
|
||||
size_t size;
|
||||
uint32_t npoints;
|
||||
uint32_t interpretation;
|
||||
uint32_t compression;
|
||||
uint8_t *bytes;
|
||||
} PCBYTES;
|
||||
*/
|
||||
|
||||
bytes = "aaaabbbbccdd";
|
||||
pcb = initbytes((uint8_t *)bytes, strlen(bytes), PC_UINT8);
|
||||
epcb = pc_bytes_run_length_encode(pcb);
|
||||
CU_ASSERT_EQUAL(epcb.bytes[0], 4);
|
||||
|
||||
map1 = pc_bytes_bitmap(&epcb, PC_GT, 'b', 'b');
|
||||
CU_ASSERT_EQUAL(map1->nset, 4);
|
||||
map2 = pc_bytes_bitmap(&epcb, PC_GT, 'a', 'a');
|
||||
CU_ASSERT_EQUAL(map2->nset, 8);
|
||||
|
||||
fpcb = pc_bytes_filter(&epcb, map1, NULL);
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[0], 2);
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[1], 'c');
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[2], 2);
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[3], 'd');
|
||||
CU_ASSERT_EQUAL(fpcb.size, 4);
|
||||
CU_ASSERT_EQUAL(fpcb.npoints, 4);
|
||||
bytes = "aaaabbbbccdd";
|
||||
pcb = initbytes((uint8_t *)bytes, strlen(bytes), PC_UINT8);
|
||||
epcb = pc_bytes_run_length_encode(pcb);
|
||||
CU_ASSERT_EQUAL(epcb.bytes[0], 4);
|
||||
|
||||
map1 = pc_bytes_bitmap(&epcb, PC_GT, 'b', 'b');
|
||||
CU_ASSERT_EQUAL(map1->nset, 4);
|
||||
map2 = pc_bytes_bitmap(&epcb, PC_GT, 'a', 'a');
|
||||
CU_ASSERT_EQUAL(map2->nset, 8);
|
||||
|
||||
fpcb = pc_bytes_filter(&epcb, map1, NULL);
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[0], 2);
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[1], 'c');
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[2], 2);
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[3], 'd');
|
||||
CU_ASSERT_EQUAL(fpcb.size, 4);
|
||||
CU_ASSERT_EQUAL(fpcb.npoints, 4);
|
||||
pc_bytes_free(fpcb);
|
||||
pc_bitmap_free(map1);
|
||||
pc_bitmap_free(map1);
|
||||
|
||||
fpcb = pc_bytes_filter(&epcb, map2, NULL);
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[0], 4);
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[1], 'b');
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[2], 2);
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[3], 'c');
|
||||
CU_ASSERT_EQUAL(fpcb.size, 6);
|
||||
CU_ASSERT_EQUAL(fpcb.npoints, 8);
|
||||
fpcb = pc_bytes_filter(&epcb, map2, NULL);
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[0], 4);
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[1], 'b');
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[2], 2);
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[3], 'c');
|
||||
CU_ASSERT_EQUAL(fpcb.size, 6);
|
||||
CU_ASSERT_EQUAL(fpcb.npoints, 8);
|
||||
pc_bytes_free(fpcb);
|
||||
pc_bitmap_free(map2);
|
||||
pc_bitmap_free(map2);
|
||||
pc_bytes_free(epcb);
|
||||
|
||||
bytes = (char *)((uint32_t[]){ 10, 10, 10, 20, 20, 30, 20, 20 });
|
||||
pcb = initbytes((uint8_t *)bytes, 8*4, PC_UINT32);
|
||||
epcb = pc_bytes_run_length_encode(pcb);
|
||||
map1 = pc_bytes_bitmap(&epcb, PC_LT, 25, 25); /* strip out the 30 */
|
||||
CU_ASSERT_EQUAL(map1->nset, 7);
|
||||
fpcb = pc_bytes_filter(&epcb, map1, NULL);
|
||||
CU_ASSERT_EQUAL(fpcb.size, 15); /* three runs (2x10, 2x20, 2x20), of 5 bytes eachh */
|
||||
CU_ASSERT_EQUAL(fpcb.npoints, 7);
|
||||
bytes = (char *)((uint32_t[]){ 10, 10, 10, 20, 20, 30, 20, 20 });
|
||||
pcb = initbytes((uint8_t *)bytes, 8*4, PC_UINT32);
|
||||
epcb = pc_bytes_run_length_encode(pcb);
|
||||
map1 = pc_bytes_bitmap(&epcb, PC_LT, 25, 25); /* strip out the 30 */
|
||||
CU_ASSERT_EQUAL(map1->nset, 7);
|
||||
fpcb = pc_bytes_filter(&epcb, map1, NULL);
|
||||
CU_ASSERT_EQUAL(fpcb.size, 15); /* three runs (2x10, 2x20, 2x20), of 5 bytes eachh */
|
||||
CU_ASSERT_EQUAL(fpcb.npoints, 7);
|
||||
pc_bytes_free(fpcb);
|
||||
pc_bytes_free(pcb);
|
||||
pc_bitmap_free(map1);
|
||||
pc_bitmap_free(map1);
|
||||
|
||||
bytes = (char *)((uint16_t[]){ 1, 2, 3, 4, 5, 6, 7, 8 });
|
||||
pcb = initbytes((uint8_t *)bytes, 8*2, PC_UINT16);
|
||||
map1 = pc_bytes_bitmap(&pcb, PC_BETWEEN, 2.5, 4.5); /* everything except entries 3 and 4 */
|
||||
bytes = (char *)((uint16_t[]){ 1, 2, 3, 4, 5, 6, 7, 8 });
|
||||
pcb = initbytes((uint8_t *)bytes, 8*2, PC_UINT16);
|
||||
map1 = pc_bytes_bitmap(&pcb, PC_BETWEEN, 2.5, 4.5); /* everything except entries 3 and 4 */
|
||||
CU_ASSERT_EQUAL(map1->nset, 2);
|
||||
fpcb = pc_bytes_filter(&epcb, map1, NULL); /* Should have only two entry, 10, 20 */
|
||||
CU_ASSERT_EQUAL(fpcb.size, 10); /* two runs (1x10, 1x20), of 5 bytes eachh */
|
||||
CU_ASSERT_EQUAL(fpcb.npoints, 2);
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[0], 1);
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[5], 1);
|
||||
memcpy(&i, fpcb.bytes+1, 4);
|
||||
CU_ASSERT_EQUAL(i, 10);
|
||||
memcpy(&i, fpcb.bytes+6, 4);
|
||||
CU_ASSERT_EQUAL(i, 20);
|
||||
|
||||
fpcb = pc_bytes_filter(&epcb, map1, NULL); /* Should have only two entry, 10, 20 */
|
||||
CU_ASSERT_EQUAL(fpcb.size, 10); /* two runs (1x10, 1x20), of 5 bytes eachh */
|
||||
CU_ASSERT_EQUAL(fpcb.npoints, 2);
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[0], 1);
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[5], 1);
|
||||
memcpy(&i, fpcb.bytes+1, 4);
|
||||
CU_ASSERT_EQUAL(i, 10);
|
||||
memcpy(&i, fpcb.bytes+6, 4);
|
||||
CU_ASSERT_EQUAL(i, 20);
|
||||
|
||||
pc_bytes_free(fpcb);
|
||||
pc_bytes_free(pcb);
|
||||
pc_bitmap_free(map1);
|
||||
pc_bitmap_free(map1);
|
||||
pc_bytes_free(epcb);
|
||||
}
|
||||
|
||||
@ -489,34 +489,34 @@ static void
|
||||
test_uncompressed_filter()
|
||||
{
|
||||
char *bytes;
|
||||
PCBYTES pcb, fpcb;
|
||||
PCBITMAP *map1;
|
||||
PCBYTES pcb, fpcb;
|
||||
PCBITMAP *map1;
|
||||
|
||||
/*
|
||||
typedef struct
|
||||
{
|
||||
size_t size;
|
||||
uint32_t npoints;
|
||||
uint32_t interpretation;
|
||||
uint32_t compression;
|
||||
uint8_t *bytes;
|
||||
} PCBYTES;
|
||||
*/
|
||||
/*
|
||||
typedef struct
|
||||
{
|
||||
size_t size;
|
||||
uint32_t npoints;
|
||||
uint32_t interpretation;
|
||||
uint32_t compression;
|
||||
uint8_t *bytes;
|
||||
} PCBYTES;
|
||||
*/
|
||||
|
||||
bytes = "aaaabbbbccdd";
|
||||
pcb = initbytes((uint8_t *)bytes, strlen(bytes), PC_UINT8);
|
||||
CU_ASSERT_EQUAL(pcb.bytes[0], 'a');
|
||||
CU_ASSERT_EQUAL(pcb.npoints, 12);
|
||||
|
||||
map1 = pc_bytes_bitmap(&pcb, PC_GT, 'b', 'b');
|
||||
CU_ASSERT_EQUAL(map1->nset, 4);
|
||||
|
||||
fpcb = pc_bytes_filter(&pcb, map1, NULL);
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[0], 'c');
|
||||
CU_ASSERT_EQUAL(fpcb.size, 4);
|
||||
CU_ASSERT_EQUAL(fpcb.npoints, 4);
|
||||
pc_bytes_free(fpcb);
|
||||
pc_bitmap_free(map1);
|
||||
bytes = "aaaabbbbccdd";
|
||||
pcb = initbytes((uint8_t *)bytes, strlen(bytes), PC_UINT8);
|
||||
CU_ASSERT_EQUAL(pcb.bytes[0], 'a');
|
||||
CU_ASSERT_EQUAL(pcb.npoints, 12);
|
||||
|
||||
map1 = pc_bytes_bitmap(&pcb, PC_GT, 'b', 'b');
|
||||
CU_ASSERT_EQUAL(map1->nset, 4);
|
||||
|
||||
fpcb = pc_bytes_filter(&pcb, map1, NULL);
|
||||
CU_ASSERT_EQUAL(fpcb.bytes[0], 'c');
|
||||
CU_ASSERT_EQUAL(fpcb.size, 4);
|
||||
CU_ASSERT_EQUAL(fpcb.npoints, 4);
|
||||
pc_bytes_free(fpcb);
|
||||
pc_bitmap_free(map1);
|
||||
// pc_bytes_free(epcb);
|
||||
|
||||
}
|
||||
@ -534,8 +534,8 @@ CU_TestInfo bytes_tests[] = {
|
||||
};
|
||||
|
||||
CU_SuiteInfo bytes_suite = {
|
||||
.pName = "bytes",
|
||||
.pInitFunc = init_suite,
|
||||
.pCleanupFunc = clean_suite,
|
||||
.pTests = bytes_tests
|
||||
.pName = "bytes",
|
||||
.pInitFunc = init_suite,
|
||||
.pCleanupFunc = clean_suite,
|
||||
.pTests = bytes_tests
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -41,94 +41,94 @@ clean_suite(void)
|
||||
static void
|
||||
test_patch_ght()
|
||||
{
|
||||
PCPOINT *pt;
|
||||
int i;
|
||||
static int npts = 100;
|
||||
PCPOINTLIST *pl;
|
||||
PCPATCH_GHT *pag;
|
||||
PCPATCH_UNCOMPRESSED *pu;
|
||||
PCPOINT *pt;
|
||||
int i;
|
||||
static int npts = 100;
|
||||
PCPOINTLIST *pl;
|
||||
PCPATCH_GHT *pag;
|
||||
PCPATCH_UNCOMPRESSED *pu;
|
||||
|
||||
pl = pc_pointlist_make(npts);
|
||||
pl = pc_pointlist_make(npts);
|
||||
|
||||
for ( i = 0; i < npts; i++ )
|
||||
{
|
||||
pt = pc_point_make(simpleschema);
|
||||
pc_point_set_double_by_name(pt, "x", 45 + i*0.000004);
|
||||
pc_point_set_double_by_name(pt, "y", 45 + i*0.000001666);
|
||||
pc_point_set_double_by_name(pt, "Z", 10 + i*0.34);
|
||||
pc_point_set_double_by_name(pt, "intensity", 10);
|
||||
pc_pointlist_add_point(pl, pt);
|
||||
}
|
||||
for ( i = 0; i < npts; i++ )
|
||||
{
|
||||
pt = pc_point_make(simpleschema);
|
||||
pc_point_set_double_by_name(pt, "x", 45 + i*0.000004);
|
||||
pc_point_set_double_by_name(pt, "y", 45 + i*0.000001666);
|
||||
pc_point_set_double_by_name(pt, "Z", 10 + i*0.34);
|
||||
pc_point_set_double_by_name(pt, "intensity", 10);
|
||||
pc_pointlist_add_point(pl, pt);
|
||||
}
|
||||
|
||||
pag = pc_patch_ght_from_pointlist(pl);
|
||||
pc_pointlist_free(pl);
|
||||
pag = pc_patch_ght_from_pointlist(pl);
|
||||
pc_pointlist_free(pl);
|
||||
|
||||
pu = pc_patch_uncompressed_from_ght(pag);
|
||||
CU_ASSERT_EQUAL(npts, pag->npoints);
|
||||
CU_ASSERT_EQUAL(npts, pu->npoints);
|
||||
pu = pc_patch_uncompressed_from_ght(pag);
|
||||
CU_ASSERT_EQUAL(npts, pag->npoints);
|
||||
CU_ASSERT_EQUAL(npts, pu->npoints);
|
||||
|
||||
CU_ASSERT_DOUBLE_EQUAL(pag->bounds.xmax, 45.0004, 0.0001);
|
||||
CU_ASSERT_DOUBLE_EQUAL(pag->bounds.ymax, 45.000165, 0.000001);
|
||||
CU_ASSERT_DOUBLE_EQUAL(pag->bounds.xmax, 45.0004, 0.0001);
|
||||
CU_ASSERT_DOUBLE_EQUAL(pag->bounds.ymax, 45.000165, 0.000001);
|
||||
|
||||
// pl2 = pc_pointlist_from_uncompressed(pu);
|
||||
// for ( i = 0; i < npts; i++ )
|
||||
// {
|
||||
// PCPOINT *pt = pc_pointlist_get_point(pl2, i);
|
||||
// double x, y, z, ints;
|
||||
// pc_point_get_double_by_name(pt, "x", &x);
|
||||
// pc_point_get_double_by_name(pt, "y", &y);
|
||||
// pc_point_get_double_by_name(pt, "Z", &z);
|
||||
// pc_point_get_double_by_name(pt, "intensity", &ints);
|
||||
// printf("(%g %g %g) %g\n", x, y, z, ints);
|
||||
// }
|
||||
// pc_pointlist_free(pl2);
|
||||
|
||||
pc_patch_uncompressed_free(pu);
|
||||
pc_patch_ght_free(pag);
|
||||
// pl2 = pc_pointlist_from_uncompressed(pu);
|
||||
// for ( i = 0; i < npts; i++ )
|
||||
// {
|
||||
// PCPOINT *pt = pc_pointlist_get_point(pl2, i);
|
||||
// double x, y, z, ints;
|
||||
// pc_point_get_double_by_name(pt, "x", &x);
|
||||
// pc_point_get_double_by_name(pt, "y", &y);
|
||||
// pc_point_get_double_by_name(pt, "Z", &z);
|
||||
// pc_point_get_double_by_name(pt, "intensity", &ints);
|
||||
// printf("(%g %g %g) %g\n", x, y, z, ints);
|
||||
// }
|
||||
// pc_pointlist_free(pl2);
|
||||
|
||||
pc_patch_uncompressed_free(pu);
|
||||
pc_patch_ght_free(pag);
|
||||
}
|
||||
|
||||
static void
|
||||
test_patch_ght_filtering()
|
||||
{
|
||||
int dimnum = 2; /* Z */
|
||||
PCPOINT *pt;
|
||||
int i;
|
||||
static int npts = 100;
|
||||
PCPOINTLIST *pl;
|
||||
PCPATCH_GHT *pag, *pag_filtered;
|
||||
|
||||
pl = pc_pointlist_make(npts);
|
||||
int dimnum = 2; /* Z */
|
||||
PCPOINT *pt;
|
||||
int i;
|
||||
static int npts = 100;
|
||||
PCPOINTLIST *pl;
|
||||
PCPATCH_GHT *pag, *pag_filtered;
|
||||
|
||||
for ( i = 0; i < npts; i++ )
|
||||
{
|
||||
pt = pc_point_make(simpleschema);
|
||||
pc_point_set_double_by_name(pt, "x", 45 + i*0.000004);
|
||||
pc_point_set_double_by_name(pt, "y", 45 + i*0.000001666);
|
||||
pc_point_set_double_by_name(pt, "Z", 10 + i*0.34);
|
||||
pc_point_set_double_by_name(pt, "intensity", 10);
|
||||
pc_pointlist_add_point(pl, pt);
|
||||
}
|
||||
pl = pc_pointlist_make(npts);
|
||||
|
||||
pag = pc_patch_ght_from_pointlist(pl);
|
||||
pc_pointlist_free(pl);
|
||||
for ( i = 0; i < npts; i++ )
|
||||
{
|
||||
pt = pc_point_make(simpleschema);
|
||||
pc_point_set_double_by_name(pt, "x", 45 + i*0.000004);
|
||||
pc_point_set_double_by_name(pt, "y", 45 + i*0.000001666);
|
||||
pc_point_set_double_by_name(pt, "Z", 10 + i*0.34);
|
||||
pc_point_set_double_by_name(pt, "intensity", 10);
|
||||
pc_pointlist_add_point(pl, pt);
|
||||
}
|
||||
|
||||
pag_filtered = pc_patch_ght_filter(pag, dimnum, PC_LT, 10, 10);
|
||||
CU_ASSERT_EQUAL(pag_filtered->npoints, 0);
|
||||
pc_patch_ght_free(pag_filtered);
|
||||
pag = pc_patch_ght_from_pointlist(pl);
|
||||
pc_pointlist_free(pl);
|
||||
|
||||
pag_filtered = pc_patch_ght_filter(pag, dimnum, PC_LT, 11, 11);
|
||||
CU_ASSERT_EQUAL(pag_filtered->npoints, 3);
|
||||
pc_patch_ght_free(pag_filtered);
|
||||
pag_filtered = pc_patch_ght_filter(pag, dimnum, PC_LT, 10, 10);
|
||||
CU_ASSERT_EQUAL(pag_filtered->npoints, 0);
|
||||
pc_patch_ght_free(pag_filtered);
|
||||
|
||||
pag_filtered = pc_patch_ght_filter(pag, dimnum, PC_GT, 11, 11);
|
||||
CU_ASSERT_EQUAL(pag_filtered->npoints, 97);
|
||||
pc_patch_ght_free(pag_filtered);
|
||||
pag_filtered = pc_patch_ght_filter(pag, dimnum, PC_LT, 11, 11);
|
||||
CU_ASSERT_EQUAL(pag_filtered->npoints, 3);
|
||||
pc_patch_ght_free(pag_filtered);
|
||||
|
||||
pag_filtered = pc_patch_ght_filter(pag, dimnum, PC_BETWEEN, 11, 16);
|
||||
CU_ASSERT_EQUAL(pag_filtered->npoints, 15);
|
||||
pc_patch_ght_free(pag_filtered);
|
||||
pag_filtered = pc_patch_ght_filter(pag, dimnum, PC_GT, 11, 11);
|
||||
CU_ASSERT_EQUAL(pag_filtered->npoints, 97);
|
||||
pc_patch_ght_free(pag_filtered);
|
||||
|
||||
pc_patch_ght_free(pag);
|
||||
pag_filtered = pc_patch_ght_filter(pag, dimnum, PC_BETWEEN, 11, 16);
|
||||
CU_ASSERT_EQUAL(pag_filtered->npoints, 15);
|
||||
pc_patch_ght_free(pag_filtered);
|
||||
|
||||
pc_patch_ght_free(pag);
|
||||
}
|
||||
|
||||
|
||||
@ -145,8 +145,8 @@ CU_TestInfo ght_tests[] = {
|
||||
};
|
||||
|
||||
CU_SuiteInfo ght_suite = {
|
||||
.pName = "ght",
|
||||
.pInitFunc = init_suite,
|
||||
.pCleanupFunc = clean_suite,
|
||||
.pTests = ght_tests
|
||||
.pName = "ght",
|
||||
.pInitFunc = init_suite,
|
||||
.pCleanupFunc = clean_suite,
|
||||
.pTests = ght_tests
|
||||
};
|
||||
|
||||
@ -262,8 +262,8 @@ CU_TestInfo lazperf_tests[] = {
|
||||
};
|
||||
|
||||
CU_SuiteInfo lazperf_suite = {
|
||||
.pName = "lazperf",
|
||||
.pInitFunc = init_suite,
|
||||
.pCleanupFunc = clean_suite,
|
||||
.pTests = lazperf_tests
|
||||
.pName = "lazperf",
|
||||
.pInitFunc = init_suite,
|
||||
.pCleanupFunc = clean_suite,
|
||||
.pTests = lazperf_tests
|
||||
};
|
||||
|
||||
@ -45,9 +45,9 @@ clean_suite(void)
|
||||
static void
|
||||
test_point_hex_inout()
|
||||
{
|
||||
// byte: endianness (1 = NDR, 0 = XDR)
|
||||
// uint32: pcid (key to POINTCLOUD_SCHEMAS)
|
||||
// uchar[]: pointdata (interpret relative to pcid)
|
||||
// byte: endianness (1 = NDR, 0 = XDR)
|
||||
// uint32: pcid (key to POINTCLOUD_SCHEMAS)
|
||||
// uchar[]: pointdata (interpret relative to pcid)
|
||||
|
||||
double d;
|
||||
char *hexbuf = "00000000010000000100000002000000030004";
|
||||
@ -160,8 +160,8 @@ CU_TestInfo point_tests[] = {
|
||||
};
|
||||
|
||||
CU_SuiteInfo point_suite = {
|
||||
.pName = "point",
|
||||
.pInitFunc = init_suite,
|
||||
.pCleanupFunc = clean_suite,
|
||||
.pTests = point_tests
|
||||
.pName = "point",
|
||||
.pInitFunc = init_suite,
|
||||
.pCleanupFunc = clean_suite,
|
||||
.pTests = point_tests
|
||||
};
|
||||
|
||||
@ -56,15 +56,15 @@ test_schema_from_xml()
|
||||
static void
|
||||
test_schema_from_xml_with_empty_field()
|
||||
{
|
||||
PCSCHEMA *myschema = NULL;
|
||||
char *myxmlfile = "data/simple-schema-empty-field.xml";
|
||||
char *xmlstr = file_to_str(myxmlfile);
|
||||
int rv = pc_schema_from_xml(xmlstr, &myschema);
|
||||
PCSCHEMA *myschema = NULL;
|
||||
char *myxmlfile = "data/simple-schema-empty-field.xml";
|
||||
char *xmlstr = file_to_str(myxmlfile);
|
||||
int rv = pc_schema_from_xml(xmlstr, &myschema);
|
||||
|
||||
CU_ASSERT(rv == PC_SUCCESS);
|
||||
CU_ASSERT(rv == PC_SUCCESS);
|
||||
|
||||
pc_schema_free(myschema);
|
||||
pcfree(xmlstr);
|
||||
pc_schema_free(myschema);
|
||||
pcfree(xmlstr);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -142,76 +142,76 @@ test_schema_is_valid()
|
||||
rv = pc_schema_from_xml(xmlstr, &myschema);
|
||||
CU_ASSERT_EQUAL(rv, PC_SUCCESS);
|
||||
|
||||
cu_error_msg_reset();
|
||||
rv = pc_schema_is_valid(myschema);
|
||||
cu_error_msg_reset();
|
||||
rv = pc_schema_is_valid(myschema);
|
||||
CU_ASSERT_EQUAL(rv, PC_FAILURE);
|
||||
|
||||
pc_schema_free(myschema);
|
||||
pc_schema_free(myschema);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
test_schema_compression(void)
|
||||
{
|
||||
int compression = schema->compression;
|
||||
CU_ASSERT_EQUAL(compression, PC_DIMENSIONAL);
|
||||
int compression = schema->compression;
|
||||
CU_ASSERT_EQUAL(compression, PC_DIMENSIONAL);
|
||||
}
|
||||
|
||||
static void
|
||||
test_schema_clone(void)
|
||||
{
|
||||
int i;
|
||||
PCSCHEMA *myschema;
|
||||
PCSCHEMA *clone = pc_schema_clone(schema);
|
||||
hashtable *hash, *chash;
|
||||
char *xmlstr;
|
||||
CU_ASSERT_EQUAL(clone->pcid, schema->pcid);
|
||||
CU_ASSERT_EQUAL(clone->ndims, schema->ndims);
|
||||
CU_ASSERT_EQUAL(clone->size, schema->size);
|
||||
CU_ASSERT_EQUAL(clone->srid, schema->srid);
|
||||
CU_ASSERT_EQUAL(clone->x_position, schema->x_position);
|
||||
CU_ASSERT_EQUAL(clone->y_position, schema->y_position);
|
||||
CU_ASSERT_EQUAL(clone->compression, schema->compression);
|
||||
CU_ASSERT(clone->dims != schema->dims); /* deep clone */
|
||||
CU_ASSERT(clone->namehash != schema->namehash); /* deep clone */
|
||||
hash = schema->namehash;
|
||||
chash = clone->namehash;
|
||||
CU_ASSERT_EQUAL(chash->tablelength, hash->tablelength);
|
||||
CU_ASSERT_EQUAL(chash->entrycount, hash->entrycount);
|
||||
CU_ASSERT_EQUAL(chash->loadlimit, hash->loadlimit);
|
||||
CU_ASSERT_EQUAL(chash->primeindex, hash->primeindex);
|
||||
CU_ASSERT_EQUAL(chash->hashfn, hash->hashfn);
|
||||
CU_ASSERT_EQUAL(chash->eqfn, hash->eqfn);
|
||||
CU_ASSERT(chash->table != hash->table); /* deep clone */
|
||||
for (i=0; i<schema->ndims; ++i) {
|
||||
PCDIMENSION *dim = schema->dims[i];
|
||||
PCDIMENSION *cdim = clone->dims[i];
|
||||
CU_ASSERT(dim != cdim); /* deep clone */
|
||||
CU_ASSERT_STRING_EQUAL(cdim->name, dim->name);
|
||||
CU_ASSERT_STRING_EQUAL(cdim->description, dim->description);
|
||||
CU_ASSERT_EQUAL(cdim->position, dim->position);
|
||||
CU_ASSERT_EQUAL(cdim->size, dim->size);
|
||||
CU_ASSERT_EQUAL(cdim->byteoffset, dim->byteoffset);
|
||||
CU_ASSERT_EQUAL(cdim->interpretation, dim->interpretation);
|
||||
CU_ASSERT_EQUAL(cdim->scale, dim->scale);
|
||||
CU_ASSERT_EQUAL(cdim->offset, dim->offset);
|
||||
CU_ASSERT_EQUAL(cdim->active, dim->active);
|
||||
/* hash table is correctly setup */
|
||||
CU_ASSERT_EQUAL(cdim, hashtable_search(clone->namehash, dim->name) );
|
||||
}
|
||||
int i;
|
||||
PCSCHEMA *myschema;
|
||||
PCSCHEMA *clone = pc_schema_clone(schema);
|
||||
hashtable *hash, *chash;
|
||||
char *xmlstr;
|
||||
CU_ASSERT_EQUAL(clone->pcid, schema->pcid);
|
||||
CU_ASSERT_EQUAL(clone->ndims, schema->ndims);
|
||||
CU_ASSERT_EQUAL(clone->size, schema->size);
|
||||
CU_ASSERT_EQUAL(clone->srid, schema->srid);
|
||||
CU_ASSERT_EQUAL(clone->x_position, schema->x_position);
|
||||
CU_ASSERT_EQUAL(clone->y_position, schema->y_position);
|
||||
CU_ASSERT_EQUAL(clone->compression, schema->compression);
|
||||
CU_ASSERT(clone->dims != schema->dims); /* deep clone */
|
||||
CU_ASSERT(clone->namehash != schema->namehash); /* deep clone */
|
||||
hash = schema->namehash;
|
||||
chash = clone->namehash;
|
||||
CU_ASSERT_EQUAL(chash->tablelength, hash->tablelength);
|
||||
CU_ASSERT_EQUAL(chash->entrycount, hash->entrycount);
|
||||
CU_ASSERT_EQUAL(chash->loadlimit, hash->loadlimit);
|
||||
CU_ASSERT_EQUAL(chash->primeindex, hash->primeindex);
|
||||
CU_ASSERT_EQUAL(chash->hashfn, hash->hashfn);
|
||||
CU_ASSERT_EQUAL(chash->eqfn, hash->eqfn);
|
||||
CU_ASSERT(chash->table != hash->table); /* deep clone */
|
||||
for (i=0; i<schema->ndims; ++i) {
|
||||
PCDIMENSION *dim = schema->dims[i];
|
||||
PCDIMENSION *cdim = clone->dims[i];
|
||||
CU_ASSERT(dim != cdim); /* deep clone */
|
||||
CU_ASSERT_STRING_EQUAL(cdim->name, dim->name);
|
||||
CU_ASSERT_STRING_EQUAL(cdim->description, dim->description);
|
||||
CU_ASSERT_EQUAL(cdim->position, dim->position);
|
||||
CU_ASSERT_EQUAL(cdim->size, dim->size);
|
||||
CU_ASSERT_EQUAL(cdim->byteoffset, dim->byteoffset);
|
||||
CU_ASSERT_EQUAL(cdim->interpretation, dim->interpretation);
|
||||
CU_ASSERT_EQUAL(cdim->scale, dim->scale);
|
||||
CU_ASSERT_EQUAL(cdim->offset, dim->offset);
|
||||
CU_ASSERT_EQUAL(cdim->active, dim->active);
|
||||
/* hash table is correctly setup */
|
||||
CU_ASSERT_EQUAL(cdim, hashtable_search(clone->namehash, dim->name) );
|
||||
}
|
||||
|
||||
pc_schema_free(clone);
|
||||
pc_schema_free(clone);
|
||||
|
||||
/* See https://github.com/pgpointcloud/pointcloud/issues/66 */
|
||||
/* See https://github.com/pgpointcloud/pointcloud/issues/66 */
|
||||
xmlstr = "<pc:PointCloudSchema xmlns:pc='x'><pc:dimension><pc:position>1</pc:position></pc:dimension></pc:PointCloudSchema>";
|
||||
i = pc_schema_from_xml(xmlstr, &myschema);
|
||||
i = pc_schema_from_xml(xmlstr, &myschema);
|
||||
CU_ASSERT_EQUAL(i, PC_SUCCESS);
|
||||
clone = pc_schema_clone(myschema);
|
||||
CU_ASSERT_EQUAL(clone->ndims, myschema->ndims);
|
||||
CU_ASSERT_EQUAL(clone->dims[0]->name, NULL);
|
||||
CU_ASSERT_EQUAL(clone->dims[0]->description, NULL);
|
||||
pc_schema_free(myschema);
|
||||
pc_schema_free(clone);
|
||||
clone = pc_schema_clone(myschema);
|
||||
CU_ASSERT_EQUAL(clone->ndims, myschema->ndims);
|
||||
CU_ASSERT_EQUAL(clone->dims[0]->name, NULL);
|
||||
CU_ASSERT_EQUAL(clone->dims[0]->description, NULL);
|
||||
pc_schema_free(myschema);
|
||||
pc_schema_free(clone);
|
||||
}
|
||||
|
||||
/* REGISTER ***********************************************************/
|
||||
@ -229,8 +229,8 @@ CU_TestInfo schema_tests[] = {
|
||||
};
|
||||
|
||||
CU_SuiteInfo schema_suite = {
|
||||
.pName = "schema",
|
||||
.pInitFunc = init_suite,
|
||||
.pCleanupFunc = clean_suite,
|
||||
.pTests = schema_tests
|
||||
.pName = "schema",
|
||||
.pInitFunc = init_suite,
|
||||
.pCleanupFunc = clean_suite,
|
||||
.pTests = schema_tests
|
||||
};
|
||||
|
||||
@ -24,18 +24,18 @@ static const double precision = 0.000001;
|
||||
static int
|
||||
init_suite(void)
|
||||
{
|
||||
char *xmlstr = file_to_str(xmlfile);
|
||||
int rv = pc_schema_from_xml(xmlstr, &schema);
|
||||
pcfree(xmlstr);
|
||||
if ( rv == PC_FAILURE ) return 1;
|
||||
return 0;
|
||||
char *xmlstr = file_to_str(xmlfile);
|
||||
int rv = pc_schema_from_xml(xmlstr, &schema);
|
||||
pcfree(xmlstr);
|
||||
if ( rv == PC_FAILURE ) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
clean_suite(void)
|
||||
{
|
||||
pc_schema_free(schema);
|
||||
return 0;
|
||||
pc_schema_free(schema);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TESTS **************************************************************/
|
||||
@ -43,353 +43,353 @@ clean_suite(void)
|
||||
static void
|
||||
test_sort_simple()
|
||||
{
|
||||
// 00 endian (big)
|
||||
// 00000000 pcid
|
||||
// 00000000 compression
|
||||
// 00000002 npoints
|
||||
// 0000000800000003000000050006 pt1 (XYZi)
|
||||
// 0000000200000001000000040008 pt2 (XYZi)
|
||||
// 00 endian (big)
|
||||
// 00000000 pcid
|
||||
// 00000000 compression
|
||||
// 00000002 npoints
|
||||
// 0000000800000003000000050006 pt1 (XYZi)
|
||||
// 0000000200000001000000040008 pt2 (XYZi)
|
||||
|
||||
// init data
|
||||
PCPOINTLIST *lisort;
|
||||
PCPATCH *pasort;
|
||||
double d1;
|
||||
double d2;
|
||||
char *hexbuf = "0000000000000000000000000200000008000000030000000500060000000200000001000000040008";
|
||||
size_t hexsize = strlen(hexbuf);
|
||||
// init data
|
||||
PCPOINTLIST *lisort;
|
||||
PCPATCH *pasort;
|
||||
double d1;
|
||||
double d2;
|
||||
char *hexbuf = "0000000000000000000000000200000008000000030000000500060000000200000001000000040008";
|
||||
size_t hexsize = strlen(hexbuf);
|
||||
|
||||
uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize);
|
||||
PCPATCH *pa = pc_patch_from_wkb(schema, wkb, hexsize/2);
|
||||
PCPOINTLIST *li = pc_pointlist_from_patch(pa);
|
||||
const char *X[] = {"X"};
|
||||
uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize);
|
||||
PCPATCH *pa = pc_patch_from_wkb(schema, wkb, hexsize/2);
|
||||
PCPOINTLIST *li = pc_pointlist_from_patch(pa);
|
||||
const char *X[] = {"X"};
|
||||
|
||||
// check that initial data are not sorted
|
||||
pc_point_get_double_by_name(pc_pointlist_get_point(li, 0), "X", &d1);
|
||||
pc_point_get_double_by_name(pc_pointlist_get_point(li, 1), "X", &d2);
|
||||
// check that initial data are not sorted
|
||||
pc_point_get_double_by_name(pc_pointlist_get_point(li, 0), "X", &d1);
|
||||
pc_point_get_double_by_name(pc_pointlist_get_point(li, 1), "X", &d2);
|
||||
|
||||
CU_ASSERT_DOUBLE_EQUAL(d1, 0.08, precision);
|
||||
CU_ASSERT_DOUBLE_EQUAL(d2, 0.02, precision);
|
||||
CU_ASSERT_DOUBLE_EQUAL(d1, 0.08, precision);
|
||||
CU_ASSERT_DOUBLE_EQUAL(d2, 0.02, precision);
|
||||
|
||||
// sort on X attribute and check if data are well sorted
|
||||
pasort = pc_patch_sort(pa, X, 1);
|
||||
lisort = pc_pointlist_from_patch(pasort);
|
||||
// sort on X attribute and check if data are well sorted
|
||||
pasort = pc_patch_sort(pa, X, 1);
|
||||
lisort = pc_pointlist_from_patch(pasort);
|
||||
|
||||
pc_point_get_double_by_name(pc_pointlist_get_point(lisort, 0), "X", &d1);
|
||||
pc_point_get_double_by_name(pc_pointlist_get_point(lisort, 1), "X", &d2);
|
||||
pc_point_get_double_by_name(pc_pointlist_get_point(lisort, 0), "X", &d1);
|
||||
pc_point_get_double_by_name(pc_pointlist_get_point(lisort, 1), "X", &d2);
|
||||
|
||||
CU_ASSERT_DOUBLE_EQUAL(d1, 0.02, precision);
|
||||
CU_ASSERT_DOUBLE_EQUAL(d2, 0.08, precision);
|
||||
CU_ASSERT_DOUBLE_EQUAL(d1, 0.02, precision);
|
||||
CU_ASSERT_DOUBLE_EQUAL(d2, 0.08, precision);
|
||||
|
||||
// free
|
||||
pc_pointlist_free(li);
|
||||
pc_pointlist_free(lisort);
|
||||
pc_patch_free(pa);
|
||||
pc_patch_free(pasort);
|
||||
pcfree(wkb);
|
||||
// free
|
||||
pc_pointlist_free(li);
|
||||
pc_pointlist_free(lisort);
|
||||
pc_patch_free(pa);
|
||||
pc_patch_free(pasort);
|
||||
pcfree(wkb);
|
||||
}
|
||||
|
||||
static void
|
||||
test_sort_consistency()
|
||||
{
|
||||
// 00 endian (big)
|
||||
// 00000000 pcid
|
||||
// 00000000 compression
|
||||
// 00000002 npoints
|
||||
// 0000000800000003000000050006 pt1 (XYZi)
|
||||
// 0000000200000001000000040008 pt2 (XYZi)
|
||||
// 00 endian (big)
|
||||
// 00000000 pcid
|
||||
// 00000000 compression
|
||||
// 00000002 npoints
|
||||
// 0000000800000003000000050006 pt1 (XYZi)
|
||||
// 0000000200000001000000040008 pt2 (XYZi)
|
||||
|
||||
// init data
|
||||
PCPATCH *pasort;
|
||||
char *pastr, *pasortstr;
|
||||
uint8_t *wkbsort;
|
||||
char *hexbuf = "0000000000000000000000000200000008000000030000000500060000000200000001000000040008";
|
||||
size_t hexsize = strlen(hexbuf);
|
||||
uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize);
|
||||
PCPATCH *pa = pc_patch_from_wkb(schema, wkb, hexsize/2);
|
||||
PCPOINTLIST *li = pc_pointlist_from_patch(pa);
|
||||
const char *X[] = {"X"};
|
||||
// init data
|
||||
PCPATCH *pasort;
|
||||
char *pastr, *pasortstr;
|
||||
uint8_t *wkbsort;
|
||||
char *hexbuf = "0000000000000000000000000200000008000000030000000500060000000200000001000000040008";
|
||||
size_t hexsize = strlen(hexbuf);
|
||||
uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize);
|
||||
PCPATCH *pa = pc_patch_from_wkb(schema, wkb, hexsize/2);
|
||||
PCPOINTLIST *li = pc_pointlist_from_patch(pa);
|
||||
const char *X[] = {"X"};
|
||||
|
||||
// sort on X attribute
|
||||
pasort = pc_patch_sort(pa, X, 1);
|
||||
// sort on X attribute
|
||||
pasort = pc_patch_sort(pa, X, 1);
|
||||
|
||||
//chek consistency
|
||||
wkbsort = pc_patch_to_wkb(pasort, &hexsize);
|
||||
CU_ASSERT_EQUAL(wkb_get_pcid(wkb), wkb_get_pcid(wkbsort));
|
||||
CU_ASSERT_EQUAL(wkb_get_npoints(wkb), wkb_get_npoints(wkbsort));
|
||||
CU_ASSERT_EQUAL(wkb_get_compression(wkb), wkb_get_compression(wkbsort));
|
||||
//chek consistency
|
||||
wkbsort = pc_patch_to_wkb(pasort, &hexsize);
|
||||
CU_ASSERT_EQUAL(wkb_get_pcid(wkb), wkb_get_pcid(wkbsort));
|
||||
CU_ASSERT_EQUAL(wkb_get_npoints(wkb), wkb_get_npoints(wkbsort));
|
||||
CU_ASSERT_EQUAL(wkb_get_compression(wkb), wkb_get_compression(wkbsort));
|
||||
|
||||
pastr = pc_patch_to_string(pa);
|
||||
CU_ASSERT_STRING_EQUAL(pastr, "{\"pcid\":0,\"pts\":[[0.08,0.03,0.05,6],[0.02,0.01,0.04,8]]}");
|
||||
pastr = pc_patch_to_string(pa);
|
||||
CU_ASSERT_STRING_EQUAL(pastr, "{\"pcid\":0,\"pts\":[[0.08,0.03,0.05,6],[0.02,0.01,0.04,8]]}");
|
||||
|
||||
pasortstr = pc_patch_to_string(pasort);
|
||||
CU_ASSERT_STRING_EQUAL(pasortstr, "{\"pcid\":0,\"pts\":[[0.02,0.01,0.04,8],[0.08,0.03,0.05,6]]}");
|
||||
pasortstr = pc_patch_to_string(pasort);
|
||||
CU_ASSERT_STRING_EQUAL(pasortstr, "{\"pcid\":0,\"pts\":[[0.02,0.01,0.04,8],[0.08,0.03,0.05,6]]}");
|
||||
|
||||
// free
|
||||
pcfree(wkb);
|
||||
pcfree(wkbsort);
|
||||
pcfree(pastr);
|
||||
pcfree(pasortstr);
|
||||
pc_patch_free(pasort);
|
||||
pc_patch_free(pa);
|
||||
pc_pointlist_free(li);
|
||||
// free
|
||||
pcfree(wkb);
|
||||
pcfree(wkbsort);
|
||||
pcfree(pastr);
|
||||
pcfree(pasortstr);
|
||||
pc_patch_free(pasort);
|
||||
pc_patch_free(pa);
|
||||
pc_pointlist_free(li);
|
||||
}
|
||||
|
||||
static void
|
||||
test_sort_one_point()
|
||||
{
|
||||
// 00 endian (big)
|
||||
// 00000000 pcid
|
||||
// 00000000 compression
|
||||
// 00000001 npoints
|
||||
// 0000000200000003000000050006 pt1 (XYZi)
|
||||
// 00 endian (big)
|
||||
// 00000000 pcid
|
||||
// 00000000 compression
|
||||
// 00000001 npoints
|
||||
// 0000000200000003000000050006 pt1 (XYZi)
|
||||
|
||||
// init data
|
||||
PCPATCH *pasort;
|
||||
char *pastr, *pasortstr;
|
||||
uint8_t *wkbsort;
|
||||
char *hexbuf = "000000000000000000000000010000000200000003000000050006";
|
||||
size_t hexsize = strlen(hexbuf);
|
||||
uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize);
|
||||
PCPATCH *pa = pc_patch_from_wkb(schema, wkb, hexsize/2);
|
||||
PCPOINTLIST *li = pc_pointlist_from_patch(pa);
|
||||
const char *X[] = {"X"};
|
||||
// init data
|
||||
PCPATCH *pasort;
|
||||
char *pastr, *pasortstr;
|
||||
uint8_t *wkbsort;
|
||||
char *hexbuf = "000000000000000000000000010000000200000003000000050006";
|
||||
size_t hexsize = strlen(hexbuf);
|
||||
uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize);
|
||||
PCPATCH *pa = pc_patch_from_wkb(schema, wkb, hexsize/2);
|
||||
PCPOINTLIST *li = pc_pointlist_from_patch(pa);
|
||||
const char *X[] = {"X"};
|
||||
|
||||
// sort on X attribute
|
||||
pasort = pc_patch_sort(pa, X, 1);
|
||||
// sort on X attribute
|
||||
pasort = pc_patch_sort(pa, X, 1);
|
||||
|
||||
// check consistency
|
||||
wkbsort = pc_patch_to_wkb(pasort, &hexsize);
|
||||
CU_ASSERT_EQUAL(wkb_get_pcid(wkb), wkb_get_pcid(wkbsort));
|
||||
CU_ASSERT_EQUAL(wkb_get_npoints(wkb), wkb_get_npoints(wkbsort));
|
||||
CU_ASSERT_EQUAL(wkb_get_compression(wkb), wkb_get_compression(wkbsort));
|
||||
// check consistency
|
||||
wkbsort = pc_patch_to_wkb(pasort, &hexsize);
|
||||
CU_ASSERT_EQUAL(wkb_get_pcid(wkb), wkb_get_pcid(wkbsort));
|
||||
CU_ASSERT_EQUAL(wkb_get_npoints(wkb), wkb_get_npoints(wkbsort));
|
||||
CU_ASSERT_EQUAL(wkb_get_compression(wkb), wkb_get_compression(wkbsort));
|
||||
|
||||
pastr = pc_patch_to_string(pa);
|
||||
pasortstr = pc_patch_to_string(pasort);
|
||||
CU_ASSERT_STRING_EQUAL(pastr, pasortstr);
|
||||
pastr = pc_patch_to_string(pa);
|
||||
pasortstr = pc_patch_to_string(pasort);
|
||||
CU_ASSERT_STRING_EQUAL(pastr, pasortstr);
|
||||
|
||||
// free
|
||||
pcfree(wkb);
|
||||
pcfree(wkbsort);
|
||||
pcfree(pastr);
|
||||
pcfree(pasortstr);
|
||||
pc_patch_free(pa);
|
||||
pc_patch_free(pasort);
|
||||
pc_pointlist_free(li);
|
||||
// free
|
||||
pcfree(wkb);
|
||||
pcfree(wkbsort);
|
||||
pcfree(pastr);
|
||||
pcfree(pasortstr);
|
||||
pc_patch_free(pa);
|
||||
pc_patch_free(pasort);
|
||||
pc_pointlist_free(li);
|
||||
}
|
||||
|
||||
static void
|
||||
test_sort_stable()
|
||||
{
|
||||
// 00 endian (big)
|
||||
// 00000000 pcid
|
||||
// 00000000 compression
|
||||
// 00000002 npoints
|
||||
// 0000000800000003000000050006 pt1 (XYZi)
|
||||
// 0000000200000003000000040008 pt2 (XYZi)
|
||||
// 0000000200000003000000040009 pt3 (XYZi)
|
||||
// 00 endian (big)
|
||||
// 00000000 pcid
|
||||
// 00000000 compression
|
||||
// 00000002 npoints
|
||||
// 0000000800000003000000050006 pt1 (XYZi)
|
||||
// 0000000200000003000000040008 pt2 (XYZi)
|
||||
// 0000000200000003000000040009 pt3 (XYZi)
|
||||
|
||||
// init data
|
||||
PCPATCH *pasort;
|
||||
char *hexbuf = "00000000000000000000000003000000080000000300000005000600000002000000030000000400080000000200000003000000040009";
|
||||
size_t hexsize = strlen(hexbuf);
|
||||
uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize);
|
||||
PCPATCH *pa = pc_patch_from_wkb(schema, wkb, hexsize/2);
|
||||
PCPOINTLIST *li = pc_pointlist_from_patch(pa);
|
||||
const char *dims[] = {"Y"};
|
||||
// init data
|
||||
PCPATCH *pasort;
|
||||
char *hexbuf = "00000000000000000000000003000000080000000300000005000600000002000000030000000400080000000200000003000000040009";
|
||||
size_t hexsize = strlen(hexbuf);
|
||||
uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize);
|
||||
PCPATCH *pa = pc_patch_from_wkb(schema, wkb, hexsize/2);
|
||||
PCPOINTLIST *li = pc_pointlist_from_patch(pa);
|
||||
const char *dims[] = {"Y"};
|
||||
|
||||
// sort on Y attribute
|
||||
pasort = pc_patch_sort(pa, dims, 1);
|
||||
// sort on Y attribute
|
||||
pasort = pc_patch_sort(pa, dims, 1);
|
||||
|
||||
// check that sort is stable
|
||||
char *pastr = pc_patch_to_string(pa);
|
||||
char *pasortstr = pc_patch_to_string(pasort);
|
||||
CU_ASSERT_STRING_EQUAL(pastr, pasortstr);
|
||||
// check that sort is stable
|
||||
char *pastr = pc_patch_to_string(pa);
|
||||
char *pasortstr = pc_patch_to_string(pasort);
|
||||
CU_ASSERT_STRING_EQUAL(pastr, pasortstr);
|
||||
|
||||
// free
|
||||
free(pastr);
|
||||
free(pasortstr);
|
||||
pcfree(wkb);
|
||||
pc_patch_free(pa);
|
||||
pc_patch_free(pasort);
|
||||
pc_pointlist_free(li);
|
||||
// free
|
||||
free(pastr);
|
||||
free(pasortstr);
|
||||
pcfree(wkb);
|
||||
pc_patch_free(pa);
|
||||
pc_patch_free(pasort);
|
||||
pc_pointlist_free(li);
|
||||
}
|
||||
|
||||
static void
|
||||
test_sort_patch_is_sorted_no_compression()
|
||||
{
|
||||
// 00 endian (big)
|
||||
// 00000000 pcid
|
||||
// 00000000 compression
|
||||
// 00000002 npoints
|
||||
// 0000000800000003000000050006 pt1 (XYZi)
|
||||
// 0000000200000003000000040008 pt2 (XYZi)
|
||||
// 0000000200000003000000040009 pt3 (XYZi)
|
||||
// 00 endian (big)
|
||||
// 00000000 pcid
|
||||
// 00000000 compression
|
||||
// 00000002 npoints
|
||||
// 0000000800000003000000050006 pt1 (XYZi)
|
||||
// 0000000200000003000000040008 pt2 (XYZi)
|
||||
// 0000000200000003000000040009 pt3 (XYZi)
|
||||
|
||||
// init data
|
||||
PCPATCH *pasort;
|
||||
char *hexbuf = "00000000000000000000000003000000080000000300000005000600000002000000030000000400080000000200000003000000040009";
|
||||
size_t hexsize = strlen(hexbuf);
|
||||
uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize);
|
||||
PCPATCH *pa = pc_patch_from_wkb(schema, wkb, hexsize/2);
|
||||
PCPOINTLIST *li = pc_pointlist_from_patch(pa);
|
||||
const char *X[] = {"X"};
|
||||
// init data
|
||||
PCPATCH *pasort;
|
||||
char *hexbuf = "00000000000000000000000003000000080000000300000005000600000002000000030000000400080000000200000003000000040009";
|
||||
size_t hexsize = strlen(hexbuf);
|
||||
uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize);
|
||||
PCPATCH *pa = pc_patch_from_wkb(schema, wkb, hexsize/2);
|
||||
PCPOINTLIST *li = pc_pointlist_from_patch(pa);
|
||||
const char *X[] = {"X"};
|
||||
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pa, X, 1, PC_FALSE), PC_FALSE);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pa, X, 1, PC_TRUE), PC_FALSE);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pa, X, 1, PC_FALSE), PC_FALSE);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pa, X, 1, PC_TRUE), PC_FALSE);
|
||||
|
||||
pasort = pc_patch_sort(pa, X, 1);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort, X, 1, PC_FALSE), PC_FALSE);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort, X, 1, PC_TRUE), PC_TRUE);
|
||||
pasort = pc_patch_sort(pa, X, 1);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort, X, 1, PC_FALSE), PC_FALSE);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort, X, 1, PC_TRUE), PC_TRUE);
|
||||
|
||||
// free
|
||||
pcfree(wkb);
|
||||
pc_patch_free(pa);
|
||||
pc_patch_free(pasort);
|
||||
pc_pointlist_free(li);
|
||||
// free
|
||||
pcfree(wkb);
|
||||
pc_patch_free(pa);
|
||||
pc_patch_free(pasort);
|
||||
pc_pointlist_free(li);
|
||||
}
|
||||
|
||||
static void
|
||||
test_sort_patch_is_sorted_compression_dimensional(enum DIMCOMPRESSIONS dimcomp)
|
||||
{
|
||||
// init data
|
||||
PCPATCH_DIMENSIONAL *padim1, *padim2, *padimsort;
|
||||
PCPOINT *pt;
|
||||
PCPOINTLIST *pl;
|
||||
int i;
|
||||
int ndims = 1;
|
||||
int npts = PCDIMSTATS_MIN_SAMPLE+1; // force to keep custom compression
|
||||
const char *X[] = {"X"};
|
||||
// init data
|
||||
PCPATCH_DIMENSIONAL *padim1, *padim2, *padimsort;
|
||||
PCPOINT *pt;
|
||||
PCPOINTLIST *pl;
|
||||
int i;
|
||||
int ndims = 1;
|
||||
int npts = PCDIMSTATS_MIN_SAMPLE+1; // force to keep custom compression
|
||||
const char *X[] = {"X"};
|
||||
|
||||
// build a dimensional patch
|
||||
pl = pc_pointlist_make(npts);
|
||||
// build a dimensional patch
|
||||
pl = pc_pointlist_make(npts);
|
||||
|
||||
for ( i = npts; i >= 0; i-- )
|
||||
{
|
||||
pt = pc_point_make(schema);
|
||||
pc_point_set_double_by_name(pt, "x", i);
|
||||
pc_point_set_double_by_name(pt, "y", i);
|
||||
pc_point_set_double_by_name(pt, "Z", i);
|
||||
pc_point_set_double_by_name(pt, "intensity", 10);
|
||||
pc_pointlist_add_point(pl, pt);
|
||||
}
|
||||
for ( i = npts; i >= 0; i-- )
|
||||
{
|
||||
pt = pc_point_make(schema);
|
||||
pc_point_set_double_by_name(pt, "x", i);
|
||||
pc_point_set_double_by_name(pt, "y", i);
|
||||
pc_point_set_double_by_name(pt, "Z", i);
|
||||
pc_point_set_double_by_name(pt, "intensity", 10);
|
||||
pc_pointlist_add_point(pl, pt);
|
||||
}
|
||||
|
||||
padim1 = pc_patch_dimensional_from_pointlist(pl);
|
||||
padim1 = pc_patch_dimensional_from_pointlist(pl);
|
||||
|
||||
// set dimensional compression for each dimension
|
||||
PCDIMSTATS *stats = pc_dimstats_make(schema);
|
||||
pc_dimstats_update(stats, padim1);
|
||||
for ( i = 0; i<padim1->schema->ndims; i++ )
|
||||
stats->stats[i].recommended_compression = dimcomp;
|
||||
// set dimensional compression for each dimension
|
||||
PCDIMSTATS *stats = pc_dimstats_make(schema);
|
||||
pc_dimstats_update(stats, padim1);
|
||||
for ( i = 0; i<padim1->schema->ndims; i++ )
|
||||
stats->stats[i].recommended_compression = dimcomp;
|
||||
|
||||
// compress patch
|
||||
padim2 = pc_patch_dimensional_compress(padim1, stats);
|
||||
// compress patch
|
||||
padim2 = pc_patch_dimensional_compress(padim1, stats);
|
||||
|
||||
// test that patch is not sorted
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted((PCPATCH*) padim2, X, ndims, PC_FALSE), PC_FALSE);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted((PCPATCH*) padim2, X, ndims, PC_TRUE), PC_FALSE);
|
||||
// test that patch is not sorted
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted((PCPATCH*) padim2, X, ndims, PC_FALSE), PC_FALSE);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted((PCPATCH*) padim2, X, ndims, PC_TRUE), PC_FALSE);
|
||||
|
||||
// sort
|
||||
padimsort = (PCPATCH_DIMENSIONAL*) pc_patch_sort((PCPATCH*) padim2, X, 1);
|
||||
// sort
|
||||
padimsort = (PCPATCH_DIMENSIONAL*) pc_patch_sort((PCPATCH*) padim2, X, 1);
|
||||
|
||||
// test that resulting data is sorted
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted((PCPATCH*) padimsort, X, ndims, PC_TRUE), PC_TRUE);
|
||||
// test that resulting data is sorted
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted((PCPATCH*) padimsort, X, ndims, PC_TRUE), PC_TRUE);
|
||||
|
||||
// free
|
||||
pc_dimstats_free(stats);
|
||||
pc_patch_free((PCPATCH *)padim1);
|
||||
pc_patch_free((PCPATCH *)padim2);
|
||||
pc_patch_free((PCPATCH *)padimsort);
|
||||
pc_pointlist_free(pl);
|
||||
// free
|
||||
pc_dimstats_free(stats);
|
||||
pc_patch_free((PCPATCH *)padim1);
|
||||
pc_patch_free((PCPATCH *)padim2);
|
||||
pc_patch_free((PCPATCH *)padimsort);
|
||||
pc_pointlist_free(pl);
|
||||
}
|
||||
|
||||
static void
|
||||
test_sort_patch_is_sorted_compression_dimensional_none()
|
||||
{
|
||||
test_sort_patch_is_sorted_compression_dimensional(PC_DIM_NONE);
|
||||
test_sort_patch_is_sorted_compression_dimensional(PC_DIM_NONE);
|
||||
}
|
||||
|
||||
static void
|
||||
test_sort_patch_is_sorted_compression_dimensional_zlib()
|
||||
{
|
||||
test_sort_patch_is_sorted_compression_dimensional(PC_DIM_ZLIB);
|
||||
test_sort_patch_is_sorted_compression_dimensional(PC_DIM_ZLIB);
|
||||
}
|
||||
|
||||
static void
|
||||
test_sort_patch_is_sorted_compression_dimensional_rle()
|
||||
{
|
||||
test_sort_patch_is_sorted_compression_dimensional(PC_DIM_RLE);
|
||||
test_sort_patch_is_sorted_compression_dimensional(PC_DIM_RLE);
|
||||
}
|
||||
|
||||
static void
|
||||
test_sort_patch_is_sorted_compression_dimensional_sigbits()
|
||||
{
|
||||
test_sort_patch_is_sorted_compression_dimensional(PC_DIM_SIGBITS);
|
||||
test_sort_patch_is_sorted_compression_dimensional(PC_DIM_SIGBITS);
|
||||
}
|
||||
|
||||
static void
|
||||
test_sort_patch_ndims()
|
||||
{
|
||||
// 00 endian (big)
|
||||
// 00000000 pcid
|
||||
// 00000000 compression
|
||||
// 00000002 npoints
|
||||
// 0000000800000001000000050006 pt1 (XYZi)
|
||||
// 0000000200000003000000040008 pt2 (XYZi)
|
||||
// 0000000200000002000000040008 pt2 (XYZi)
|
||||
// 00 endian (big)
|
||||
// 00000000 pcid
|
||||
// 00000000 compression
|
||||
// 00000002 npoints
|
||||
// 0000000800000001000000050006 pt1 (XYZi)
|
||||
// 0000000200000003000000040008 pt2 (XYZi)
|
||||
// 0000000200000002000000040008 pt2 (XYZi)
|
||||
|
||||
// init data
|
||||
PCPATCH *pasort1, *pasort2;
|
||||
char *hexbuf = "00000000000000000000000003000000080000000400000005000600000002000000030000000400080000000200000002000000040009";
|
||||
size_t hexsize = strlen(hexbuf);
|
||||
uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize);
|
||||
PCPATCH *pa = pc_patch_from_wkb(schema, wkb, hexsize/2);
|
||||
const char *X[] = {"X"};
|
||||
const char *Y[] = {"Y"};
|
||||
const char *X_Y[] = {"X", "Y"};
|
||||
// init data
|
||||
PCPATCH *pasort1, *pasort2;
|
||||
char *hexbuf = "00000000000000000000000003000000080000000400000005000600000002000000030000000400080000000200000002000000040009";
|
||||
size_t hexsize = strlen(hexbuf);
|
||||
uint8_t *wkb = bytes_from_hexbytes(hexbuf, hexsize);
|
||||
PCPATCH *pa = pc_patch_from_wkb(schema, wkb, hexsize/2);
|
||||
const char *X[] = {"X"};
|
||||
const char *Y[] = {"Y"};
|
||||
const char *X_Y[] = {"X", "Y"};
|
||||
|
||||
// test that initial data is not sorted
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pa, X, 1, PC_FALSE), PC_FALSE);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pa, Y, 1, PC_FALSE), PC_FALSE);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pa, X_Y, 2, PC_FALSE), PC_FALSE);
|
||||
// test that initial data is not sorted
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pa, X, 1, PC_FALSE), PC_FALSE);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pa, Y, 1, PC_FALSE), PC_FALSE);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pa, X_Y, 2, PC_FALSE), PC_FALSE);
|
||||
|
||||
// sort on X attribute and test
|
||||
pasort1 = pc_patch_sort(pa, X, 1);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort1, X, 1, PC_TRUE), PC_TRUE);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort1, Y, 1, PC_TRUE), PC_FALSE);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort1, X_Y, 2, PC_TRUE), PC_FALSE);
|
||||
// sort on X attribute and test
|
||||
pasort1 = pc_patch_sort(pa, X, 1);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort1, X, 1, PC_TRUE), PC_TRUE);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort1, Y, 1, PC_TRUE), PC_FALSE);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort1, X_Y, 2, PC_TRUE), PC_FALSE);
|
||||
|
||||
// sort on X and Y and tst
|
||||
pasort2 = pc_patch_sort(pa, X_Y, 2);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort2, X, 1, PC_TRUE), PC_TRUE);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort2, Y, 1, PC_TRUE), PC_TRUE);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort2, X_Y, 2, PC_TRUE), PC_TRUE);
|
||||
// sort on X and Y and tst
|
||||
pasort2 = pc_patch_sort(pa, X_Y, 2);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort2, X, 1, PC_TRUE), PC_TRUE);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort2, Y, 1, PC_TRUE), PC_TRUE);
|
||||
CU_ASSERT_EQUAL(pc_patch_is_sorted(pasort2, X_Y, 2, PC_TRUE), PC_TRUE);
|
||||
|
||||
// free
|
||||
pcfree(wkb);
|
||||
pc_patch_free(pasort1);
|
||||
pc_patch_free(pasort2);
|
||||
pc_patch_free(pa);
|
||||
// free
|
||||
pcfree(wkb);
|
||||
pc_patch_free(pasort1);
|
||||
pc_patch_free(pasort2);
|
||||
pc_patch_free(pa);
|
||||
}
|
||||
|
||||
/* REGISTER ***********************************************************/
|
||||
|
||||
CU_TestInfo sort_tests[] = {
|
||||
PC_TEST(test_sort_simple),
|
||||
PC_TEST(test_sort_consistency),
|
||||
PC_TEST(test_sort_one_point),
|
||||
PC_TEST(test_sort_stable),
|
||||
PC_TEST(test_sort_patch_is_sorted_no_compression),
|
||||
PC_TEST(test_sort_patch_is_sorted_compression_dimensional_none),
|
||||
PC_TEST(test_sort_patch_is_sorted_compression_dimensional_zlib),
|
||||
PC_TEST(test_sort_patch_is_sorted_compression_dimensional_sigbits),
|
||||
PC_TEST(test_sort_patch_is_sorted_compression_dimensional_rle),
|
||||
PC_TEST(test_sort_patch_ndims),
|
||||
CU_TEST_INFO_NULL
|
||||
PC_TEST(test_sort_simple),
|
||||
PC_TEST(test_sort_consistency),
|
||||
PC_TEST(test_sort_one_point),
|
||||
PC_TEST(test_sort_stable),
|
||||
PC_TEST(test_sort_patch_is_sorted_no_compression),
|
||||
PC_TEST(test_sort_patch_is_sorted_compression_dimensional_none),
|
||||
PC_TEST(test_sort_patch_is_sorted_compression_dimensional_zlib),
|
||||
PC_TEST(test_sort_patch_is_sorted_compression_dimensional_sigbits),
|
||||
PC_TEST(test_sort_patch_is_sorted_compression_dimensional_rle),
|
||||
PC_TEST(test_sort_patch_ndims),
|
||||
CU_TEST_INFO_NULL
|
||||
};
|
||||
|
||||
CU_SuiteInfo sort_suite = {
|
||||
.pName = "sort",
|
||||
.pInitFunc = init_suite,
|
||||
.pCleanupFunc = clean_suite,
|
||||
.pTests = sort_tests
|
||||
.pName = "sort",
|
||||
.pInitFunc = init_suite,
|
||||
.pCleanupFunc = clean_suite,
|
||||
.pTests = sort_tests
|
||||
};
|
||||
|
||||
@ -22,16 +22,16 @@ extern CU_SuiteInfo lazperf_suite;
|
||||
extern CU_SuiteInfo sort_suite;
|
||||
|
||||
/**
|
||||
* CUnit error handler
|
||||
* Log message in a global var instead of printing in stderr
|
||||
*
|
||||
* CAUTION: Not stop execution on pcerror case !!!
|
||||
* CUnit error handler
|
||||
* Log message in a global var instead of printing in stderr
|
||||
*
|
||||
* CAUTION: Not stop execution on pcerror case !!!
|
||||
*/
|
||||
static void cu_error_reporter(const char *fmt, va_list ap)
|
||||
{
|
||||
vsnprintf(cu_error_msg, MAX_CUNIT_MSG_LENGTH-1, fmt, ap);
|
||||
cu_error_msg[MAX_CUNIT_MSG_LENGTH-1] = '\0';
|
||||
va_end (ap);
|
||||
vsnprintf(cu_error_msg, MAX_CUNIT_MSG_LENGTH-1, fmt, ap);
|
||||
cu_error_msg[MAX_CUNIT_MSG_LENGTH-1] = '\0';
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
void cu_error_msg_reset() {
|
||||
@ -52,8 +52,8 @@ int main(int argc, char *argv[])
|
||||
schema_suite,
|
||||
patch_suite,
|
||||
point_suite,
|
||||
ght_suite,
|
||||
bytes_suite,
|
||||
ght_suite,
|
||||
bytes_suite,
|
||||
lazperf_suite,
|
||||
sort_suite,
|
||||
CU_SUITE_INFO_NULL
|
||||
@ -72,7 +72,7 @@ int main(int argc, char *argv[])
|
||||
/* Set up to use the system memory management / logging */
|
||||
pc_install_default_handlers();
|
||||
|
||||
pc_set_handlers(0, 0, 0, cu_error_reporter, 0, 0);
|
||||
pc_set_handlers(0, 0, 0, cu_error_reporter, 0, 0);
|
||||
|
||||
/* initialize the CUnit test registry */
|
||||
if (CUE_SUCCESS != CU_initialize_registry())
|
||||
@ -147,7 +147,7 @@ int main(int argc, char *argv[])
|
||||
num_run = CU_get_number_of_asserts();
|
||||
num_failed = CU_get_number_of_failures();
|
||||
printf("\n %s - asserts - %3d passed, %3d failed, %3d total.\n\n",
|
||||
(0 == num_failed ? "PASSED" : "FAILED"), (num_run - num_failed), num_failed, num_run);
|
||||
(0 == num_failed ? "PASSED" : "FAILED"), (num_run - num_failed), num_failed, num_run);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -167,11 +167,11 @@ int main(int argc, char *argv[])
|
||||
num_run = CU_get_number_of_tests_run();
|
||||
num_failed = CU_get_number_of_tests_failed();
|
||||
printf("\n %s - tests - %3d passed, %3d failed, %3d total.\n",
|
||||
(0 == num_failed ? "PASSED" : "FAILED"), (num_run - num_failed), num_failed, num_run);
|
||||
(0 == num_failed ? "PASSED" : "FAILED"), (num_run - num_failed), num_failed, num_run);
|
||||
num_run = CU_get_number_of_asserts();
|
||||
num_failed = CU_get_number_of_failures();
|
||||
printf(" - asserts - %3d passed, %3d failed, %3d total.\n\n",
|
||||
(num_run - num_failed), num_failed, num_run);
|
||||
(num_run - num_failed), num_failed, num_run);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -202,7 +202,7 @@ file_to_str(const char *fname)
|
||||
snprintf(fullpath, 512, "%s/lib/cunit/%s", PROJECT_SOURCE_DIR, fname);
|
||||
fr = fopen (fullpath, "rt");
|
||||
|
||||
while (fr && fgets(buf, MAXLINELEN, fr) != NULL)
|
||||
while (fr && fgets(buf, MAXLINELEN, fr) != NULL)
|
||||
{
|
||||
if (buf[0] == '\0')
|
||||
continue;
|
||||
@ -217,8 +217,8 @@ file_to_str(const char *fname)
|
||||
memcpy(ptr, buf, lnsz);
|
||||
ptr += lnsz;
|
||||
}
|
||||
|
||||
*ptr = '\0';
|
||||
|
||||
*ptr = '\0';
|
||||
fclose(fr);
|
||||
|
||||
return str;
|
||||
|
||||
@ -16,9 +16,9 @@
|
||||
|
||||
|
||||
/*
|
||||
Credit for primes table: Aaron Krowne
|
||||
http://br.endernet.org/~akrowne/
|
||||
http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
|
||||
* Credit for primes table: Aaron Krowne
|
||||
* http://br.endernet.org/~akrowne/
|
||||
* http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
|
||||
*/
|
||||
static const unsigned int primes[] =
|
||||
{
|
||||
@ -68,9 +68,10 @@ create_string_hashtable()
|
||||
|
||||
/*****************************************************************************/
|
||||
hashtable *
|
||||
create_hashtable(unsigned int minsize,
|
||||
unsigned int (*hashf) (const void*),
|
||||
int (*eqf) (const void*,const void*))
|
||||
create_hashtable(
|
||||
unsigned int minsize,
|
||||
unsigned int (*hashf) (const void*),
|
||||
int (*eqf) (const void*,const void*))
|
||||
{
|
||||
hashtable *h;
|
||||
unsigned int pindex, size = primes[0];
|
||||
@ -153,7 +154,7 @@ hashtable_expand(hashtable *h)
|
||||
else
|
||||
{
|
||||
newtable = (struct entry **)
|
||||
realloc(h->table, newsize * sizeof(struct entry *));
|
||||
realloc(h->table, newsize * sizeof(struct entry *));
|
||||
if (NULL == newtable)
|
||||
{
|
||||
(h->primeindex)--;
|
||||
@ -316,34 +317,34 @@ hashtable_destroy(hashtable *h, int free_values)
|
||||
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002, Christopher Clark
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* Copyright (c) 2002, Christopher Clark
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
275
lib/hashtable.h
275
lib/hashtable.h
@ -28,104 +28,105 @@ unsigned int
|
||||
hash(hashtable *h, const void *k);
|
||||
|
||||
/* Example of use:
|
||||
*
|
||||
* hashtable *h;
|
||||
* struct some_key *k;
|
||||
* struct some_value *v;
|
||||
*
|
||||
* static unsigned int hash_from_key_fn( void *k );
|
||||
* static int keys_equal_fn ( void *key1, void *key2 );
|
||||
*
|
||||
* h = create_hashtable(16, hash_from_key_fn, keys_equal_fn);
|
||||
* k = (struct some_key *) malloc(sizeof(struct some_key));
|
||||
* v = (struct some_value *) malloc(sizeof(struct some_value));
|
||||
*
|
||||
* (initialise k and v to suitable values)
|
||||
*
|
||||
* if (! hashtable_insert(h,k,v) )
|
||||
* { exit(-1); }
|
||||
*
|
||||
* if (NULL == (found = hashtable_search(h,k) ))
|
||||
* { printf("not found!"); }
|
||||
*
|
||||
* if (NULL == (found = hashtable_remove(h,k) ))
|
||||
* { printf("Not found\n"); }
|
||||
*
|
||||
*/
|
||||
*
|
||||
* hashtable *h;
|
||||
* struct some_key *k;
|
||||
* struct some_value *v;
|
||||
*
|
||||
* static unsigned int hash_from_key_fn( void *k );
|
||||
* static int keys_equal_fn ( void *key1, void *key2 );
|
||||
*
|
||||
* h = create_hashtable(16, hash_from_key_fn, keys_equal_fn);
|
||||
* k = (struct some_key *) malloc(sizeof(struct some_key));
|
||||
* v = (struct some_value *) malloc(sizeof(struct some_value));
|
||||
*
|
||||
* (initialise k and v to suitable values)
|
||||
*
|
||||
* if (! hashtable_insert(h,k,v) )
|
||||
* { exit(-1); }
|
||||
*
|
||||
* if (NULL == (found = hashtable_search(h,k) ))
|
||||
* { printf("not found!"); }
|
||||
*
|
||||
* if (NULL == (found = hashtable_remove(h,k) ))
|
||||
* { printf("Not found\n"); }
|
||||
*
|
||||
*/
|
||||
|
||||
/* Macros may be used to define type-safe(r) hashtable access functions, with
|
||||
* methods specialized to take known key and value types as parameters.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* Insert this at the start of your file:
|
||||
*
|
||||
* DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value);
|
||||
* DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value);
|
||||
* DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value);
|
||||
*
|
||||
* This defines the functions 'insert_some', 'search_some' and 'remove_some'.
|
||||
* These operate just like hashtable_insert etc., with the same parameters,
|
||||
* but their function signatures have 'struct some_key *' rather than
|
||||
* 'void *', and hence can generate compile time errors if your program is
|
||||
* supplying incorrect data as a key (and similarly for value).
|
||||
*
|
||||
* Note that the hash and key equality functions passed to create_hashtable
|
||||
* still take 'void *' parameters instead of 'some key *'. This shouldn't be
|
||||
* a difficult issue as they're only defined and passed once, and the other
|
||||
* functions will ensure that only valid keys are supplied to them.
|
||||
*
|
||||
* The cost for this checking is increased code size and runtime overhead
|
||||
* - if performance is important, it may be worth switching back to the
|
||||
* unsafe methods once your program has been debugged with the safe methods.
|
||||
* This just requires switching to some simple alternative defines - eg:
|
||||
* #define insert_some hashtable_insert
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Macros may be used to define type-safe(r) hashtable access functions, with
|
||||
* methods specialized to take known key and value types as parameters.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* Insert this at the start of your file:
|
||||
*
|
||||
* DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value);
|
||||
* DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value);
|
||||
* DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value);
|
||||
*
|
||||
* This defines the functions 'insert_some', 'search_some' and 'remove_some'.
|
||||
* These operate just like hashtable_insert etc., with the same parameters,
|
||||
* but their function signatures have 'struct some_key *' rather than
|
||||
* 'void *', and hence can generate compile time errors if your program is
|
||||
* supplying incorrect data as a key (and similarly for value).
|
||||
*
|
||||
* Note that the hash and key equality functions passed to create_hashtable
|
||||
* still take 'void *' parameters instead of 'some key *'. This shouldn't be
|
||||
* a difficult issue as they're only defined and passed once, and the other
|
||||
* functions will ensure that only valid keys are supplied to them.
|
||||
*
|
||||
* The cost for this checking is increased code size and runtime overhead
|
||||
* - if performance is important, it may be worth switching back to the
|
||||
* unsafe methods once your program has been debugged with the safe methods.
|
||||
* This just requires switching to some simple alternative defines - eg:
|
||||
* #define insert_some hashtable_insert
|
||||
*
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* create_hashtable
|
||||
* create_hashtable
|
||||
|
||||
* @name create_hashtable
|
||||
* @param minsize minimum initial size of hashtable
|
||||
* @param hashfunction function for hashing keys
|
||||
* @param key_eq_fn function for determining key equality
|
||||
* @return newly created hashtable or NULL on failure
|
||||
*/
|
||||
* @name create_hashtable
|
||||
* @param minsize minimum initial size of hashtable
|
||||
* @param hashfunction function for hashing keys
|
||||
* @param key_eq_fn function for determining key equality
|
||||
* @return newly created hashtable or NULL on failure
|
||||
*/
|
||||
|
||||
hashtable *
|
||||
create_hashtable(unsigned int minsize,
|
||||
unsigned int (*hashfunction) (const void*),
|
||||
int (*key_eq_fn) (const void*,const void*));
|
||||
unsigned int (*hashfunction) (const void*),
|
||||
int (*key_eq_fn) (const void*,const void*));
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* create_string_hashtable
|
||||
* @name create_string_hashtable
|
||||
* @return hashtable for string keys, with start size of 16
|
||||
*/
|
||||
* create_string_hashtable
|
||||
* @name create_string_hashtable
|
||||
* @return hashtable for string keys, with start size of 16
|
||||
*/
|
||||
hashtable *
|
||||
create_string_hashtable(void);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* hashtable_insert
|
||||
* hashtable_insert
|
||||
|
||||
* @name hashtable_insert
|
||||
* @param h the hashtable to insert into
|
||||
* @param k the key - hashtable claims ownership and will free on removal
|
||||
* @param v the value - does not claim ownership
|
||||
* @return non-zero for successful insertion
|
||||
*
|
||||
* This function will cause the table to expand if the insertion would take
|
||||
* the ratio of entries to table size over the maximum load factor.
|
||||
*
|
||||
* This function does not check for repeated insertions with a duplicate key.
|
||||
* The value returned when using a duplicate key is undefined -- when
|
||||
* the hashtable changes size, the order of retrieval of duplicate key
|
||||
* entries is reversed.
|
||||
* If in doubt, remove before insert.
|
||||
*/
|
||||
* @name hashtable_insert
|
||||
* @param h the hashtable to insert into
|
||||
* @param k the key - hashtable claims ownership and will free on removal
|
||||
* @param v the value - does not claim ownership
|
||||
* @return non-zero for successful insertion
|
||||
*
|
||||
* This function will cause the table to expand if the insertion would take
|
||||
* the ratio of entries to table size over the maximum load factor.
|
||||
*
|
||||
* This function does not check for repeated insertions with a duplicate key.
|
||||
* The value returned when using a duplicate key is undefined -- when
|
||||
* the hashtable changes size, the order of retrieval of duplicate key
|
||||
* entries is reversed.
|
||||
* If in doubt, remove before insert.
|
||||
*/
|
||||
|
||||
int
|
||||
hashtable_insert(hashtable *h, void *k, void *v);
|
||||
@ -133,17 +134,17 @@ hashtable_insert(hashtable *h, void *k, void *v);
|
||||
#define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
|
||||
int fnname (hashtable *h, keytype *k, valuetype *v) \
|
||||
{ \
|
||||
return hashtable_insert(h,k,v); \
|
||||
return hashtable_insert(h,k,v); \
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* hashtable_search
|
||||
* hashtable_search
|
||||
|
||||
* @name hashtable_search
|
||||
* @param h the hashtable to search
|
||||
* @param k the key to search for - does not claim ownership
|
||||
* @return the value associated with the key, or NULL if none found
|
||||
*/
|
||||
* @name hashtable_search
|
||||
* @param h the hashtable to search
|
||||
* @param k the key to search for - does not claim ownership
|
||||
* @return the value associated with the key, or NULL if none found
|
||||
*/
|
||||
|
||||
void *
|
||||
hashtable_search(hashtable *h, const void *k);
|
||||
@ -151,17 +152,17 @@ hashtable_search(hashtable *h, const void *k);
|
||||
#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
|
||||
valuetype * fnname (hashtable *h, keytype *k) \
|
||||
{ \
|
||||
return (valuetype *) (hashtable_search(h,k)); \
|
||||
return (valuetype *) (hashtable_search(h,k)); \
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* hashtable_remove
|
||||
* hashtable_remove
|
||||
|
||||
* @name hashtable_remove
|
||||
* @param h the hashtable to remove the item from
|
||||
* @param k the key to search for - does not claim ownership
|
||||
* @return the value associated with the key, or NULL if none found
|
||||
*/
|
||||
* @name hashtable_remove
|
||||
* @param h the hashtable to remove the item from
|
||||
* @param k the key to search for - does not claim ownership
|
||||
* @return the value associated with the key, or NULL if none found
|
||||
*/
|
||||
|
||||
void * /* returns value */
|
||||
hashtable_remove(hashtable *h, void *k);
|
||||
@ -169,7 +170,7 @@ hashtable_remove(hashtable *h, void *k);
|
||||
#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
|
||||
valuetype * fnname (hashtable *h, keytype *k) \
|
||||
{ \
|
||||
return (valuetype *) (hashtable_remove(h,k)); \
|
||||
return (valuetype *) (hashtable_remove(h,k)); \
|
||||
}
|
||||
|
||||
|
||||
@ -192,23 +193,23 @@ str_eq(const void *str1, const void *str2);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* hashtable_count
|
||||
* hashtable_count
|
||||
|
||||
* @name hashtable_count
|
||||
* @param h the hashtable
|
||||
* @return the number of items stored in the hashtable
|
||||
*/
|
||||
* @name hashtable_count
|
||||
* @param h the hashtable
|
||||
* @return the number of items stored in the hashtable
|
||||
*/
|
||||
unsigned int
|
||||
hashtable_count(hashtable *h);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* hashtable_destroy
|
||||
* hashtable_destroy
|
||||
|
||||
* @name hashtable_destroy
|
||||
* @param h the hashtable
|
||||
* @param free_values whether to call 'free' on the remaining values
|
||||
*/
|
||||
* @name hashtable_destroy
|
||||
* @param h the hashtable
|
||||
* @param free_values whether to call 'free' on the remaining values
|
||||
*/
|
||||
|
||||
void
|
||||
hashtable_destroy(hashtable *h, int free_values);
|
||||
@ -227,34 +228,34 @@ indexFor(unsigned int tablelength, unsigned int hashvalue)
|
||||
#endif /* __HASHTABLE_CWC22_H__ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002, Christopher Clark
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* Copyright (c) 2002, Christopher Clark
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
50
lib/pc_api.h
50
lib/pc_api.h
@ -38,10 +38,10 @@
|
||||
*/
|
||||
enum COMPRESSIONS
|
||||
{
|
||||
PC_NONE = 0,
|
||||
PC_GHT = 1,
|
||||
PC_DIMENSIONAL = 2,
|
||||
PC_LAZPERF = 3
|
||||
PC_NONE = 0,
|
||||
PC_GHT = 1,
|
||||
PC_DIMENSIONAL = 2,
|
||||
PC_LAZPERF = 3
|
||||
};
|
||||
|
||||
/**
|
||||
@ -50,16 +50,16 @@ enum COMPRESSIONS
|
||||
*/
|
||||
enum ENDIANS
|
||||
{
|
||||
PC_XDR = 0, /* Big */
|
||||
PC_NDR = 1 /* Little */
|
||||
PC_XDR = 0, /* Big */
|
||||
PC_NDR = 1 /* Little */
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PC_GT,
|
||||
PC_LT,
|
||||
PC_EQUAL,
|
||||
PC_BETWEEN
|
||||
PC_GT,
|
||||
PC_LT,
|
||||
PC_EQUAL,
|
||||
PC_BETWEEN
|
||||
} PC_FILTERTYPE;
|
||||
|
||||
|
||||
@ -168,12 +168,12 @@ PCSTATS;
|
||||
*/
|
||||
|
||||
#define PCPATCH_COMMON \
|
||||
int type; \
|
||||
int8_t readonly; \
|
||||
const PCSCHEMA *schema; \
|
||||
uint32_t npoints; \
|
||||
PCBOUNDS bounds; \
|
||||
PCSTATS *stats;
|
||||
int type; \
|
||||
int8_t readonly; \
|
||||
const PCSCHEMA *schema; \
|
||||
uint32_t npoints; \
|
||||
PCBOUNDS bounds; \
|
||||
PCSTATS *stats;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -214,7 +214,7 @@ typedef void* (*pc_allocator)(size_t size);
|
||||
typedef void* (*pc_reallocator)(void *mem, size_t size);
|
||||
typedef void (*pc_deallocator)(void *mem);
|
||||
typedef void (*pc_message_handler)(const char *string, va_list ap)
|
||||
__attribute__ (( format (printf, 1, 0) ));
|
||||
__attribute__ (( format (printf, 1, 0) ));
|
||||
|
||||
|
||||
|
||||
@ -236,9 +236,11 @@ void pcinfo(const char *fmt, ...);
|
||||
void pcwarn(const char *fmt, ...);
|
||||
|
||||
/** Set custom memory allocators and messaging (used by PgSQL module) */
|
||||
void pc_set_handlers(pc_allocator allocator, pc_reallocator reallocator,
|
||||
pc_deallocator deallocator, pc_message_handler error_handler,
|
||||
pc_message_handler info_handler, pc_message_handler warning_handler);
|
||||
void pc_set_handlers(
|
||||
pc_allocator allocator, pc_reallocator reallocator,
|
||||
pc_deallocator deallocator, pc_message_handler error_handler,
|
||||
pc_message_handler info_handler, pc_message_handler warning_handler
|
||||
);
|
||||
|
||||
/** Set program to use system memory allocators and messaging */
|
||||
void pc_install_default_handlers(void);
|
||||
@ -318,10 +320,10 @@ PCPOINT* pc_point_from_data(const PCSCHEMA *s, const uint8_t *data);
|
||||
PCPOINT* pc_point_from_double_array(const PCSCHEMA *s, double *array, uint32_t nelems);
|
||||
|
||||
/**
|
||||
* Return an allocated double array of doubles representing point values
|
||||
*
|
||||
* The number of elements in the array is equal to pt->schema->n_dims
|
||||
*/
|
||||
* Return an allocated double array of doubles representing point values
|
||||
*
|
||||
* The number of elements in the array is equal to pt->schema->n_dims
|
||||
*/
|
||||
double* pc_point_to_double_array(const PCPOINT *pt);
|
||||
|
||||
/** Frees the PTPOINT and data (if not readonly). Does not free referenced schema */
|
||||
|
||||
@ -48,20 +48,20 @@
|
||||
|
||||
enum INTERPRETATIONS
|
||||
{
|
||||
PC_UNKNOWN = 0,
|
||||
PC_INT8 = 1, PC_UINT8 = 2,
|
||||
PC_INT16 = 3, PC_UINT16 = 4,
|
||||
PC_INT32 = 5, PC_UINT32 = 6,
|
||||
PC_INT64 = 7, PC_UINT64 = 8,
|
||||
PC_DOUBLE = 9, PC_FLOAT = 10
|
||||
PC_UNKNOWN = 0,
|
||||
PC_INT8 = 1, PC_UINT8 = 2,
|
||||
PC_INT16 = 3, PC_UINT16 = 4,
|
||||
PC_INT32 = 5, PC_UINT32 = 6,
|
||||
PC_INT64 = 7, PC_UINT64 = 8,
|
||||
PC_DOUBLE = 9, PC_FLOAT = 10
|
||||
};
|
||||
|
||||
enum DIMCOMPRESSIONS
|
||||
{
|
||||
PC_DIM_NONE = 0,
|
||||
PC_DIM_RLE = 1,
|
||||
PC_DIM_SIGBITS = 2,
|
||||
PC_DIM_ZLIB = 3
|
||||
PC_DIM_NONE = 0,
|
||||
PC_DIM_RLE = 1,
|
||||
PC_DIM_SIGBITS = 2,
|
||||
PC_DIM_ZLIB = 3
|
||||
};
|
||||
|
||||
/* PCDOUBLESTAT are members of PCDOUBLESTATS */
|
||||
|
||||
232
lib/pc_bytes.c
232
lib/pc_bytes.c
@ -1493,25 +1493,25 @@ pc_bytes_uncompressed_filter(const PCBYTES *pcb, const PCBITMAP *map, PCDOUBLEST
|
||||
int i = 0, j = 0;
|
||||
double d;
|
||||
PCBYTES fpcb = pc_bytes_clone(*pcb);
|
||||
int interp = pcb->interpretation;
|
||||
int interp = pcb->interpretation;
|
||||
int sz = pc_interpretation_size(interp);
|
||||
uint8_t *buf = pcb->bytes;
|
||||
uint8_t *fbuf = fpcb.bytes;
|
||||
|
||||
while ( i < pcb->npoints )
|
||||
{
|
||||
/* This entry is flagged to copy, so... */
|
||||
/* This entry is flagged to copy, so... */
|
||||
if ( pc_bitmap_get(map, i) )
|
||||
{
|
||||
/* Update stats on filtered bytes */
|
||||
if ( stats )
|
||||
{
|
||||
d = pc_double_from_ptr(buf, interp);
|
||||
if ( d < stats->min ) stats->min = d;
|
||||
if ( d > stats->max ) stats->max = d;
|
||||
stats->sum += d;
|
||||
}
|
||||
/* Copy into filtered byte array */
|
||||
/* Update stats on filtered bytes */
|
||||
if ( stats )
|
||||
{
|
||||
d = pc_double_from_ptr(buf, interp);
|
||||
if ( d < stats->min ) stats->min = d;
|
||||
if ( d > stats->max ) stats->max = d;
|
||||
stats->sum += d;
|
||||
}
|
||||
/* Copy into filtered byte array */
|
||||
memcpy(fbuf, buf, sz);
|
||||
fbuf += sz;
|
||||
j++;
|
||||
@ -1528,7 +1528,7 @@ pc_bytes_uncompressed_filter(const PCBYTES *pcb, const PCBITMAP *map, PCDOUBLEST
|
||||
static PCBYTES
|
||||
pc_bytes_run_length_filter(const PCBYTES *pcb, const PCBITMAP *map, PCDOUBLESTAT *stats)
|
||||
{
|
||||
int i = 0, j = 0, npoints = 0;
|
||||
int i = 0, j = 0, npoints = 0;
|
||||
double d;
|
||||
|
||||
PCBYTES fpcb = pc_bytes_clone(*pcb);
|
||||
@ -1537,51 +1537,51 @@ pc_bytes_run_length_filter(const PCBYTES *pcb, const PCBITMAP *map, PCDOUBLESTAT
|
||||
uint8_t *ptr = pcb->bytes;
|
||||
uint8_t *ptr_end = pcb->bytes + pcb->size;
|
||||
uint8_t count;
|
||||
uint8_t fcount;
|
||||
uint8_t fcount;
|
||||
|
||||
while( ptr < ptr_end )
|
||||
{
|
||||
/* Read unfiltered count */
|
||||
count = *ptr;
|
||||
/* Initialize filtered count */
|
||||
fcount = 0;
|
||||
|
||||
/* How many filtered points are in this value entry? */
|
||||
for ( j = i; j < i+count; j++ )
|
||||
{
|
||||
if ( pc_bitmap_get(map, j) )
|
||||
{
|
||||
fcount++;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there are some, we need to copy */
|
||||
if ( fcount )
|
||||
{
|
||||
/* Copy in the filtered count */
|
||||
memcpy(fptr, &fcount, 1);
|
||||
/* Advance to the value */
|
||||
fptr++;
|
||||
/* Copy in the value */
|
||||
memcpy(fptr, ptr+1, sz);
|
||||
/* Advance to next entry */
|
||||
fptr += sz;
|
||||
/* Increment point counter */
|
||||
npoints += fcount;
|
||||
/* Update the stats */
|
||||
if ( stats )
|
||||
{
|
||||
d = pc_double_from_ptr(ptr+1, pcb->interpretation);
|
||||
if ( d < stats->min ) stats->min = d;
|
||||
if ( d > stats->max ) stats->max = d;
|
||||
stats->sum += d;
|
||||
}
|
||||
}
|
||||
fcount = 0;
|
||||
|
||||
/* How many filtered points are in this value entry? */
|
||||
for ( j = i; j < i+count; j++ )
|
||||
{
|
||||
if ( pc_bitmap_get(map, j) )
|
||||
{
|
||||
fcount++;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there are some, we need to copy */
|
||||
if ( fcount )
|
||||
{
|
||||
/* Copy in the filtered count */
|
||||
memcpy(fptr, &fcount, 1);
|
||||
/* Advance to the value */
|
||||
fptr++;
|
||||
/* Copy in the value */
|
||||
memcpy(fptr, ptr+1, sz);
|
||||
/* Advance to next entry */
|
||||
fptr += sz;
|
||||
/* Increment point counter */
|
||||
npoints += fcount;
|
||||
/* Update the stats */
|
||||
if ( stats )
|
||||
{
|
||||
d = pc_double_from_ptr(ptr+1, pcb->interpretation);
|
||||
if ( d < stats->min ) stats->min = d;
|
||||
if ( d > stats->max ) stats->max = d;
|
||||
stats->sum += d;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move to next value in unfiltered bytes */
|
||||
ptr += sz+1;
|
||||
i += count;
|
||||
|
||||
/* Move to next value in unfiltered bytes */
|
||||
ptr += sz+1;
|
||||
i += count;
|
||||
|
||||
}
|
||||
fpcb.size = fptr - fpcb.bytes;
|
||||
fpcb.npoints = npoints;
|
||||
@ -1598,7 +1598,7 @@ pc_bytes_filter(const PCBYTES *pcb, const PCBITMAP *map, PCDOUBLESTAT *stats)
|
||||
return pc_bytes_uncompressed_filter(pcb, map, stats);
|
||||
|
||||
case PC_DIM_RLE:
|
||||
return pc_bytes_run_length_filter(pcb, map, stats);
|
||||
return pc_bytes_run_length_filter(pcb, map, stats);
|
||||
|
||||
case PC_DIM_SIGBITS:
|
||||
case PC_DIM_ZLIB:
|
||||
@ -1711,7 +1711,7 @@ pc_bytes_run_length_to_ptr(uint8_t *buf, PCBYTES pcb, int n)
|
||||
const uint8_t *bytes_rle_ptr = pcb.bytes;
|
||||
const uint8_t *bytes_rle_end = pcb.bytes + pcb.size;
|
||||
uint8_t run;
|
||||
|
||||
|
||||
size_t size = pc_interpretation_size(pcb.interpretation);
|
||||
assert(pcb.compression == PC_DIM_RLE);
|
||||
|
||||
@ -1732,37 +1732,37 @@ pc_bytes_run_length_to_ptr(uint8_t *buf, PCBYTES pcb, int n)
|
||||
void \
|
||||
pc_bytes_sigbits_to_ptr_##N(uint8_t *buf, PCBYTES pcb, int n) \
|
||||
{ \
|
||||
const uint##N##_t *bytes_ptr = (const uint##N##_t*)(pcb.bytes); \
|
||||
/* How many unique bits? */ \
|
||||
uint##N##_t nbits = *bytes_ptr++; \
|
||||
/* What is the shared bit value? */ \
|
||||
uint##N##_t commonvalue = *bytes_ptr++; \
|
||||
/* Mask for just the unique parts */ \
|
||||
uint##N##_t mask = 0xFFFFFFFFFFFFFFFF >> (64-nbits); \
|
||||
\
|
||||
uint##N##_t bitoffset = n*nbits; \
|
||||
bytes_ptr += bitoffset / N; \
|
||||
int shift = N - (bitoffset % N) - nbits; \
|
||||
\
|
||||
uint##N##_t res = commonvalue; \
|
||||
uint##N##_t val = *bytes_ptr; \
|
||||
/* The unique part is split over this word and the next */ \
|
||||
if ( shift < 0 ) \
|
||||
{ \
|
||||
val <<= -shift; \
|
||||
val &= mask; \
|
||||
res |= val; \
|
||||
bytes_ptr++; \
|
||||
val = *bytes_ptr; \
|
||||
shift += N; \
|
||||
} \
|
||||
/* Push unique part to bottom of word */ \
|
||||
val >>= shift; \
|
||||
/* Mask out any excess */ \
|
||||
val &= mask; \
|
||||
/* Save */ \
|
||||
res |= val; \
|
||||
memcpy(buf,&res,sizeof(res)); \
|
||||
const uint##N##_t *bytes_ptr = (const uint##N##_t*)(pcb.bytes); \
|
||||
/* How many unique bits? */ \
|
||||
uint##N##_t nbits = *bytes_ptr++; \
|
||||
/* What is the shared bit value? */ \
|
||||
uint##N##_t commonvalue = *bytes_ptr++; \
|
||||
/* Mask for just the unique parts */ \
|
||||
uint##N##_t mask = 0xFFFFFFFFFFFFFFFF >> (64-nbits); \
|
||||
\
|
||||
uint##N##_t bitoffset = n*nbits; \
|
||||
bytes_ptr += bitoffset / N; \
|
||||
int shift = N - (bitoffset % N) - nbits; \
|
||||
\
|
||||
uint##N##_t res = commonvalue; \
|
||||
uint##N##_t val = *bytes_ptr; \
|
||||
/* The unique part is split over this word and the next */ \
|
||||
if ( shift < 0 ) \
|
||||
{ \
|
||||
val <<= -shift; \
|
||||
val &= mask; \
|
||||
res |= val; \
|
||||
bytes_ptr++; \
|
||||
val = *bytes_ptr; \
|
||||
shift += N; \
|
||||
} \
|
||||
/* Push unique part to bottom of word */ \
|
||||
val >>= shift; \
|
||||
/* Mask out any excess */ \
|
||||
val &= mask; \
|
||||
/* Save */ \
|
||||
res |= val; \
|
||||
memcpy(buf,&res,sizeof(res)); \
|
||||
}
|
||||
|
||||
PC_BYTES_SIGBITS_TO_PTR(8)
|
||||
@ -1778,19 +1778,19 @@ pc_bytes_sigbits_to_ptr(uint8_t *buf, PCBYTES pcb, int n)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
return pc_bytes_sigbits_to_ptr_8(buf,pcb,n);
|
||||
return pc_bytes_sigbits_to_ptr_8(buf,pcb,n);
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
return pc_bytes_sigbits_to_ptr_16(buf,pcb,n);
|
||||
return pc_bytes_sigbits_to_ptr_16(buf,pcb,n);
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
return pc_bytes_sigbits_to_ptr_32(buf,pcb,n);
|
||||
return pc_bytes_sigbits_to_ptr_32(buf,pcb,n);
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
return pc_bytes_sigbits_to_ptr_64(buf,pcb,n);
|
||||
return pc_bytes_sigbits_to_ptr_64(buf,pcb,n);
|
||||
}
|
||||
default:
|
||||
{
|
||||
@ -1803,40 +1803,40 @@ pc_bytes_sigbits_to_ptr(uint8_t *buf, PCBYTES pcb, int n)
|
||||
void
|
||||
pc_bytes_zlib_to_ptr(uint8_t *buf, PCBYTES pcb, int n)
|
||||
{
|
||||
PCBYTES dpcb = pc_bytes_decode(pcb);
|
||||
pc_bytes_uncompressed_to_ptr(buf,dpcb,n);
|
||||
pc_bytes_free(dpcb);
|
||||
PCBYTES dpcb = pc_bytes_decode(pcb);
|
||||
pc_bytes_uncompressed_to_ptr(buf,dpcb,n);
|
||||
pc_bytes_free(dpcb);
|
||||
}
|
||||
|
||||
void
|
||||
pc_bytes_to_ptr(uint8_t *buf, PCBYTES pcb, int n)
|
||||
{
|
||||
switch ( pcb.compression )
|
||||
{
|
||||
case PC_DIM_RLE:
|
||||
{
|
||||
switch ( pcb.compression )
|
||||
{
|
||||
case PC_DIM_RLE:
|
||||
{
|
||||
pc_bytes_run_length_to_ptr(buf,pcb,n);
|
||||
break;
|
||||
}
|
||||
case PC_DIM_SIGBITS:
|
||||
{
|
||||
pc_bytes_sigbits_to_ptr(buf,pcb,n);
|
||||
break;
|
||||
}
|
||||
case PC_DIM_ZLIB:
|
||||
{
|
||||
pc_bytes_zlib_to_ptr(buf,pcb,n);
|
||||
break;
|
||||
}
|
||||
case PC_DIM_NONE:
|
||||
{
|
||||
pc_bytes_uncompressed_to_ptr(buf,pcb,n);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
pcerror("%s: Uh oh", __func__);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PC_DIM_SIGBITS:
|
||||
{
|
||||
pc_bytes_sigbits_to_ptr(buf,pcb,n);
|
||||
break;
|
||||
}
|
||||
case PC_DIM_ZLIB:
|
||||
{
|
||||
pc_bytes_zlib_to_ptr(buf,pcb,n);
|
||||
break;
|
||||
}
|
||||
case PC_DIM_NONE:
|
||||
{
|
||||
pc_bytes_uncompressed_to_ptr(buf,pcb,n);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
pcerror("%s: Uh oh", __func__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -44,17 +44,17 @@ pc_dimstats_free(PCDIMSTATS *pds)
|
||||
/*
|
||||
typedef struct
|
||||
{
|
||||
uint32_t total_runs;
|
||||
uint32_t total_commonbits;
|
||||
uint32_t recommended_compression;
|
||||
uint32_t total_runs;
|
||||
uint32_t total_commonbits;
|
||||
uint32_t recommended_compression;
|
||||
} PCDIMSTAT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t ndims;
|
||||
uint32_t total_points;
|
||||
uint32_t total_patches;
|
||||
PCDIMSTAT *stats;
|
||||
int32_t ndims;
|
||||
uint32_t total_points;
|
||||
uint32_t total_patches;
|
||||
PCDIMSTAT *stats;
|
||||
} PCDIMSTATS;
|
||||
*/
|
||||
|
||||
@ -65,20 +65,22 @@ pc_dimstats_to_string(const PCDIMSTATS *pds)
|
||||
stringbuffer_t *sb = stringbuffer_create();
|
||||
char *str;
|
||||
|
||||
stringbuffer_aprintf(sb,"{\"ndims\":%d,\"total_points\":%d,\"total_patches\":%d,\"dims\":[",
|
||||
pds->ndims,
|
||||
pds->total_points,
|
||||
pds->total_patches
|
||||
);
|
||||
stringbuffer_aprintf(sb,
|
||||
"{\"ndims\":%d,\"total_points\":%d,\"total_patches\":%d,\"dims\":[",
|
||||
pds->ndims,
|
||||
pds->total_points,
|
||||
pds->total_patches
|
||||
);
|
||||
|
||||
for ( i = 0; i < pds->ndims; i++ )
|
||||
{
|
||||
if ( i ) stringbuffer_append(sb, ",");
|
||||
stringbuffer_aprintf(sb, "{\"total_runs\":%d,\"total_commonbits\":%d,\"recommended_compression\":%d}",
|
||||
pds->stats[i].total_runs,
|
||||
pds->stats[i].total_commonbits,
|
||||
pds->stats[i].recommended_compression
|
||||
);
|
||||
stringbuffer_aprintf(sb,
|
||||
"{\"total_runs\":%d,\"total_commonbits\":%d,\"recommended_compression\":%d}",
|
||||
pds->stats[i].total_runs,
|
||||
pds->stats[i].total_commonbits,
|
||||
pds->stats[i].recommended_compression
|
||||
);
|
||||
}
|
||||
stringbuffer_append(sb, "]}");
|
||||
|
||||
|
||||
118
lib/pc_filter.c
118
lib/pc_filter.c
@ -146,16 +146,16 @@ pc_patch_dimensional_filter(const PCPATCH_DIMENSIONAL *pdl, const PCBITMAP *map)
|
||||
int i = 0;
|
||||
PCPATCH_DIMENSIONAL *fpdl = pc_patch_dimensional_clone(pdl);
|
||||
|
||||
fpdl->stats = pc_stats_clone(pdl->stats);
|
||||
fpdl->stats = pc_stats_clone(pdl->stats);
|
||||
fpdl->npoints = map->nset;
|
||||
|
||||
for ( i = 0; i < pdl->schema->ndims; i++ )
|
||||
{
|
||||
PCDIMENSION *dim;
|
||||
PCDOUBLESTAT stats;
|
||||
stats.min = FLT_MAX;
|
||||
stats.max = -1*FLT_MAX;
|
||||
stats.sum = 0;
|
||||
PCDOUBLESTAT stats;
|
||||
stats.min = FLT_MAX;
|
||||
stats.max = -1*FLT_MAX;
|
||||
stats.sum = 0;
|
||||
fpdl->bytes[i] = pc_bytes_filter(&(pdl->bytes[i]), map, &stats);
|
||||
|
||||
|
||||
@ -168,18 +168,18 @@ pc_patch_dimensional_filter(const PCPATCH_DIMENSIONAL *pdl, const PCBITMAP *map)
|
||||
/* Save the X/Y stats for use in bounds later */
|
||||
if ( i == pdl->schema->x_position )
|
||||
{
|
||||
fpdl->bounds.xmin = stats.min;
|
||||
fpdl->bounds.xmax = stats.max;
|
||||
}
|
||||
fpdl->bounds.xmin = stats.min;
|
||||
fpdl->bounds.xmax = stats.max;
|
||||
}
|
||||
else if ( i == pdl->schema->y_position )
|
||||
{
|
||||
fpdl->bounds.ymin = stats.min;
|
||||
fpdl->bounds.ymax = stats.max;
|
||||
}
|
||||
fpdl->bounds.ymin = stats.min;
|
||||
fpdl->bounds.ymax = stats.max;
|
||||
}
|
||||
|
||||
pc_point_set_double_by_index(&(fpdl->stats->min), i, stats.min);
|
||||
pc_point_set_double_by_index(&(fpdl->stats->max), i, stats.max);
|
||||
pc_point_set_double_by_index(&(fpdl->stats->avg), i, stats.sum/fpdl->npoints);
|
||||
pc_point_set_double_by_index(&(fpdl->stats->min), i, stats.min);
|
||||
pc_point_set_double_by_index(&(fpdl->stats->max), i, stats.max);
|
||||
pc_point_set_double_by_index(&(fpdl->stats->avg), i, stats.sum/fpdl->npoints);
|
||||
}
|
||||
|
||||
return fpdl;
|
||||
@ -189,33 +189,33 @@ pc_patch_dimensional_filter(const PCPATCH_DIMENSIONAL *pdl, const PCBITMAP *map)
|
||||
static int
|
||||
pc_patch_filter_has_results(const PCSTATS *stats, uint32_t dimnum, PC_FILTERTYPE filter, double val1, double val2)
|
||||
{
|
||||
double min, max;
|
||||
pc_point_get_double_by_index(&(stats->min), dimnum, &min);
|
||||
pc_point_get_double_by_index(&(stats->max), dimnum, &max);
|
||||
double min, max;
|
||||
pc_point_get_double_by_index(&(stats->min), dimnum, &min);
|
||||
pc_point_get_double_by_index(&(stats->max), dimnum, &max);
|
||||
switch ( filter )
|
||||
{
|
||||
case PC_GT:
|
||||
{
|
||||
if ( max < val1 ) return PC_FALSE;
|
||||
break;
|
||||
case PC_GT:
|
||||
{
|
||||
if ( max < val1 ) return PC_FALSE;
|
||||
break;
|
||||
}
|
||||
case PC_LT:
|
||||
{
|
||||
if ( min > val1 ) return PC_FALSE;
|
||||
break;
|
||||
case PC_LT:
|
||||
{
|
||||
if ( min > val1 ) return PC_FALSE;
|
||||
break;
|
||||
}
|
||||
case PC_EQUAL:
|
||||
{
|
||||
if ( min > val1 || max < val1 ) return PC_FALSE;
|
||||
break;
|
||||
case PC_EQUAL:
|
||||
{
|
||||
if ( min > val1 || max < val1 ) return PC_FALSE;
|
||||
break;
|
||||
}
|
||||
case PC_BETWEEN:
|
||||
{
|
||||
if ( min > val2 || max < val1 ) return PC_FALSE;
|
||||
break;
|
||||
case PC_BETWEEN:
|
||||
{
|
||||
if ( min > val2 || max < val1 ) return PC_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return PC_TRUE;
|
||||
return PC_TRUE;
|
||||
}
|
||||
|
||||
|
||||
@ -225,13 +225,13 @@ pc_patch_filter(const PCPATCH *pa, uint32_t dimnum, PC_FILTERTYPE filter, double
|
||||
if ( ! pa ) return NULL;
|
||||
PCPATCH *paout;
|
||||
|
||||
/* If the stats say this filter returns an empty result, do that */
|
||||
if ( pa->stats && ! pc_patch_filter_has_results(pa->stats, dimnum, filter, val1, val2) )
|
||||
{
|
||||
/* Empty uncompressed patch to return */
|
||||
paout = (PCPATCH*)pc_patch_uncompressed_make(pa->schema, 0);
|
||||
return paout;
|
||||
}
|
||||
/* If the stats say this filter returns an empty result, do that */
|
||||
if ( pa->stats && ! pc_patch_filter_has_results(pa->stats, dimnum, filter, val1, val2) )
|
||||
{
|
||||
/* Empty uncompressed patch to return */
|
||||
paout = (PCPATCH*)pc_patch_uncompressed_make(pa->schema, 0);
|
||||
return paout;
|
||||
}
|
||||
|
||||
switch ( pa->type )
|
||||
{
|
||||
@ -253,11 +253,11 @@ pc_patch_filter(const PCPATCH *pa, uint32_t dimnum, PC_FILTERTYPE filter, double
|
||||
}
|
||||
case PC_GHT:
|
||||
{
|
||||
PCPATCH_GHT *pgh = pc_patch_ght_filter((PCPATCH_GHT*)pa, dimnum, filter, val1, val2);
|
||||
PCPATCH_GHT *pgh = pc_patch_ght_filter((PCPATCH_GHT*)pa, dimnum, filter, val1, val2);
|
||||
/* pc_patch_ght_filter computes the bounds itself */
|
||||
/* TODO: add stats computation to pc_patch_ght_filter */
|
||||
/* pc_patch_ght_filter is just re-using the input stats, which is wrong */
|
||||
paout = (PCPATCH*)pgh;
|
||||
paout = (PCPATCH*)pgh;
|
||||
break;
|
||||
}
|
||||
case PC_DIMENSIONAL:
|
||||
@ -277,25 +277,25 @@ pc_patch_filter(const PCPATCH *pa, uint32_t dimnum, PC_FILTERTYPE filter, double
|
||||
}
|
||||
case PC_LAZPERF:
|
||||
{
|
||||
PCBITMAP *map;
|
||||
PCPATCH_UNCOMPRESSED *pu;
|
||||
PCPATCH_UNCOMPRESSED *pau;
|
||||
PCBITMAP *map;
|
||||
PCPATCH_UNCOMPRESSED *pu;
|
||||
PCPATCH_UNCOMPRESSED *pau;
|
||||
|
||||
pau = pc_patch_uncompressed_from_lazperf( (PCPATCH_LAZPERF*) pa );
|
||||
map = pc_patch_uncompressed_bitmap(pau, dimnum, filter, val1, val2);
|
||||
if ( map->nset == 0 )
|
||||
{
|
||||
pau = pc_patch_uncompressed_from_lazperf( (PCPATCH_LAZPERF*) pa );
|
||||
map = pc_patch_uncompressed_bitmap(pau, dimnum, filter, val1, val2);
|
||||
if ( map->nset == 0 )
|
||||
{
|
||||
pc_bitmap_free(map);
|
||||
return (PCPATCH*)pc_patch_uncompressed_make(pa->schema, -1);
|
||||
}
|
||||
|
||||
pu = pc_patch_uncompressed_filter(pau, map);
|
||||
pc_bitmap_free(map);
|
||||
return (PCPATCH*)pc_patch_uncompressed_make(pa->schema, -1);
|
||||
}
|
||||
/* pc_patch_uncompressed_filter computes stats and bounds, so we're ready to return here */
|
||||
/* TODO, it could/should compute bounds and stats while filtering the points */
|
||||
paout = (PCPATCH*)pu;
|
||||
|
||||
pu = pc_patch_uncompressed_filter(pau, map);
|
||||
pc_bitmap_free(map);
|
||||
/* pc_patch_uncompressed_filter computes stats and bounds, so we're ready to return here */
|
||||
/* TODO, it could/should compute bounds and stats while filtering the points */
|
||||
paout = (PCPATCH*)pu;
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
pcerror("%s: failure", __func__);
|
||||
|
||||
23
lib/pc_mem.c
23
lib/pc_mem.c
@ -92,16 +92,19 @@ void pc_install_default_handlers(void)
|
||||
pc_context.warn = default_warn_handler;
|
||||
|
||||
#ifdef HAVE_LIBGHT
|
||||
ght_set_handlers((void *)default_allocator, (void *)default_reallocator,
|
||||
(void *)default_freeor, (void *)default_error_handler,
|
||||
(void *)default_info_handler, (void *)default_warn_handler);
|
||||
ght_set_handlers(
|
||||
(void *)default_allocator, (void *)default_reallocator,
|
||||
(void *)default_freeor, (void *)default_error_handler,
|
||||
(void *)default_info_handler, (void *)default_warn_handler
|
||||
);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void pc_set_handlers(pc_allocator allocator, pc_reallocator reallocator,
|
||||
pc_deallocator deallocator, pc_message_handler error_handler,
|
||||
pc_message_handler info_handler, pc_message_handler warn_handler)
|
||||
void pc_set_handlers(
|
||||
pc_allocator allocator, pc_reallocator reallocator,
|
||||
pc_deallocator deallocator, pc_message_handler error_handler,
|
||||
pc_message_handler info_handler, pc_message_handler warn_handler)
|
||||
{
|
||||
if ( ! allocator ) allocator = pc_context.alloc;
|
||||
if ( ! reallocator ) reallocator = pc_context.realloc;
|
||||
@ -118,9 +121,11 @@ void pc_set_handlers(pc_allocator allocator, pc_reallocator reallocator,
|
||||
pc_context.info = info_handler;
|
||||
|
||||
#ifdef HAVE_LIBGHT
|
||||
ght_set_handlers((void *)allocator, (void *)reallocator,
|
||||
(void *)deallocator, (void *)error_handler,
|
||||
(void *)info_handler, (void *)warn_handler);
|
||||
ght_set_handlers(
|
||||
(void *)allocator, (void *)reallocator,
|
||||
(void *)deallocator, (void *)error_handler,
|
||||
(void *)info_handler, (void *)warn_handler
|
||||
);
|
||||
#endif
|
||||
|
||||
return;
|
||||
|
||||
@ -527,20 +527,20 @@ pc_patch_from_patchlist(PCPATCH **palist, int numpatches)
|
||||
/** negative 1-based: -1=last point, -npoints=first point */
|
||||
PCPOINT *pc_patch_pointn(const PCPATCH *patch, int n)
|
||||
{
|
||||
if(!patch) return NULL;
|
||||
if(n<0) n = patch->npoints+n; // negative indices count a backward
|
||||
else --n; // 1-based => 0-based indexing
|
||||
if(n<0 || n>= patch->npoints) return NULL;
|
||||
if(!patch) return NULL;
|
||||
if(n<0) n = patch->npoints+n; // negative indices count a backward
|
||||
else --n; // 1-based => 0-based indexing
|
||||
if(n<0 || n>= patch->npoints) return NULL;
|
||||
|
||||
switch( patch->type )
|
||||
{
|
||||
case PC_NONE:
|
||||
return pc_patch_uncompressed_pointn((PCPATCH_UNCOMPRESSED*)patch,n);
|
||||
case PC_DIMENSIONAL:
|
||||
return pc_patch_dimensional_pointn((PCPATCH_DIMENSIONAL*)patch,n);
|
||||
case PC_GHT:
|
||||
return pc_patch_ght_pointn((PCPATCH_GHT*)patch,n);
|
||||
}
|
||||
pcerror("%s: unsupported compression %d requested", __func__, patch->type);
|
||||
return NULL;
|
||||
switch( patch->type )
|
||||
{
|
||||
case PC_NONE:
|
||||
return pc_patch_uncompressed_pointn((PCPATCH_UNCOMPRESSED*)patch,n);
|
||||
case PC_DIMENSIONAL:
|
||||
return pc_patch_dimensional_pointn((PCPATCH_DIMENSIONAL*)patch,n);
|
||||
case PC_GHT:
|
||||
return pc_patch_ght_pointn((PCPATCH_GHT*)patch,n);
|
||||
}
|
||||
pcerror("%s: unsupported compression %d requested", __func__, patch->type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -17,13 +17,13 @@
|
||||
/*
|
||||
typedef struct
|
||||
{
|
||||
int type;
|
||||
int type;
|
||||
int8_t readonly;
|
||||
const PCSCHEMA *schema;
|
||||
uint32_t npoints;
|
||||
double xmin, xmax, ymin, ymax;
|
||||
PCSTATS *stats;
|
||||
PCBYTES *bytes;
|
||||
PCBYTES *bytes;
|
||||
} PCPATCH_DIMENSIONAL;
|
||||
*/
|
||||
|
||||
@ -307,17 +307,17 @@ pc_patch_dimensional_from_pointlist(const PCPOINTLIST *pdl)
|
||||
/** get point n, 0-based, positive */
|
||||
PCPOINT *pc_patch_dimensional_pointn(const PCPATCH_DIMENSIONAL *pdl, int n)
|
||||
{
|
||||
assert(pdl);
|
||||
assert(pdl->schema);
|
||||
int i;
|
||||
int ndims = pdl->schema->ndims;
|
||||
PCPOINT *pt = pc_point_make(pdl->schema);
|
||||
uint8_t *buf = pt->data;
|
||||
for ( i = 0; i < ndims; i++ )
|
||||
{
|
||||
PCDIMENSION *dim = pc_schema_get_dimension(pdl->schema, i);
|
||||
pc_bytes_to_ptr(buf+dim->byteoffset,pdl->bytes[i], n);
|
||||
}
|
||||
assert(pdl);
|
||||
assert(pdl->schema);
|
||||
int i;
|
||||
int ndims = pdl->schema->ndims;
|
||||
PCPOINT *pt = pc_point_make(pdl->schema);
|
||||
uint8_t *buf = pt->data;
|
||||
for ( i = 0; i < ndims; i++ )
|
||||
{
|
||||
PCDIMENSION *dim = pc_schema_get_dimension(pdl->schema, i);
|
||||
pc_bytes_to_ptr(buf+dim->byteoffset,pdl->bytes[i], n);
|
||||
}
|
||||
|
||||
return pt;
|
||||
return pt;
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@ ght_type_from_pc_type(const int pctype)
|
||||
case PC_FLOAT:
|
||||
return GHT_FLOAT;
|
||||
}
|
||||
|
||||
|
||||
return GHT_UNKNOWN;
|
||||
}
|
||||
|
||||
@ -216,7 +216,7 @@ pc_patch_ght_from_uncompressed(const PCPATCH_UNCOMPRESSED *pa)
|
||||
ght_writer_free(writer);
|
||||
}
|
||||
|
||||
// Let the heirarchical memory manager clean up the tree
|
||||
// Let the hierarchical memory manager clean up the tree
|
||||
// ght_tree_free(tree);
|
||||
return paght;
|
||||
#endif
|
||||
@ -236,8 +236,8 @@ pc_patch_ght_free(PCPATCH_GHT *paght)
|
||||
/* so only free a readwrite tree */
|
||||
if ( ! paght->readonly )
|
||||
{
|
||||
if ( paght->ght )
|
||||
pcfree(paght->ght);
|
||||
if ( paght->ght )
|
||||
pcfree(paght->ght);
|
||||
}
|
||||
|
||||
pcfree(paght);
|
||||
@ -479,93 +479,93 @@ pc_patch_ght_filter(const PCPATCH_GHT *patch, uint32_t dimnum, PC_FILTERTYPE fil
|
||||
|
||||
GhtTreePtr tree;
|
||||
GhtTreePtr tree_filtered;
|
||||
GhtErr err;
|
||||
GhtErr err;
|
||||
GhtWriterPtr writer;
|
||||
GhtArea area;
|
||||
const char *dimname;
|
||||
const PCDIMENSION *dim;
|
||||
PCPATCH_GHT *paght;
|
||||
int npoints;
|
||||
const char *dimname;
|
||||
const PCDIMENSION *dim;
|
||||
PCPATCH_GHT *paght;
|
||||
int npoints;
|
||||
|
||||
/* Echo null back */
|
||||
if ( ! patch ) return NULL;
|
||||
|
||||
/* Echo null back */
|
||||
if ( ! patch ) return NULL;
|
||||
|
||||
/* Get a tree */
|
||||
tree = ght_tree_from_pc_patch(patch);
|
||||
if ( ! tree ) pcerror("%s: call to ght_tree_from_pc_patch failed", __func__);
|
||||
|
||||
/* Get dimname */
|
||||
dim = pc_schema_get_dimension(patch->schema, dimnum);
|
||||
if ( ! dim ) pcerror("%s: invalid dimension number (%d)", __func__, dimnum);
|
||||
dimname = dim->name;
|
||||
/* Get dimname */
|
||||
dim = pc_schema_get_dimension(patch->schema, dimnum);
|
||||
if ( ! dim ) pcerror("%s: invalid dimension number (%d)", __func__, dimnum);
|
||||
dimname = dim->name;
|
||||
|
||||
switch ( filter )
|
||||
{
|
||||
case PC_GT:
|
||||
err = ght_tree_filter_greater_than(tree, dimname, val1 > val2 ? val1 : val2, &tree_filtered);
|
||||
break;
|
||||
case PC_LT:
|
||||
err = ght_tree_filter_less_than(tree, dimname, val1 < val2 ? val1 : val2, &tree_filtered);
|
||||
break;
|
||||
case PC_EQUAL:
|
||||
err = ght_tree_filter_equal(tree, dimname, val1, &tree_filtered);
|
||||
break;
|
||||
case PC_BETWEEN:
|
||||
err = ght_tree_filter_between(tree, dimname, val1, val2, &tree_filtered);
|
||||
break;
|
||||
default:
|
||||
pcerror("%s: invalid filter type (%d)", __func__, filter);
|
||||
return NULL;
|
||||
}
|
||||
switch ( filter )
|
||||
{
|
||||
case PC_GT:
|
||||
err = ght_tree_filter_greater_than(tree, dimname, val1 > val2 ? val1 : val2, &tree_filtered);
|
||||
break;
|
||||
case PC_LT:
|
||||
err = ght_tree_filter_less_than(tree, dimname, val1 < val2 ? val1 : val2, &tree_filtered);
|
||||
break;
|
||||
case PC_EQUAL:
|
||||
err = ght_tree_filter_equal(tree, dimname, val1, &tree_filtered);
|
||||
break;
|
||||
case PC_BETWEEN:
|
||||
err = ght_tree_filter_between(tree, dimname, val1, val2, &tree_filtered);
|
||||
break;
|
||||
default:
|
||||
pcerror("%s: invalid filter type (%d)", __func__, filter);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ght_tree_filter_* returns a tree with NULL tree element and npoints == 0 */
|
||||
/* for empty filter results (everything got filtered away) */
|
||||
if ( err != GHT_OK || ! tree_filtered )
|
||||
pcerror("%s: ght_tree_filter failed", __func__);
|
||||
/* ght_tree_filter_* returns a tree with NULL tree element and npoints == 0 */
|
||||
/* for empty filter results (everything got filtered away) */
|
||||
if ( err != GHT_OK || ! tree_filtered )
|
||||
pcerror("%s: ght_tree_filter failed", __func__);
|
||||
|
||||
/* Read numpoints left in patch */
|
||||
ght_tree_get_numpoints(tree_filtered, &(npoints));
|
||||
/* Read numpoints left in patch */
|
||||
ght_tree_get_numpoints(tree_filtered, &(npoints));
|
||||
|
||||
/* Allocate a fresh GHT patch for output */
|
||||
/* Allocate a fresh GHT patch for output */
|
||||
paght = pcalloc(sizeof(PCPATCH_GHT));
|
||||
paght->type = PC_GHT;
|
||||
paght->readonly = PC_FALSE;
|
||||
paght->schema = patch->schema;
|
||||
paght->npoints = npoints;
|
||||
|
||||
/* No points, not much to do... */
|
||||
/* No points, not much to do... */
|
||||
if ( ! npoints )
|
||||
{
|
||||
paght->ghtsize = 0;
|
||||
paght->ght = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Calculate bounds and save */
|
||||
if ( GHT_OK != ght_tree_get_extent(tree_filtered, &area) )
|
||||
pcerror("%s: ght_tree_get_extent failed", __func__);
|
||||
paght->ghtsize = 0;
|
||||
paght->ght = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Calculate bounds and save */
|
||||
if ( GHT_OK != ght_tree_get_extent(tree_filtered, &area) )
|
||||
pcerror("%s: ght_tree_get_extent failed", __func__);
|
||||
|
||||
paght->bounds.xmin = area.x.min;
|
||||
paght->bounds.xmax = area.x.max;
|
||||
paght->bounds.ymin = area.y.min;
|
||||
paght->bounds.ymax = area.y.max;
|
||||
paght->bounds.xmin = area.x.min;
|
||||
paght->bounds.xmax = area.x.max;
|
||||
paght->bounds.ymin = area.y.min;
|
||||
paght->bounds.ymax = area.y.max;
|
||||
|
||||
/* TODO: Replace this; need to update stats too */
|
||||
paght->stats = pc_stats_clone(patch->stats);
|
||||
|
||||
/* Convert the tree to a memory buffer */
|
||||
ght_writer_new_mem(&writer);
|
||||
ght_tree_write(tree_filtered, writer);
|
||||
ght_writer_get_size(writer, &(paght->ghtsize));
|
||||
paght->ght = pcalloc(paght->ghtsize);
|
||||
ght_writer_get_bytes(writer, paght->ght);
|
||||
ght_writer_free(writer);
|
||||
/* TODO: Replace this; need to update stats too */
|
||||
paght->stats = pc_stats_clone(patch->stats);
|
||||
|
||||
/* Convert the tree to a memory buffer */
|
||||
ght_writer_new_mem(&writer);
|
||||
ght_tree_write(tree_filtered, writer);
|
||||
ght_writer_get_size(writer, &(paght->ghtsize));
|
||||
paght->ght = pcalloc(paght->ghtsize);
|
||||
ght_writer_get_bytes(writer, paght->ght);
|
||||
ght_writer_free(writer);
|
||||
}
|
||||
|
||||
// ght_tree_free(tree_filtered);
|
||||
// ght_tree_free(tree);
|
||||
|
||||
return paght;
|
||||
return paght;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -14,8 +14,8 @@
|
||||
#include "stringbuffer.h"
|
||||
|
||||
/* TODO: expose to API ? Would require also exposing stringbuffer
|
||||
* See https://github.com/pgpointcloud/pointcloud/issues/74
|
||||
*/
|
||||
* See https://github.com/pgpointcloud/pointcloud/issues/74
|
||||
*/
|
||||
static int
|
||||
pc_patch_uncompressed_to_stringbuffer(const PCPATCH_UNCOMPRESSED *patch, stringbuffer_t *sb)
|
||||
{
|
||||
@ -57,13 +57,13 @@ pc_patch_uncompressed_to_stringbuffer(const PCPATCH_UNCOMPRESSED *patch, stringb
|
||||
char *
|
||||
pc_patch_uncompressed_to_string(const PCPATCH_UNCOMPRESSED *patch)
|
||||
{
|
||||
stringbuffer_t *sb = stringbuffer_create();
|
||||
char *str;
|
||||
if ( PC_FAILURE == pc_patch_uncompressed_to_stringbuffer(patch, sb) )
|
||||
return NULL;
|
||||
str = stringbuffer_release_string(sb);
|
||||
stringbuffer_destroy(sb);
|
||||
return str;
|
||||
stringbuffer_t *sb = stringbuffer_create();
|
||||
char *str;
|
||||
if ( PC_FAILURE == pc_patch_uncompressed_to_stringbuffer(patch, sb) )
|
||||
return NULL;
|
||||
str = stringbuffer_release_string(sb);
|
||||
stringbuffer_destroy(sb);
|
||||
return str;
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
@ -175,10 +175,10 @@ pc_patch_uncompressed_make(const PCSCHEMA *s, uint32_t maxpoints)
|
||||
/* Make our own data area */
|
||||
datasize = s->size * maxpoints;
|
||||
pch->datasize = datasize;
|
||||
pch->data = NULL;
|
||||
pch->data = NULL;
|
||||
if ( datasize )
|
||||
{
|
||||
pch->data = pcalloc(datasize);
|
||||
pch->data = pcalloc(datasize);
|
||||
}
|
||||
pc_bounds_init(&(pch->bounds));
|
||||
|
||||
@ -208,7 +208,7 @@ pc_patch_uncompressed_compute_extent(PCPATCH_UNCOMPRESSED *patch)
|
||||
}
|
||||
|
||||
patch->bounds = b;
|
||||
pcfree(pt);
|
||||
pcfree(pt);
|
||||
return PC_SUCCESS;
|
||||
}
|
||||
|
||||
@ -336,7 +336,7 @@ pc_patch_uncompressed_from_dimensional(const PCPATCH_DIMENSIONAL *pdl)
|
||||
patch->npoints = npoints;
|
||||
patch->maxpoints = npoints;
|
||||
patch->bounds = pdl->bounds;
|
||||
patch->stats = pc_stats_clone(pdl->stats);
|
||||
patch->stats = pc_stats_clone(pdl->stats);
|
||||
patch->datasize = schema->size * pdl->npoints;
|
||||
patch->data = pcalloc(patch->datasize);
|
||||
buf = patch->data;
|
||||
|
||||
@ -354,15 +354,15 @@ pc_point_to_geometry_wkb(const PCPOINT *pt, size_t *wkbsize)
|
||||
|
||||
|
||||
/**
|
||||
* @brief this function convert a PCPOINT to an array of double containing
|
||||
* all the dimension values of this point
|
||||
*
|
||||
* @param a pointer to the point to convert to double
|
||||
*
|
||||
* @return a pointer to an array of double containing all the dimensions
|
||||
* of the point expressed as double precision
|
||||
*
|
||||
*/
|
||||
* @brief this function convert a PCPOINT to an array of double containing
|
||||
* all the dimension values of this point
|
||||
*
|
||||
* @param a pointer to the point to convert to double
|
||||
*
|
||||
* @return a pointer to an array of double containing all the dimensions
|
||||
* of the point expressed as double precision
|
||||
*
|
||||
*/
|
||||
double * pc_point_to_double_array(const PCPOINT *p)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -85,26 +85,26 @@ pc_interpretation_number(const char *str)
|
||||
}
|
||||
else
|
||||
return PC_UNKNOWN;
|
||||
|
||||
|
||||
return PC_UNKNOWN;
|
||||
}
|
||||
|
||||
const char*
|
||||
pc_compression_name(int num)
|
||||
{
|
||||
switch (num)
|
||||
{
|
||||
case PC_NONE:
|
||||
return "none";
|
||||
case PC_GHT:
|
||||
return "ght";
|
||||
case PC_DIMENSIONAL:
|
||||
return "dimensional";
|
||||
case PC_LAZPERF:
|
||||
return "laz";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
switch (num)
|
||||
{
|
||||
case PC_NONE:
|
||||
return "none";
|
||||
case PC_GHT:
|
||||
return "ght";
|
||||
case PC_DIMENSIONAL:
|
||||
return "dimensional";
|
||||
case PC_LAZPERF:
|
||||
return "laz";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
@ -113,26 +113,26 @@ pc_compression_number(const char *str)
|
||||
if ( ! str )
|
||||
return PC_NONE;
|
||||
|
||||
if ( (str[0] == 'd' || str[0] == 'D') &&
|
||||
(strcasecmp(str, "dimensional") == 0) )
|
||||
if ( (str[0] == 'd' || str[0] == 'D') &&
|
||||
(strcasecmp(str, "dimensional") == 0) )
|
||||
{
|
||||
return PC_DIMENSIONAL;
|
||||
}
|
||||
|
||||
if ( (str[0] == 'l' || str[0] == 'L') &&
|
||||
(strcasecmp(str, "laz") == 0) )
|
||||
if ( (str[0] == 'l' || str[0] == 'L') &&
|
||||
(strcasecmp(str, "laz") == 0) )
|
||||
{
|
||||
return PC_LAZPERF;
|
||||
}
|
||||
|
||||
if ( (str[0] == 'g' || str[0] == 'G') &&
|
||||
(strcasecmp(str, "ght") == 0) )
|
||||
if ( (str[0] == 'g' || str[0] == 'G') &&
|
||||
(strcasecmp(str, "ght") == 0) )
|
||||
{
|
||||
return PC_GHT;
|
||||
}
|
||||
|
||||
if ( (str[0] == 'n' || str[0] == 'N') &&
|
||||
(strcasecmp(str, "none") == 0) )
|
||||
if ( (str[0] == 'n' || str[0] == 'N') &&
|
||||
(strcasecmp(str, "none") == 0) )
|
||||
{
|
||||
return PC_NONE;
|
||||
}
|
||||
@ -333,16 +333,16 @@ void pc_schema_check_xy(PCSCHEMA *s)
|
||||
{
|
||||
char *dimname = s->dims[i]->name;
|
||||
if ( ! dimname ) continue;
|
||||
if ( strcasecmp(dimname, "X") == 0 ||
|
||||
strcasecmp(dimname, "Longitude") == 0 ||
|
||||
strcasecmp(dimname, "Lon") == 0 )
|
||||
if ( strcasecmp(dimname, "X") == 0 ||
|
||||
strcasecmp(dimname, "Longitude") == 0 ||
|
||||
strcasecmp(dimname, "Lon") == 0 )
|
||||
{
|
||||
s->x_position = i;
|
||||
continue;
|
||||
}
|
||||
if ( strcasecmp(dimname, "Y") == 0 ||
|
||||
strcasecmp(dimname, "Latitude") == 0 ||
|
||||
strcasecmp(dimname, "Lat") == 0 )
|
||||
if ( strcasecmp(dimname, "Y") == 0 ||
|
||||
strcasecmp(dimname, "Latitude") == 0 ||
|
||||
strcasecmp(dimname, "Lat") == 0 )
|
||||
{
|
||||
s->y_position = i;
|
||||
continue;
|
||||
@ -472,15 +472,15 @@ pc_schema_from_xml(const char *xml_str, PCSCHEMA **schema)
|
||||
char *name = (char*)(child->name);
|
||||
if ( strcmp(name, "name") == 0 )
|
||||
{
|
||||
if ( strcasecmp(content, "X") == 0 ||
|
||||
strcasecmp(content, "Longitude") == 0 ||
|
||||
strcasecmp(content, "Lon") == 0 )
|
||||
if ( strcasecmp(content, "X") == 0 ||
|
||||
strcasecmp(content, "Longitude") == 0 ||
|
||||
strcasecmp(content, "Lon") == 0 )
|
||||
{
|
||||
xydim = 'x';
|
||||
}
|
||||
if ( strcasecmp(content, "Y") == 0 ||
|
||||
strcasecmp(content, "Latitude") == 0 ||
|
||||
strcasecmp(content, "Lat") == 0 )
|
||||
if ( strcasecmp(content, "Y") == 0 ||
|
||||
strcasecmp(content, "Latitude") == 0 ||
|
||||
strcasecmp(content, "Lat") == 0 )
|
||||
{
|
||||
xydim = 'y';
|
||||
}
|
||||
@ -520,7 +520,7 @@ pc_schema_from_xml(const char *xml_str, PCSCHEMA **schema)
|
||||
xmlXPathFreeObject(xpath_obj);
|
||||
xmlXPathFreeContext(xpath_ctx);
|
||||
xmlFreeDoc(xml_doc);
|
||||
xmlCleanupParser();
|
||||
xmlCleanupParser();
|
||||
pc_schema_free(s);
|
||||
pcwarn("schema dimension at position \"%d\" is declared twice", d->position + 1, ndims);
|
||||
return PC_FAILURE;
|
||||
@ -541,7 +541,7 @@ pc_schema_from_xml(const char *xml_str, PCSCHEMA **schema)
|
||||
xmlXPathFreeContext(xpath_ctx);
|
||||
xmlFreeDoc(xml_doc);
|
||||
xmlCleanupParser();
|
||||
pc_schema_free(s);
|
||||
pc_schema_free(s);
|
||||
pcwarn("schema dimension states position \"%d\", but number of XML dimensions is \"%d\"", d->position + 1, ndims);
|
||||
return PC_FAILURE;
|
||||
}
|
||||
|
||||
354
lib/pc_sort.c
354
lib/pc_sort.c
@ -16,265 +16,265 @@
|
||||
typedef PCDIMENSION ** PCDIMENSION_LIST;
|
||||
|
||||
/**
|
||||
* Comparators
|
||||
*/
|
||||
* Comparators
|
||||
*/
|
||||
|
||||
int
|
||||
pc_compare_dim (const void *a, const void *b, void *arg)
|
||||
{
|
||||
PCDIMENSION_LIST dim = (PCDIMENSION_LIST)arg;
|
||||
uint32_t byteoffset = dim[0]->byteoffset;
|
||||
uint32_t interpretation = dim[0]->interpretation;
|
||||
double da = pc_double_from_ptr(a+byteoffset,interpretation);
|
||||
double db = pc_double_from_ptr(b+byteoffset,interpretation);
|
||||
int cmp = ((da > db) - (da < db));
|
||||
return ( cmp == 0 && dim[1]) ? pc_compare_dim(a,b,dim+1) : cmp;
|
||||
PCDIMENSION_LIST dim = (PCDIMENSION_LIST)arg;
|
||||
uint32_t byteoffset = dim[0]->byteoffset;
|
||||
uint32_t interpretation = dim[0]->interpretation;
|
||||
double da = pc_double_from_ptr(a+byteoffset,interpretation);
|
||||
double db = pc_double_from_ptr(b+byteoffset,interpretation);
|
||||
int cmp = ((da > db) - (da < db));
|
||||
return ( cmp == 0 && dim[1]) ? pc_compare_dim(a,b,dim+1) : cmp;
|
||||
}
|
||||
|
||||
int
|
||||
pc_compare_pcb (const void *a, const void *b, const void *arg)
|
||||
{
|
||||
PCBYTES *pcb = (PCBYTES *)arg;
|
||||
double da = pc_double_from_ptr(a,pcb->interpretation);
|
||||
double db = pc_double_from_ptr(b,pcb->interpretation);
|
||||
return ((da > db) - (da < db));
|
||||
PCBYTES *pcb = (PCBYTES *)arg;
|
||||
double da = pc_double_from_ptr(a,pcb->interpretation);
|
||||
double db = pc_double_from_ptr(b,pcb->interpretation);
|
||||
return ((da > db) - (da < db));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sort
|
||||
*/
|
||||
* Sort
|
||||
*/
|
||||
|
||||
PCPATCH_UNCOMPRESSED *
|
||||
pc_patch_uncompressed_sort(const PCPATCH_UNCOMPRESSED *pu, PCDIMENSION_LIST dim)
|
||||
{
|
||||
PCPATCH_UNCOMPRESSED *spu = pc_patch_uncompressed_make(pu->schema, pu->npoints);
|
||||
PCPATCH_UNCOMPRESSED *spu = pc_patch_uncompressed_make(pu->schema, pu->npoints);
|
||||
|
||||
memcpy(spu->data, pu->data, pu->datasize);
|
||||
spu->npoints = pu->npoints;
|
||||
spu->bounds = pu->bounds;
|
||||
spu->stats = pc_stats_clone(pu->stats);
|
||||
memcpy(spu->data, pu->data, pu->datasize);
|
||||
spu->npoints = pu->npoints;
|
||||
spu->bounds = pu->bounds;
|
||||
spu->stats = pc_stats_clone(pu->stats);
|
||||
|
||||
sort_r(spu->data, spu->npoints, pu->schema->size, pc_compare_dim, dim);
|
||||
sort_r(spu->data, spu->npoints, pu->schema->size, pc_compare_dim, dim);
|
||||
|
||||
return spu;
|
||||
return spu;
|
||||
}
|
||||
|
||||
PCDIMENSION_LIST pc_schema_get_dimensions_by_name(const PCSCHEMA *schema, const char ** name, int ndims)
|
||||
{
|
||||
PCDIMENSION_LIST dim = pcalloc( (ndims+1) * sizeof(PCDIMENSION *));
|
||||
int i;
|
||||
for(i=0; i<ndims; ++i)
|
||||
{
|
||||
dim[i] = pc_schema_get_dimension_by_name(schema, name[i]);
|
||||
if ( ! dim[i] ) {
|
||||
pcerror("dimension \"%s\" does not exist", name[i]);
|
||||
return NULL;
|
||||
}
|
||||
assert(dim[i]->scale>0);
|
||||
}
|
||||
dim[ndims] = NULL;
|
||||
return dim;
|
||||
PCDIMENSION_LIST dim = pcalloc( (ndims+1) * sizeof(PCDIMENSION *));
|
||||
int i;
|
||||
for(i=0; i<ndims; ++i)
|
||||
{
|
||||
dim[i] = pc_schema_get_dimension_by_name(schema, name[i]);
|
||||
if ( ! dim[i] ) {
|
||||
pcerror("dimension \"%s\" does not exist", name[i]);
|
||||
return NULL;
|
||||
}
|
||||
assert(dim[i]->scale>0);
|
||||
}
|
||||
dim[ndims] = NULL;
|
||||
return dim;
|
||||
}
|
||||
|
||||
PCPATCH *
|
||||
pc_patch_sort(const PCPATCH *pa, const char ** name, int ndims)
|
||||
{
|
||||
PCDIMENSION_LIST dim = pc_schema_get_dimensions_by_name(pa->schema, name, ndims);
|
||||
PCPATCH *pu = pc_patch_uncompress(pa);
|
||||
if ( !pu ) {
|
||||
pcfree(dim);
|
||||
pcerror("Patch uncompression failed");
|
||||
return NULL;
|
||||
}
|
||||
PCPATCH_UNCOMPRESSED *ps = pc_patch_uncompressed_sort((PCPATCH_UNCOMPRESSED *)pu, dim);
|
||||
|
||||
pcfree(dim);
|
||||
if ( pu != pa )
|
||||
pc_patch_free(pu);
|
||||
return (PCPATCH *) ps;
|
||||
PCDIMENSION_LIST dim = pc_schema_get_dimensions_by_name(pa->schema, name, ndims);
|
||||
PCPATCH *pu = pc_patch_uncompress(pa);
|
||||
if ( !pu ) {
|
||||
pcfree(dim);
|
||||
pcerror("Patch uncompression failed");
|
||||
return NULL;
|
||||
}
|
||||
PCPATCH_UNCOMPRESSED *ps = pc_patch_uncompressed_sort((PCPATCH_UNCOMPRESSED *)pu, dim);
|
||||
|
||||
pcfree(dim);
|
||||
if ( pu != pa )
|
||||
pc_patch_free(pu);
|
||||
return (PCPATCH *) ps;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* IsSorted
|
||||
*/
|
||||
* IsSorted
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
pc_patch_uncompressed_is_sorted(const PCPATCH_UNCOMPRESSED *pu, PCDIMENSION_LIST dim, char strict)
|
||||
{
|
||||
size_t size = pu->schema->size;
|
||||
uint8_t *buf = pu->data, *last = pu->data+pu->datasize-size;
|
||||
while ( buf < last )
|
||||
{
|
||||
if( pc_compare_dim(buf,buf+size,dim) >= strict )
|
||||
return PC_FALSE;
|
||||
buf += size;
|
||||
}
|
||||
return PC_TRUE;
|
||||
size_t size = pu->schema->size;
|
||||
uint8_t *buf = pu->data, *last = pu->data+pu->datasize-size;
|
||||
while ( buf < last )
|
||||
{
|
||||
if( pc_compare_dim(buf,buf+size,dim) >= strict )
|
||||
return PC_FALSE;
|
||||
buf += size;
|
||||
}
|
||||
return PC_TRUE;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
pc_bytes_uncompressed_is_sorted(const PCBYTES *pcb, char strict)
|
||||
{
|
||||
assert(pcb->compression == PC_DIM_NONE);
|
||||
size_t size = pc_interpretation_size(pcb->interpretation);
|
||||
uint8_t *buf = pcb->bytes;
|
||||
uint8_t *last = buf+pcb->size-size;
|
||||
while ( buf < last )
|
||||
{
|
||||
if( pc_compare_pcb(buf,buf+size,pcb) >= strict )
|
||||
return PC_FALSE;
|
||||
buf += size;
|
||||
}
|
||||
return PC_TRUE;
|
||||
assert(pcb->compression == PC_DIM_NONE);
|
||||
size_t size = pc_interpretation_size(pcb->interpretation);
|
||||
uint8_t *buf = pcb->bytes;
|
||||
uint8_t *last = buf+pcb->size-size;
|
||||
while ( buf < last )
|
||||
{
|
||||
if( pc_compare_pcb(buf,buf+size,pcb) >= strict )
|
||||
return PC_FALSE;
|
||||
buf += size;
|
||||
}
|
||||
return PC_TRUE;
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
pc_bytes_sigbits_is_sorted(const PCBYTES *pcb, char strict)
|
||||
{
|
||||
assert(pcb->compression == PC_DIM_SIGBITS);
|
||||
pcinfo("%s not implemented, decoding",__func__);
|
||||
PCBYTES dpcb = pc_bytes_decode(*pcb);
|
||||
uint32_t is_sorted = pc_bytes_uncompressed_is_sorted(&dpcb,strict);
|
||||
pc_bytes_free(dpcb);
|
||||
return is_sorted;
|
||||
assert(pcb->compression == PC_DIM_SIGBITS);
|
||||
pcinfo("%s not implemented, decoding",__func__);
|
||||
PCBYTES dpcb = pc_bytes_decode(*pcb);
|
||||
uint32_t is_sorted = pc_bytes_uncompressed_is_sorted(&dpcb,strict);
|
||||
pc_bytes_free(dpcb);
|
||||
return is_sorted;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
pc_bytes_zlib_is_sorted(const PCBYTES *pcb, char strict)
|
||||
{
|
||||
assert(pcb->compression == PC_DIM_ZLIB);
|
||||
pcinfo("%s not implemented, decoding",__func__);
|
||||
PCBYTES dpcb = pc_bytes_decode(*pcb);
|
||||
uint32_t is_sorted = pc_bytes_uncompressed_is_sorted(&dpcb,strict);
|
||||
pc_bytes_free(dpcb);
|
||||
return is_sorted;
|
||||
assert(pcb->compression == PC_DIM_ZLIB);
|
||||
pcinfo("%s not implemented, decoding",__func__);
|
||||
PCBYTES dpcb = pc_bytes_decode(*pcb);
|
||||
uint32_t is_sorted = pc_bytes_uncompressed_is_sorted(&dpcb,strict);
|
||||
pc_bytes_free(dpcb);
|
||||
return is_sorted;
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
pc_bytes_run_length_is_sorted(const PCBYTES *pcb, char strict)
|
||||
{
|
||||
assert(pcb->compression == PC_DIM_RLE);
|
||||
uint8_t run;
|
||||
size_t size = pc_interpretation_size(pcb->interpretation);
|
||||
const uint8_t *bytes_rle_curr_val = pcb->bytes + 1;
|
||||
const uint8_t *bytes_rle_next_val = pcb->bytes + 2 + size;
|
||||
const uint8_t *bytes_rle_end_val = pcb->bytes + pcb->size - size;
|
||||
while( bytes_rle_next_val < bytes_rle_end_val )
|
||||
{
|
||||
run = bytes_rle_curr_val[-1];
|
||||
assert(run>0);
|
||||
if( pc_compare_pcb(bytes_rle_curr_val,bytes_rle_next_val,pcb) >= strict // value comparison
|
||||
|| (strict && run > 1) ) // run_length should be 1 if strict
|
||||
return PC_FALSE;
|
||||
bytes_rle_curr_val = bytes_rle_next_val;
|
||||
bytes_rle_next_val += 1 + size;
|
||||
}
|
||||
return PC_TRUE;
|
||||
assert(pcb->compression == PC_DIM_RLE);
|
||||
uint8_t run;
|
||||
size_t size = pc_interpretation_size(pcb->interpretation);
|
||||
const uint8_t *bytes_rle_curr_val = pcb->bytes + 1;
|
||||
const uint8_t *bytes_rle_next_val = pcb->bytes + 2 + size;
|
||||
const uint8_t *bytes_rle_end_val = pcb->bytes + pcb->size - size;
|
||||
while( bytes_rle_next_val < bytes_rle_end_val )
|
||||
{
|
||||
run = bytes_rle_curr_val[-1];
|
||||
assert(run>0);
|
||||
if( pc_compare_pcb(bytes_rle_curr_val,bytes_rle_next_val,pcb) >= strict // value comparison
|
||||
|| (strict && run > 1) ) // run_length should be 1 if strict
|
||||
return PC_FALSE;
|
||||
bytes_rle_curr_val = bytes_rle_next_val;
|
||||
bytes_rle_next_val += 1 + size;
|
||||
}
|
||||
return PC_TRUE;
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
pc_patch_dimensional_is_sorted(const PCPATCH_DIMENSIONAL *pdl, PCDIMENSION_LIST dim, char strict)
|
||||
{
|
||||
assert(pdl);
|
||||
assert(pdl->schema);
|
||||
assert(pdl);
|
||||
assert(pdl->schema);
|
||||
|
||||
// uncompress when checking multiple dimensions
|
||||
if(dim[1])
|
||||
{
|
||||
PCPATCH_UNCOMPRESSED *pu = pc_patch_uncompressed_from_dimensional(pdl);
|
||||
if ( !pu ) {
|
||||
pcerror("Patch uncompression failed");
|
||||
return PC_FAILURE - 1; // aliasing issue : PC_FALSE == PC_FAILURE...
|
||||
}
|
||||
uint32_t is_sorted = pc_patch_uncompressed_is_sorted(pu,dim,strict);
|
||||
pc_patch_free((PCPATCH *)pu);
|
||||
return is_sorted;
|
||||
}
|
||||
// uncompress when checking multiple dimensions
|
||||
if(dim[1])
|
||||
{
|
||||
PCPATCH_UNCOMPRESSED *pu = pc_patch_uncompressed_from_dimensional(pdl);
|
||||
if ( !pu ) {
|
||||
pcerror("Patch uncompression failed");
|
||||
return PC_FAILURE - 1; // aliasing issue : PC_FALSE == PC_FAILURE...
|
||||
}
|
||||
uint32_t is_sorted = pc_patch_uncompressed_is_sorted(pu,dim,strict);
|
||||
pc_patch_free((PCPATCH *)pu);
|
||||
return is_sorted;
|
||||
}
|
||||
|
||||
PCBYTES *pcb = pdl->bytes + dim[0]->position;
|
||||
switch ( pcb->compression )
|
||||
{
|
||||
case PC_DIM_RLE:
|
||||
{
|
||||
return pc_bytes_run_length_is_sorted(pcb,strict);
|
||||
}
|
||||
case PC_DIM_SIGBITS:
|
||||
{
|
||||
return pc_bytes_sigbits_is_sorted(pcb,strict);
|
||||
}
|
||||
case PC_DIM_ZLIB:
|
||||
{
|
||||
return pc_bytes_zlib_is_sorted(pcb,strict);
|
||||
}
|
||||
case PC_DIM_NONE:
|
||||
{
|
||||
return pc_bytes_uncompressed_is_sorted(pcb,strict);
|
||||
}
|
||||
default:
|
||||
{
|
||||
pcerror("%s: Uh oh", __func__);
|
||||
}
|
||||
}
|
||||
return PC_FAILURE - 1; // aliasing issue : PC_FALSE == PC_FAILURE...
|
||||
PCBYTES *pcb = pdl->bytes + dim[0]->position;
|
||||
switch ( pcb->compression )
|
||||
{
|
||||
case PC_DIM_RLE:
|
||||
{
|
||||
return pc_bytes_run_length_is_sorted(pcb,strict);
|
||||
}
|
||||
case PC_DIM_SIGBITS:
|
||||
{
|
||||
return pc_bytes_sigbits_is_sorted(pcb,strict);
|
||||
}
|
||||
case PC_DIM_ZLIB:
|
||||
{
|
||||
return pc_bytes_zlib_is_sorted(pcb,strict);
|
||||
}
|
||||
case PC_DIM_NONE:
|
||||
{
|
||||
return pc_bytes_uncompressed_is_sorted(pcb,strict);
|
||||
}
|
||||
default:
|
||||
{
|
||||
pcerror("%s: Uh oh", __func__);
|
||||
}
|
||||
}
|
||||
return PC_FAILURE - 1; // aliasing issue : PC_FALSE == PC_FAILURE...
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
pc_patch_ght_is_sorted(const PCPATCH_GHT *pa, PCDIMENSION_LIST dim, char strict)
|
||||
{
|
||||
PCPATCH_UNCOMPRESSED *pu = pc_patch_uncompressed_from_ght(pa);
|
||||
if ( !pu ) {
|
||||
pcerror("Patch uncompression failed");
|
||||
return PC_FAILURE - 1; // aliasing issue : PC_FALSE == PC_FAILURE...
|
||||
}
|
||||
uint32_t is_sorted = pc_patch_uncompressed_is_sorted(pu,dim,strict);
|
||||
pc_patch_free((PCPATCH*)pu);
|
||||
return is_sorted;
|
||||
PCPATCH_UNCOMPRESSED *pu = pc_patch_uncompressed_from_ght(pa);
|
||||
if ( !pu ) {
|
||||
pcerror("Patch uncompression failed");
|
||||
return PC_FAILURE - 1; // aliasing issue : PC_FALSE == PC_FAILURE...
|
||||
}
|
||||
uint32_t is_sorted = pc_patch_uncompressed_is_sorted(pu,dim,strict);
|
||||
pc_patch_free((PCPATCH*)pu);
|
||||
return is_sorted;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
pc_patch_lazperf_is_sorted(const PCPATCH_LAZPERF *pa, PCDIMENSION_LIST dim, char strict)
|
||||
{
|
||||
PCPATCH_UNCOMPRESSED *pu = pc_patch_uncompressed_from_lazperf(pa);
|
||||
if ( !pu ) {
|
||||
pcerror("Patch uncompression failed");
|
||||
return PC_FAILURE - 1; // aliasing issue : PC_FALSE == PC_FAILURE...
|
||||
}
|
||||
uint32_t is_sorted = pc_patch_uncompressed_is_sorted(pu,dim,strict);
|
||||
pc_patch_free((PCPATCH*) pu);
|
||||
return is_sorted;
|
||||
PCPATCH_UNCOMPRESSED *pu = pc_patch_uncompressed_from_lazperf(pa);
|
||||
if ( !pu ) {
|
||||
pcerror("Patch uncompression failed");
|
||||
return PC_FAILURE - 1; // aliasing issue : PC_FALSE == PC_FAILURE...
|
||||
}
|
||||
uint32_t is_sorted = pc_patch_uncompressed_is_sorted(pu,dim,strict);
|
||||
pc_patch_free((PCPATCH*) pu);
|
||||
return is_sorted;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
pc_patch_is_sorted(const PCPATCH *pa, const char **name, int ndims, char strict)
|
||||
{
|
||||
int is_sorted = PC_FAILURE -1; // aliasing issue : PC_FALSE == PC_FAILURE...
|
||||
PCDIMENSION_LIST dim = pc_schema_get_dimensions_by_name(pa->schema, name, ndims);
|
||||
if ( ! dim ) return is_sorted;
|
||||
strict = (strict > 0); // ensure 0-1 value
|
||||
int is_sorted = PC_FAILURE -1; // aliasing issue : PC_FALSE == PC_FAILURE...
|
||||
PCDIMENSION_LIST dim = pc_schema_get_dimensions_by_name(pa->schema, name, ndims);
|
||||
if ( ! dim ) return is_sorted;
|
||||
strict = (strict > 0); // ensure 0-1 value
|
||||
|
||||
switch( pa->type )
|
||||
{
|
||||
case PC_NONE:
|
||||
is_sorted = pc_patch_uncompressed_is_sorted((PCPATCH_UNCOMPRESSED*)pa,dim,strict);
|
||||
break;
|
||||
case PC_DIMENSIONAL:
|
||||
is_sorted = pc_patch_dimensional_is_sorted((PCPATCH_DIMENSIONAL*)pa,dim,strict);
|
||||
break;
|
||||
case PC_GHT:
|
||||
is_sorted = pc_patch_ght_is_sorted((PCPATCH_GHT*)pa,dim,strict);
|
||||
break;
|
||||
case PC_LAZPERF:
|
||||
is_sorted = pc_patch_lazperf_is_sorted((PCPATCH_LAZPERF*)pa,dim,strict);
|
||||
break;
|
||||
default:
|
||||
pcerror("%s: unsupported compression %d requested", __func__, pa->type);
|
||||
}
|
||||
pcfree(dim);
|
||||
return is_sorted;
|
||||
switch( pa->type )
|
||||
{
|
||||
case PC_NONE:
|
||||
is_sorted = pc_patch_uncompressed_is_sorted((PCPATCH_UNCOMPRESSED*)pa,dim,strict);
|
||||
break;
|
||||
case PC_DIMENSIONAL:
|
||||
is_sorted = pc_patch_dimensional_is_sorted((PCPATCH_DIMENSIONAL*)pa,dim,strict);
|
||||
break;
|
||||
case PC_GHT:
|
||||
is_sorted = pc_patch_ght_is_sorted((PCPATCH_GHT*)pa,dim,strict);
|
||||
break;
|
||||
case PC_LAZPERF:
|
||||
is_sorted = pc_patch_lazperf_is_sorted((PCPATCH_LAZPERF*)pa,dim,strict);
|
||||
break;
|
||||
default:
|
||||
pcerror("%s: unsupported compression %d requested", __func__, pa->type);
|
||||
}
|
||||
pcfree(dim);
|
||||
return is_sorted;
|
||||
}
|
||||
|
||||
@ -95,13 +95,13 @@ hexbytes_from_bytes(const uint8_t *bytebuf, size_t bytesize)
|
||||
}
|
||||
|
||||
|
||||
/* 0 = xdr | big endian */
|
||||
/* 1 = ndr | little endian */
|
||||
char
|
||||
machine_endian(void)
|
||||
{
|
||||
static int check_int = 1; /* dont modify this!!! */
|
||||
return *((char *) &check_int); /* 0 = big endian | xdr,
|
||||
* 1 = little endian | ndr
|
||||
*/
|
||||
return *((char *) &check_int);
|
||||
}
|
||||
|
||||
int32_t
|
||||
@ -238,10 +238,10 @@ uncompressed_bytes_flip_endian(const uint8_t *bytebuf, const PCSCHEMA *schema, u
|
||||
int
|
||||
pc_bounds_intersects(const PCBOUNDS *b1, const PCBOUNDS *b2)
|
||||
{
|
||||
if ( b1->xmin > b2->xmax ||
|
||||
b1->xmax < b2->xmin ||
|
||||
b1->ymin > b2->ymax ||
|
||||
b1->ymax < b2->ymin )
|
||||
if ( b1->xmin > b2->xmax ||
|
||||
b1->xmax < b2->xmin ||
|
||||
b1->ymin > b2->ymax ||
|
||||
b1->ymax < b2->ymin )
|
||||
{
|
||||
return PC_FALSE;
|
||||
}
|
||||
|
||||
16
lib/pc_val.c
16
lib/pc_val.c
@ -122,14 +122,14 @@ pc_double_from_ptr(const uint8_t *ptr, uint32_t interpretation)
|
||||
}
|
||||
|
||||
#define CLAMP(v,min,max,t,format) do { \
|
||||
if ( v > max ) { \
|
||||
pcwarn("Value %g truncated to "format" to fit in "t, v, max); \
|
||||
v = max; \
|
||||
} else if ( v < min ) { \
|
||||
pcwarn("Value %g truncated to "format" to fit in "t, v, min); \
|
||||
v = min; \
|
||||
} \
|
||||
} while(0)
|
||||
if ( v > max ) { \
|
||||
pcwarn("Value %g truncated to "format" to fit in "t, v, max); \
|
||||
v = max; \
|
||||
} else if ( v < min ) { \
|
||||
pcwarn("Value %g truncated to "format" to fit in "t, v, min); \
|
||||
v = min; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
int
|
||||
pc_double_to_ptr(uint8_t *ptr, uint32_t interpretation, double val)
|
||||
|
||||
@ -1,40 +1,40 @@
|
||||
/**********************************************************************
|
||||
* stringbuffer.c
|
||||
*
|
||||
* Copyright 2002 Thamer Alharbash
|
||||
* Copyright 2009 Paul Ramsey <pramsey@cleverelephant.ca>
|
||||
* Copyright 2015 Sandro Santilli <strk@keybit.net>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
**********************************************************************/
|
||||
* stringbuffer.c
|
||||
*
|
||||
* Copyright 2002 Thamer Alharbash
|
||||
* Copyright 2009 Paul Ramsey <pramsey@cleverelephant.ca>
|
||||
* Copyright 2015 Sandro Santilli <strk@keybit.net>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
#include "stringbuffer.h"
|
||||
|
||||
@ -150,10 +150,10 @@ stringbuffer_getstring(stringbuffer_t *s)
|
||||
char*
|
||||
stringbuffer_release_string(stringbuffer_t *s)
|
||||
{
|
||||
char *ret = s->str_start;
|
||||
s->str_start = s->str_end = NULL;
|
||||
s->capacity = 0;
|
||||
return ret;
|
||||
char *ret = s->str_start;
|
||||
s->str_start = s->str_end = NULL;
|
||||
s->capacity = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,40 +1,40 @@
|
||||
/**********************************************************************
|
||||
* stringbuffer.h
|
||||
*
|
||||
* Copyright 2002 Thamer Alharbash
|
||||
* Copyright 2009 Paul Ramsey <pramsey@cleverelephant.ca>
|
||||
* Copyright 2015 Sandro Santilli <strk@keybit.net>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
**********************************************************************/
|
||||
* stringbuffer.h
|
||||
*
|
||||
* Copyright 2002 Thamer Alharbash
|
||||
* Copyright 2009 Paul Ramsey <pramsey@cleverelephant.ca>
|
||||
* Copyright 2015 Sandro Santilli <strk@keybit.net>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef _STRINGBUFFER_H
|
||||
#define _STRINGBUFFER_H 1
|
||||
|
||||
@ -1,41 +1,41 @@
|
||||
{
|
||||
"name": "pointcloud",
|
||||
"abstract": "LIDAR data support type and functions",
|
||||
"description": "Point and Patch types for LIDAR storage. Aggregate and access functions. JSON and binary serializations. Compression.",
|
||||
"version": "1.0.0",
|
||||
"release_status": "unstable",
|
||||
"maintainer": "Paul Ramsey",
|
||||
"license": "bsd",
|
||||
"provides": {
|
||||
"pointcloud": {
|
||||
"abstract": "LIDAR point and patch types and functions",
|
||||
"version": "1.0.0",
|
||||
"file": "",
|
||||
"docfile": ""
|
||||
}
|
||||
}
|
||||
"prereqs": {
|
||||
"runtime": {
|
||||
"requires": {
|
||||
}
|
||||
}
|
||||
},
|
||||
"generated_by": "Paul Ramsey",
|
||||
"resources": {
|
||||
"bugtracker": {
|
||||
"web": "http://github.com/pramsey/pointcloud"
|
||||
},
|
||||
"repository": {
|
||||
"url": "",
|
||||
"web": "http://github.com/pramsey/pointcloud",
|
||||
"type": "git"
|
||||
}
|
||||
},
|
||||
"meta-spec": {
|
||||
"version": "1.0.0",
|
||||
"url": "http://pgxn.org/meta/spec.txt"
|
||||
},
|
||||
"tags": [
|
||||
"gis", "lidar"
|
||||
]
|
||||
}
|
||||
{
|
||||
"name": "pointcloud",
|
||||
"abstract": "LIDAR data support type and functions",
|
||||
"description": "Point and Patch types for LIDAR storage. Aggregate and access functions. JSON and binary serializations. Compression.",
|
||||
"version": "1.0.0",
|
||||
"release_status": "unstable",
|
||||
"maintainer": "Paul Ramsey",
|
||||
"license": "bsd",
|
||||
"provides": {
|
||||
"pointcloud": {
|
||||
"abstract": "LIDAR point and patch types and functions",
|
||||
"version": "1.0.0",
|
||||
"file": "",
|
||||
"docfile": ""
|
||||
}
|
||||
}
|
||||
"prereqs": {
|
||||
"runtime": {
|
||||
"requires": {
|
||||
}
|
||||
}
|
||||
},
|
||||
"generated_by": "Paul Ramsey",
|
||||
"resources": {
|
||||
"bugtracker": {
|
||||
"web": "http://github.com/pramsey/pointcloud"
|
||||
},
|
||||
"repository": {
|
||||
"url": "",
|
||||
"web": "http://github.com/pramsey/pointcloud",
|
||||
"type": "git"
|
||||
}
|
||||
},
|
||||
"meta-spec": {
|
||||
"version": "1.0.0",
|
||||
"url": "http://pgxn.org/meta/spec.txt"
|
||||
},
|
||||
"tags": [
|
||||
"gis", "lidar"
|
||||
]
|
||||
}
|
||||
|
||||
@ -105,13 +105,13 @@ Datum pcpoint_get_values(PG_FUNCTION_ARGS)
|
||||
pt = pc_point_deserialize(serpt, schema);
|
||||
if ( ! pt ) PG_RETURN_NULL();
|
||||
|
||||
elems = (Datum * )palloc(schema->ndims * sizeof(Datum) );
|
||||
vals = pc_point_to_double_array(pt);
|
||||
i = schema->ndims;
|
||||
while (i--) elems[i] = Float8GetDatum(vals[i]);
|
||||
pcfree(vals);
|
||||
result = construct_array(elems, schema->ndims, FLOAT8OID,
|
||||
sizeof(float8), FLOAT8PASSBYVAL, 'd');
|
||||
elems = (Datum * )palloc(schema->ndims * sizeof(Datum) );
|
||||
vals = pc_point_to_double_array(pt);
|
||||
i = schema->ndims;
|
||||
while (i--) elems[i] = Float8GetDatum(vals[i]);
|
||||
pcfree(vals);
|
||||
result = construct_array(elems, schema->ndims, FLOAT8OID,
|
||||
sizeof(float8), FLOAT8PASSBYVAL, 'd');
|
||||
|
||||
pc_point_free(pt);
|
||||
PG_RETURN_ARRAYTYPE_P(result);
|
||||
@ -333,7 +333,7 @@ PG_FUNCTION_INFO_V1(pointcloud_abs_in);
|
||||
Datum pointcloud_abs_in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ereport(ERROR,(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("function pointcloud_abs_in not implemented")));
|
||||
errmsg("function pointcloud_abs_in not implemented")));
|
||||
PG_RETURN_POINTER(NULL);
|
||||
}
|
||||
|
||||
@ -341,7 +341,7 @@ PG_FUNCTION_INFO_V1(pointcloud_abs_out);
|
||||
Datum pointcloud_abs_out(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ereport(ERROR,(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("function pointcloud_abs_out not implemented")));
|
||||
errmsg("function pointcloud_abs_out not implemented")));
|
||||
PG_RETURN_POINTER(NULL);
|
||||
}
|
||||
|
||||
@ -357,8 +357,8 @@ Datum pointcloud_agg_transfn(PG_FUNCTION_ARGS)
|
||||
|
||||
if (arg1_typeid == InvalidOid)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("could not determine input data type")));
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("could not determine input data type")));
|
||||
|
||||
if ( ! AggCheckCallContext(fcinfo, &aggcontext) )
|
||||
{
|
||||
@ -379,10 +379,10 @@ Datum pointcloud_agg_transfn(PG_FUNCTION_ARGS)
|
||||
state = a->s;
|
||||
elem = PG_ARGISNULL(1) ? (Datum) 0 : PG_GETARG_DATUM(1);
|
||||
state = accumArrayResult(state,
|
||||
elem,
|
||||
PG_ARGISNULL(1),
|
||||
arg1_typeid,
|
||||
aggcontext);
|
||||
elem,
|
||||
PG_ARGISNULL(1),
|
||||
arg1_typeid,
|
||||
aggcontext);
|
||||
a->s = state;
|
||||
|
||||
PG_RETURN_POINTER(a);
|
||||
@ -568,87 +568,87 @@ Datum pcpatch_uncompress(PG_FUNCTION_ARGS)
|
||||
PG_FUNCTION_INFO_V1(pcpatch_compress);
|
||||
Datum pcpatch_compress(PG_FUNCTION_ARGS)
|
||||
{
|
||||
SERIALIZED_PATCH *serpa = PG_GETARG_SERPATCH_P(0);
|
||||
text *compr_in_text = PG_GETARG_TEXT_P(1);
|
||||
char *compr_in = text_to_cstring(compr_in_text);
|
||||
text *config_in_text = PG_GETARG_TEXT_P(2);
|
||||
char *config_in = text_to_cstring(config_in_text);
|
||||
PCSCHEMA *schema = pc_schema_from_pcid(serpa->pcid, fcinfo);
|
||||
PCPATCH *patch_in = pc_patch_deserialize(serpa, schema);
|
||||
PCPATCH *pa = patch_in;
|
||||
SERIALIZED_PATCH *serpa_out;
|
||||
PCDIMSTATS *stats = NULL;
|
||||
int i;
|
||||
SERIALIZED_PATCH *serpa = PG_GETARG_SERPATCH_P(0);
|
||||
text *compr_in_text = PG_GETARG_TEXT_P(1);
|
||||
char *compr_in = text_to_cstring(compr_in_text);
|
||||
text *config_in_text = PG_GETARG_TEXT_P(2);
|
||||
char *config_in = text_to_cstring(config_in_text);
|
||||
PCSCHEMA *schema = pc_schema_from_pcid(serpa->pcid, fcinfo);
|
||||
PCPATCH *patch_in = pc_patch_deserialize(serpa, schema);
|
||||
PCPATCH *pa = patch_in;
|
||||
SERIALIZED_PATCH *serpa_out;
|
||||
PCDIMSTATS *stats = NULL;
|
||||
int i;
|
||||
|
||||
/* Uncompress first */
|
||||
if ( patch_in->type != PC_NONE ) {
|
||||
pa = pc_patch_uncompress(patch_in);
|
||||
}
|
||||
/* Uncompress first */
|
||||
if ( patch_in->type != PC_NONE ) {
|
||||
pa = pc_patch_uncompress(patch_in);
|
||||
}
|
||||
|
||||
schema = pc_schema_clone(schema); /* we're going to modify it */
|
||||
schema = pc_schema_clone(schema); /* we're going to modify it */
|
||||
|
||||
/* Set compression scheme */
|
||||
if ( *compr_in == '\0' || strcasecmp(compr_in, "auto") == 0 ) {
|
||||
/* keep schema defined compression */
|
||||
}
|
||||
else if ( strcmp(compr_in, "dimensional") == 0 ) {{
|
||||
char *ptr = config_in;
|
||||
PCPATCH_DIMENSIONAL *pdl = pc_patch_dimensional_from_uncompressed((PCPATCH_UNCOMPRESSED*)pa);
|
||||
schema->compression = PC_DIMENSIONAL;
|
||||
stats = pc_dimstats_make(schema);
|
||||
pc_dimstats_update(stats, pdl);
|
||||
/* make sure to avoid stat updates (not sure if needed) */
|
||||
stats->total_points = PCDIMSTATS_MIN_SAMPLE+1;
|
||||
/* Set compression scheme */
|
||||
if ( *compr_in == '\0' || strcasecmp(compr_in, "auto") == 0 ) {
|
||||
/* keep schema defined compression */
|
||||
}
|
||||
else if ( strcmp(compr_in, "dimensional") == 0 ) {{
|
||||
char *ptr = config_in;
|
||||
PCPATCH_DIMENSIONAL *pdl = pc_patch_dimensional_from_uncompressed((PCPATCH_UNCOMPRESSED*)pa);
|
||||
schema->compression = PC_DIMENSIONAL;
|
||||
stats = pc_dimstats_make(schema);
|
||||
pc_dimstats_update(stats, pdl);
|
||||
/* make sure to avoid stat updates (not sure if needed) */
|
||||
stats->total_points = PCDIMSTATS_MIN_SAMPLE+1;
|
||||
|
||||
|
||||
/* Fill in per-dimension compression */
|
||||
if ( *ptr )
|
||||
for (i=0; i<stats->ndims; ++i) {
|
||||
PCDIMSTAT *stat = &(stats->stats[i]);
|
||||
/*pcinfo("ptr: %s", ptr);*/
|
||||
if ( *ptr == ',' || strncmp(ptr, "auto", strlen("auto")) == 0 ) {
|
||||
/* leave auto-determined compression */
|
||||
}
|
||||
else if ( strncmp(ptr, "rle", strlen("rle")) == 0 ) {
|
||||
stat->recommended_compression = PC_DIM_RLE;
|
||||
}
|
||||
else if ( strncmp(ptr, "sigbits", strlen("sigbits")) == 0 ) {
|
||||
stat->recommended_compression = PC_DIM_SIGBITS;
|
||||
}
|
||||
else if ( strncmp(ptr, "zlib", strlen("zlib")) == 0 ) {
|
||||
stat->recommended_compression = PC_DIM_ZLIB;
|
||||
}
|
||||
else {
|
||||
elog(ERROR, "Unrecognized dimensional compression '%s'. Please specify 'auto', 'rle', 'sigbits' or 'zlib'", ptr);
|
||||
}
|
||||
while (*ptr && *ptr != ',') ++ptr;
|
||||
if ( ! *ptr ) break;
|
||||
else ++ptr;
|
||||
}
|
||||
/* Fill in per-dimension compression */
|
||||
if ( *ptr )
|
||||
for (i=0; i<stats->ndims; ++i) {
|
||||
PCDIMSTAT *stat = &(stats->stats[i]);
|
||||
/*pcinfo("ptr: %s", ptr);*/
|
||||
if ( *ptr == ',' || strncmp(ptr, "auto", strlen("auto")) == 0 ) {
|
||||
/* leave auto-determined compression */
|
||||
}
|
||||
else if ( strncmp(ptr, "rle", strlen("rle")) == 0 ) {
|
||||
stat->recommended_compression = PC_DIM_RLE;
|
||||
}
|
||||
else if ( strncmp(ptr, "sigbits", strlen("sigbits")) == 0 ) {
|
||||
stat->recommended_compression = PC_DIM_SIGBITS;
|
||||
}
|
||||
else if ( strncmp(ptr, "zlib", strlen("zlib")) == 0 ) {
|
||||
stat->recommended_compression = PC_DIM_ZLIB;
|
||||
}
|
||||
else {
|
||||
elog(ERROR, "Unrecognized dimensional compression '%s'. Please specify 'auto', 'rle', 'sigbits' or 'zlib'", ptr);
|
||||
}
|
||||
while (*ptr && *ptr != ',') ++ptr;
|
||||
if ( ! *ptr ) break;
|
||||
else ++ptr;
|
||||
}
|
||||
|
||||
if ( pa != patch_in ) pc_patch_free(pa);
|
||||
pa = (PCPATCH*)pc_patch_dimensional_compress(pdl, stats);
|
||||
pc_patch_dimensional_free(pdl);
|
||||
}}
|
||||
else if ( strcmp(compr_in, "ght") == 0 ) {
|
||||
schema->compression = PC_GHT;
|
||||
}
|
||||
else if ( strcmp(compr_in, "laz") == 0 ) {
|
||||
schema->compression = PC_LAZPERF;
|
||||
}
|
||||
else {
|
||||
elog(ERROR, "Unrecognized compression '%s'. Please specify 'auto','dimensional' or 'ght'", compr_in);
|
||||
}
|
||||
if ( pa != patch_in ) pc_patch_free(pa);
|
||||
pa = (PCPATCH*)pc_patch_dimensional_compress(pdl, stats);
|
||||
pc_patch_dimensional_free(pdl);
|
||||
}}
|
||||
else if ( strcmp(compr_in, "ght") == 0 ) {
|
||||
schema->compression = PC_GHT;
|
||||
}
|
||||
else if ( strcmp(compr_in, "laz") == 0 ) {
|
||||
schema->compression = PC_LAZPERF;
|
||||
}
|
||||
else {
|
||||
elog(ERROR, "Unrecognized compression '%s'. Please specify 'auto','dimensional' or 'ght'", compr_in);
|
||||
}
|
||||
|
||||
pa->schema = schema; /* install overridden schema */
|
||||
serpa_out = pc_patch_serialize(pa, stats);
|
||||
pa->schema = schema; /* install overridden schema */
|
||||
serpa_out = pc_patch_serialize(pa, stats);
|
||||
|
||||
if ( pa != patch_in )
|
||||
pc_patch_free(pa);
|
||||
pc_patch_free(patch_in);
|
||||
pc_schema_free(schema);
|
||||
if ( pa != patch_in )
|
||||
pc_patch_free(pa);
|
||||
pc_patch_free(patch_in);
|
||||
pc_schema_free(schema);
|
||||
|
||||
PG_RETURN_POINTER(serpa_out);
|
||||
PG_RETURN_POINTER(serpa_out);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(pcpatch_numpoints);
|
||||
@ -687,99 +687,99 @@ Datum pcpatch_pcid(PG_FUNCTION_ARGS)
|
||||
PG_FUNCTION_INFO_V1(pcpatch_summary);
|
||||
Datum pcpatch_summary(PG_FUNCTION_ARGS)
|
||||
{
|
||||
const int stats_size_guess = 400;
|
||||
SERIALIZED_PATCH *serpa;
|
||||
PCSCHEMA *schema;
|
||||
PCSTATS *stats;
|
||||
PCPATCH *patch = NULL;
|
||||
StringInfoData strdata;
|
||||
text *ret;
|
||||
const char *comma = "";
|
||||
int i;
|
||||
const int stats_size_guess = 400;
|
||||
SERIALIZED_PATCH *serpa;
|
||||
PCSCHEMA *schema;
|
||||
PCSTATS *stats;
|
||||
PCPATCH *patch = NULL;
|
||||
StringInfoData strdata;
|
||||
text *ret;
|
||||
const char *comma = "";
|
||||
int i;
|
||||
|
||||
serpa = PG_GETHEADERX_SERPATCH_P(0, stats_size_guess);
|
||||
schema = pc_schema_from_pcid(serpa->pcid, fcinfo);
|
||||
if ( serpa->compression == PC_DIMENSIONAL )
|
||||
{
|
||||
/* need full data to inspect per-dimension compression */
|
||||
/* NOTE: memory usage could be optimized to only fetch slices
|
||||
* at specific offsets, but doesn't seem worth at this time
|
||||
* See https://github.com/pgpointcloud/pointcloud/pull/51#issuecomment-83592363
|
||||
*/
|
||||
serpa = PG_GETARG_SERPATCH_P(0);
|
||||
patch = pc_patch_deserialize(serpa, schema);
|
||||
}
|
||||
else if ( stats_size_guess < pc_stats_size(schema) )
|
||||
{
|
||||
/* only need stats here */
|
||||
serpa = PG_GETHEADERX_SERPATCH_P(0, pc_stats_size(schema));
|
||||
}
|
||||
stats = pc_patch_stats_deserialize(schema, serpa->data);
|
||||
serpa = PG_GETHEADERX_SERPATCH_P(0, stats_size_guess);
|
||||
schema = pc_schema_from_pcid(serpa->pcid, fcinfo);
|
||||
if ( serpa->compression == PC_DIMENSIONAL )
|
||||
{
|
||||
/* need full data to inspect per-dimension compression */
|
||||
/* NOTE: memory usage could be optimized to only fetch slices
|
||||
* at specific offsets, but doesn't seem worth at this time
|
||||
* See https://github.com/pgpointcloud/pointcloud/pull/51#issuecomment-83592363
|
||||
*/
|
||||
serpa = PG_GETARG_SERPATCH_P(0);
|
||||
patch = pc_patch_deserialize(serpa, schema);
|
||||
}
|
||||
else if ( stats_size_guess < pc_stats_size(schema) )
|
||||
{
|
||||
/* only need stats here */
|
||||
serpa = PG_GETHEADERX_SERPATCH_P(0, pc_stats_size(schema));
|
||||
}
|
||||
stats = pc_patch_stats_deserialize(schema, serpa->data);
|
||||
|
||||
initStringInfo(&strdata);
|
||||
/* Make space for VARSIZ, see SET_VARSIZE below */
|
||||
appendStringInfoSpaces(&strdata, VARHDRSZ);
|
||||
initStringInfo(&strdata);
|
||||
/* Make space for VARSIZ, see SET_VARSIZE below */
|
||||
appendStringInfoSpaces(&strdata, VARHDRSZ);
|
||||
|
||||
appendStringInfo(&strdata, "{"
|
||||
"\"pcid\":%d, \"npts\":%d, \"srid\":%d, "
|
||||
"\"compr\":\"%s\",\"dims\":[",
|
||||
serpa->pcid, serpa->npoints, schema->srid,
|
||||
pc_compression_name(serpa->compression));
|
||||
appendStringInfo(&strdata, "{"
|
||||
"\"pcid\":%d, \"npts\":%d, \"srid\":%d, "
|
||||
"\"compr\":\"%s\",\"dims\":[",
|
||||
serpa->pcid, serpa->npoints, schema->srid,
|
||||
pc_compression_name(serpa->compression));
|
||||
|
||||
for (i=0; i<schema->ndims; ++i)
|
||||
{
|
||||
PCDIMENSION *dim = schema->dims[i];
|
||||
PCBYTES bytes;
|
||||
double val;
|
||||
appendStringInfo(&strdata,
|
||||
"%s{\"pos\":%d,\"name\":\"%s\",\"size\":%d"
|
||||
",\"type\":\"%s\"",
|
||||
comma, dim->position, dim->name, dim->size,
|
||||
pc_interpretation_string(dim->interpretation));
|
||||
for (i=0; i<schema->ndims; ++i)
|
||||
{
|
||||
PCDIMENSION *dim = schema->dims[i];
|
||||
PCBYTES bytes;
|
||||
double val;
|
||||
appendStringInfo(&strdata,
|
||||
"%s{\"pos\":%d,\"name\":\"%s\",\"size\":%d"
|
||||
",\"type\":\"%s\"",
|
||||
comma, dim->position, dim->name, dim->size,
|
||||
pc_interpretation_string(dim->interpretation));
|
||||
|
||||
/* Print per-dimension compression (if dimensional) */
|
||||
if ( serpa->compression == PC_DIMENSIONAL )
|
||||
{
|
||||
bytes = ((PCPATCH_DIMENSIONAL*)patch)->bytes[i];
|
||||
switch ( bytes.compression )
|
||||
{
|
||||
case PC_DIM_RLE:
|
||||
appendStringInfoString(&strdata,",\"compr\":\"rle\"");
|
||||
break;
|
||||
case PC_DIM_SIGBITS:
|
||||
appendStringInfoString(&strdata,",\"compr\":\"sigbits\"");
|
||||
break;
|
||||
case PC_DIM_ZLIB:
|
||||
appendStringInfoString(&strdata,",\"compr\":\"zlib\"");
|
||||
break;
|
||||
case PC_DIM_NONE:
|
||||
appendStringInfoString(&strdata,",\"compr\":\"none\"");
|
||||
break;
|
||||
default:
|
||||
appendStringInfo(&strdata,",\"compr\":\"unknown(%d)\"",
|
||||
bytes.compression);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Print per-dimension compression (if dimensional) */
|
||||
if ( serpa->compression == PC_DIMENSIONAL )
|
||||
{
|
||||
bytes = ((PCPATCH_DIMENSIONAL*)patch)->bytes[i];
|
||||
switch ( bytes.compression )
|
||||
{
|
||||
case PC_DIM_RLE:
|
||||
appendStringInfoString(&strdata,",\"compr\":\"rle\"");
|
||||
break;
|
||||
case PC_DIM_SIGBITS:
|
||||
appendStringInfoString(&strdata,",\"compr\":\"sigbits\"");
|
||||
break;
|
||||
case PC_DIM_ZLIB:
|
||||
appendStringInfoString(&strdata,",\"compr\":\"zlib\"");
|
||||
break;
|
||||
case PC_DIM_NONE:
|
||||
appendStringInfoString(&strdata,",\"compr\":\"none\"");
|
||||
break;
|
||||
default:
|
||||
appendStringInfo(&strdata,",\"compr\":\"unknown(%d)\"",
|
||||
bytes.compression);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( stats )
|
||||
{
|
||||
pc_point_get_double_by_name(&(stats->min), dim->name, &val);
|
||||
appendStringInfo(&strdata,",\"stats\":{\"min\":%g", val);
|
||||
pc_point_get_double_by_name(&(stats->max), dim->name, &val);
|
||||
appendStringInfo(&strdata,",\"max\":%g", val);
|
||||
pc_point_get_double_by_name(&(stats->avg), dim->name, &val);
|
||||
appendStringInfo(&strdata,",\"avg\":%g}", val);
|
||||
}
|
||||
appendStringInfoString(&strdata, "}");
|
||||
comma = ",";
|
||||
}
|
||||
if ( stats )
|
||||
{
|
||||
pc_point_get_double_by_name(&(stats->min), dim->name, &val);
|
||||
appendStringInfo(&strdata,",\"stats\":{\"min\":%g", val);
|
||||
pc_point_get_double_by_name(&(stats->max), dim->name, &val);
|
||||
appendStringInfo(&strdata,",\"max\":%g", val);
|
||||
pc_point_get_double_by_name(&(stats->avg), dim->name, &val);
|
||||
appendStringInfo(&strdata,",\"avg\":%g}", val);
|
||||
}
|
||||
appendStringInfoString(&strdata, "}");
|
||||
comma = ",";
|
||||
}
|
||||
|
||||
appendStringInfoString(&strdata, "]}");
|
||||
appendStringInfoString(&strdata, "]}");
|
||||
|
||||
ret = (text*)strdata.data;
|
||||
SET_VARSIZE(ret, strdata.len);
|
||||
PG_RETURN_TEXT_P(ret);
|
||||
ret = (text*)strdata.data;
|
||||
SET_VARSIZE(ret, strdata.len);
|
||||
PG_RETURN_TEXT_P(ret);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(pcpatch_compression);
|
||||
@ -862,7 +862,7 @@ Datum pcpatch_get_stat(PG_FUNCTION_ARGS)
|
||||
|
||||
if ( PG_NARGS() > 2 ) {
|
||||
/* TODO: only get small slice ? */
|
||||
dim_str = text_to_cstring(PG_GETARG_TEXT_P(2));
|
||||
dim_str = text_to_cstring(PG_GETARG_TEXT_P(2));
|
||||
}
|
||||
|
||||
if ( stats_size_guess < pc_stats_size(schema) )
|
||||
@ -962,7 +962,7 @@ Datum pcpatch_filter(PG_FUNCTION_ARGS)
|
||||
}
|
||||
pfree(dim_name);
|
||||
|
||||
/* Always treat zero-point patches as SQL NULL */
|
||||
/* Always treat zero-point patches as SQL NULL */
|
||||
if ( patch_filtered->npoints <= 0 )
|
||||
{
|
||||
pc_patch_free(patch_filtered);
|
||||
@ -976,16 +976,16 @@ Datum pcpatch_filter(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
const char **array_to_cstring_array(ArrayType *array, int *size)
|
||||
{
|
||||
{
|
||||
int i, j, offset = 0;
|
||||
int nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
|
||||
const char **cstring = nelems ? pcalloc(nelems * sizeof(char*)) : NULL;
|
||||
bits8 *bitmap = ARR_NULLBITMAP(array);
|
||||
for(i=j=0; i<nelems; ++i)
|
||||
for(i=j=0; i<nelems; ++i)
|
||||
{
|
||||
text *array_text;
|
||||
if(array_get_isnull(bitmap,i)) continue;
|
||||
|
||||
|
||||
array_text = (text *)(ARR_DATA_PTR(array)+offset);
|
||||
cstring[j++] = text_to_cstring(array_text);
|
||||
offset += INTALIGN(VARSIZE(array_text));
|
||||
@ -1008,7 +1008,7 @@ void pc_cstring_array_free(const char **array, int nelems)
|
||||
PG_FUNCTION_INFO_V1(pcpatch_sort);
|
||||
Datum pcpatch_sort(PG_FUNCTION_ARGS)
|
||||
{
|
||||
SERIALIZED_PATCH *serpatch = PG_GETARG_SERPATCH_P(0);
|
||||
SERIALIZED_PATCH *serpatch = PG_GETARG_SERPATCH_P(0);
|
||||
ArrayType *array = PG_GETARG_ARRAYTYPE_P(1);
|
||||
PCSCHEMA *schema = NULL;
|
||||
PCPATCH *patch = NULL;
|
||||
@ -1026,13 +1026,13 @@ Datum pcpatch_sort(PG_FUNCTION_ARGS)
|
||||
schema = pc_schema_from_pcid(serpatch->pcid, fcinfo);
|
||||
|
||||
patch = pc_patch_deserialize(serpatch, schema);
|
||||
if(patch) patch_sorted = pc_patch_sort(patch,dim_name,ndims);
|
||||
if(patch) patch_sorted = pc_patch_sort(patch,dim_name,ndims);
|
||||
|
||||
pc_cstring_array_free(dim_name,ndims);
|
||||
if(patch) pc_patch_free(patch);
|
||||
PG_FREE_IF_COPY(serpatch, 0);
|
||||
PG_FREE_IF_COPY(serpatch, 0);
|
||||
|
||||
if(!patch_sorted) PG_RETURN_NULL();
|
||||
if(!patch_sorted) PG_RETURN_NULL();
|
||||
|
||||
serpatch_sorted = pc_patch_serialize(patch_sorted,NULL);
|
||||
pc_patch_free(patch_sorted);
|
||||
@ -1058,16 +1058,16 @@ Datum pcpatch_is_sorted(PG_FUNCTION_ARGS)
|
||||
}
|
||||
serpatch = PG_GETARG_SERPATCH_P(0);
|
||||
schema = pc_schema_from_pcid(serpatch->pcid, fcinfo);
|
||||
patch = pc_patch_deserialize(serpatch, schema);
|
||||
patch = pc_patch_deserialize(serpatch, schema);
|
||||
|
||||
res = pc_patch_is_sorted(patch,dim_name,ndims,strict);
|
||||
res = pc_patch_is_sorted(patch,dim_name,ndims,strict);
|
||||
|
||||
pc_cstring_array_free(dim_name,ndims);
|
||||
pc_patch_free(patch);
|
||||
pc_patch_free(patch);
|
||||
|
||||
if(res == PC_FAILURE-1)
|
||||
elog(ERROR, "PC_IsSorted failed");
|
||||
|
||||
|
||||
PG_RETURN_BOOL(res);
|
||||
}
|
||||
|
||||
|
||||
@ -40,9 +40,9 @@ pcid_consistent(const uint32 pcid, const uint32 column_pcid)
|
||||
if ( column_pcid && pcid != column_pcid )
|
||||
{
|
||||
ereport(ERROR, (
|
||||
errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||
errmsg("point/patch pcid (%u) does not match column pcid (%d)", pcid, column_pcid)
|
||||
));
|
||||
errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||
errmsg("point/patch pcid (%u) does not match column pcid (%d)", pcid, column_pcid)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -325,27 +325,27 @@ Datum pc_typmod_in(PG_FUNCTION_ARGS)
|
||||
|
||||
if (ARR_ELEMTYPE(arr) != CSTRINGOID)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
|
||||
errmsg("typmod array must be type cstring[]")));
|
||||
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
|
||||
errmsg("typmod array must be type cstring[]")));
|
||||
|
||||
if (ARR_NDIM(arr) != 1)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
||||
errmsg("typmod array must be one-dimensional")));
|
||||
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
||||
errmsg("typmod array must be one-dimensional")));
|
||||
|
||||
if (ARR_HASNULL(arr))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
|
||||
errmsg("typmod array must not contain nulls")));
|
||||
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
|
||||
errmsg("typmod array must not contain nulls")));
|
||||
|
||||
if (ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr)) > 1)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
||||
errmsg("typmod array must have one element")));
|
||||
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
|
||||
errmsg("typmod array must have one element")));
|
||||
|
||||
deconstruct_array(arr,
|
||||
CSTRINGOID, -2, false, 'c', /* hardwire cstring representation details */
|
||||
&elem_values, NULL, &n);
|
||||
CSTRINGOID, -2, false, 'c', /* hardwire cstring representation details */
|
||||
&elem_values, NULL, &n);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
|
||||
@ -31,8 +31,8 @@ pgsql_alloc(size_t size)
|
||||
if ( ! result )
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OUT_OF_MEMORY),
|
||||
errmsg("Out of virtual memory")));
|
||||
(errcode(ERRCODE_OUT_OF_MEMORY),
|
||||
errmsg("Out of virtual memory")));
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -46,8 +46,8 @@ pgsql_realloc(void *mem, size_t size)
|
||||
if ( ! result )
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OUT_OF_MEMORY),
|
||||
errmsg("Out of virtual memory")));
|
||||
(errcode(ERRCODE_OUT_OF_MEMORY),
|
||||
errmsg("Out of virtual memory")));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -60,7 +60,7 @@ pgsql_free(void *ptr)
|
||||
|
||||
static void
|
||||
pgsql_msg_handler(int sig, const char *fmt, va_list ap)
|
||||
__attribute__ (( format (printf, 2, 0) ));
|
||||
__attribute__ (( format (printf, 2, 0) ));
|
||||
|
||||
static void
|
||||
pgsql_msg_handler(int sig, const char *fmt, va_list ap)
|
||||
@ -113,9 +113,11 @@ void
|
||||
_PG_init(void)
|
||||
{
|
||||
elog(LOG, "Pointcloud (%s) module loaded", POINTCLOUD_VERSION);
|
||||
pc_set_handlers(pgsql_alloc, pgsql_realloc,
|
||||
pgsql_free, pgsql_error,
|
||||
pgsql_info, pgsql_warn);
|
||||
pc_set_handlers(
|
||||
pgsql_alloc, pgsql_realloc,
|
||||
pgsql_free, pgsql_error,
|
||||
pgsql_info, pgsql_warn
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@ -240,7 +242,7 @@ pc_schema_from_pcid_uncached(uint32 pcid)
|
||||
}
|
||||
|
||||
sprintf(sql, "select %s, %s from %s where pcid = %d",
|
||||
POINTCLOUD_FORMATS_XML, POINTCLOUD_FORMATS_SRID, POINTCLOUD_FORMATS, pcid);
|
||||
POINTCLOUD_FORMATS_XML, POINTCLOUD_FORMATS_SRID, POINTCLOUD_FORMATS, pcid);
|
||||
err = SPI_exec(sql, 1);
|
||||
|
||||
if ( err < 0 )
|
||||
@ -287,8 +289,8 @@ pc_schema_from_pcid_uncached(uint32 pcid)
|
||||
if ( ! err )
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_NOT_AN_XML_DOCUMENT),
|
||||
errmsg("unable to parse XML for pcid = %d in \"%s\"", pcid, POINTCLOUD_FORMATS)));
|
||||
(errcode(ERRCODE_NOT_AN_XML_DOCUMENT),
|
||||
errmsg("unable to parse XML for pcid = %d in \"%s\"", pcid, POINTCLOUD_FORMATS)));
|
||||
}
|
||||
|
||||
schema->pcid = pcid;
|
||||
@ -388,8 +390,8 @@ pc_schema_from_pcid(uint32 pcid, FunctionCallInfoData *fcinfo)
|
||||
if ( ! schema_cache )
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INTERNAL_ERROR),
|
||||
errmsg("unable to create/load statement level schema cache")));
|
||||
(errcode(ERRCODE_INTERNAL_ERROR),
|
||||
errmsg("unable to create/load statement level schema cache")));
|
||||
}
|
||||
|
||||
/* Find our PCID if it's in there (usually it will be first) */
|
||||
@ -410,8 +412,8 @@ pc_schema_from_pcid(uint32 pcid, FunctionCallInfoData *fcinfo)
|
||||
if ( ! schema )
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INTERNAL_ERROR),
|
||||
errmsg("unable to load schema for pcid %u", pcid)));
|
||||
(errcode(ERRCODE_INTERNAL_ERROR),
|
||||
errmsg("unable to load schema for pcid %u", pcid)));
|
||||
}
|
||||
|
||||
/* Save the XML in the next unused slot */
|
||||
@ -1019,12 +1021,13 @@ pc_patch_wkb_set_char(uint8_t *wkb, char c)
|
||||
return wkb;
|
||||
}
|
||||
|
||||
/* 0 = xdr | big endian */
|
||||
/* 1 = ndr | little endian */
|
||||
static char
|
||||
machine_endian(void)
|
||||
{
|
||||
static int check_int = 1; /* dont modify this!!! */
|
||||
return *((char *) &check_int); /* 0 = big endian | xdr,
|
||||
* 1 = little endian | ndr */
|
||||
return *((char *) &check_int);
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
@ -1038,15 +1041,15 @@ pc_patch_to_geometry_wkb_envelope(const SERIALIZED_PATCH *pa, const PCSCHEMA *sc
|
||||
int has_srid = false;
|
||||
size_t size = 1 + 4 + 4 + 4 + 2*npoints*8; /* endian + type + nrings + npoints + 5 dbl pts */
|
||||
|
||||
/* Bounds! */
|
||||
double xmin = pa->bounds.xmin;
|
||||
double ymin = pa->bounds.ymin;
|
||||
double xmax = pa->bounds.xmax;
|
||||
double ymax = pa->bounds.ymax;
|
||||
|
||||
/* Make sure they're slightly bigger than a point */
|
||||
if ( xmin == xmax ) xmax += xmax * 0.0000001;
|
||||
if ( ymin == ymax ) ymax += ymax * 0.0000001;
|
||||
/* Bounds! */
|
||||
double xmin = pa->bounds.xmin;
|
||||
double ymin = pa->bounds.ymin;
|
||||
double xmax = pa->bounds.xmax;
|
||||
double ymax = pa->bounds.ymax;
|
||||
|
||||
/* Make sure they're slightly bigger than a point */
|
||||
if ( xmin == xmax ) xmax += xmax * 0.0000001;
|
||||
if ( ymin == ymax ) ymax += ymax * 0.0000001;
|
||||
|
||||
if ( schema->srid > 0 )
|
||||
{
|
||||
|
||||
@ -10,16 +10,16 @@
|
||||
-- Confirm the XML representation of a schema has everything we need
|
||||
CREATE OR REPLACE FUNCTION PC_SchemaIsValid(schemaxml text)
|
||||
RETURNS boolean AS 'MODULE_PATHNAME','pcschema_is_valid'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
-- Metadata table describing contents of pcpoints
|
||||
CREATE TABLE IF NOT EXISTS pointcloud_formats (
|
||||
pcid INTEGER PRIMARY KEY
|
||||
-- PCID == 0 is unknown
|
||||
-- PCID > 2^16 is reserved to leave space in typmod
|
||||
CHECK (pcid > 0 AND pcid < 65536),
|
||||
srid INTEGER, -- REFERENCES spatial_ref_sys(srid)
|
||||
schema TEXT
|
||||
pcid INTEGER PRIMARY KEY
|
||||
-- PCID == 0 is unknown
|
||||
-- PCID > 2^16 is reserved to leave space in typmod
|
||||
CHECK (pcid > 0 AND pcid < 65536),
|
||||
srid INTEGER, -- REFERENCES spatial_ref_sys(srid)
|
||||
schema TEXT
|
||||
CHECK ( PC_SchemaIsValid(schema) )
|
||||
);
|
||||
|
||||
@ -27,50 +27,50 @@ CREATE TABLE IF NOT EXISTS pointcloud_formats (
|
||||
SELECT pg_catalog.pg_extension_config_dump('pointcloud_formats', '');
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_SchemaGetNDims(pcid integer)
|
||||
RETURNS integer
|
||||
RETURNS integer
|
||||
AS 'MODULE_PATHNAME','pcschema_get_ndims'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
-- Read typmod number from string
|
||||
CREATE OR REPLACE FUNCTION pc_typmod_in(cstring[])
|
||||
RETURNS integer AS 'MODULE_PATHNAME','pc_typmod_in'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
RETURNS integer AS 'MODULE_PATHNAME','pc_typmod_in'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
-- Write typmod number to string
|
||||
CREATE OR REPLACE FUNCTION pc_typmod_out(typmod integer)
|
||||
RETURNS cstring AS 'MODULE_PATHNAME','pc_typmod_out'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
RETURNS cstring AS 'MODULE_PATHNAME','pc_typmod_out'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
-- Read pcid from typmod number
|
||||
CREATE OR REPLACE FUNCTION pc_typmod_pcid(typmod integer)
|
||||
RETURNS int4 AS 'MODULE_PATHNAME','pc_typmod_pcid'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
RETURNS int4 AS 'MODULE_PATHNAME','pc_typmod_pcid'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
-- Return the script version number
|
||||
CREATE OR REPLACE FUNCTION pc_script_version()
|
||||
RETURNS text AS $$ SELECT '@POINTCLOUD_VERSION@'::text $$
|
||||
LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
RETURNS text AS $$ SELECT '@POINTCLOUD_VERSION@'::text $$
|
||||
LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
|
||||
-- Return the library version number
|
||||
CREATE OR REPLACE FUNCTION pc_lib_version()
|
||||
RETURNS text AS 'MODULE_PATHNAME', 'pc_version'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
RETURNS text AS 'MODULE_PATHNAME', 'pc_version'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
-- Return the extension version number and check sanity
|
||||
CREATE OR REPLACE FUNCTION pc_version()
|
||||
RETURNS text AS
|
||||
RETURNS text AS
|
||||
$$
|
||||
DECLARE
|
||||
libver TEXT;
|
||||
scrver TEXT;
|
||||
libver TEXT;
|
||||
scrver TEXT;
|
||||
BEGIN
|
||||
scrver := pc_script_version();
|
||||
libver := pc_lib_version();
|
||||
IF scrver != libver THEN
|
||||
RAISE WARNING 'Library (%) and script (%) version mismatch',
|
||||
libver, scrver;
|
||||
END IF;
|
||||
RETURN libver;
|
||||
scrver := pc_script_version();
|
||||
libver := pc_lib_version();
|
||||
IF scrver != libver THEN
|
||||
RAISE WARNING 'Library (%) and script (%) version mismatch',
|
||||
libver, scrver;
|
||||
END IF;
|
||||
RETURN libver;
|
||||
END;
|
||||
$$
|
||||
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
@ -78,42 +78,42 @@ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
|
||||
-- Upgrade pointcloud extension to latest (or specified) version.
|
||||
-- Takes care of in-development upgrades
|
||||
CREATE OR REPLACE FUNCTION pc_upgrade(to_version text DEFAULT NULL)
|
||||
RETURNS text AS
|
||||
RETURNS text AS
|
||||
$$
|
||||
DECLARE
|
||||
ver RECORD;
|
||||
target_version text;
|
||||
ver RECORD;
|
||||
target_version text;
|
||||
BEGIN
|
||||
SELECT default_version, installed_version
|
||||
FROM pg_catalog.pg_available_extensions
|
||||
WHERE name = 'pointcloud'
|
||||
INTO ver;
|
||||
SELECT default_version, installed_version
|
||||
FROM pg_catalog.pg_available_extensions
|
||||
WHERE name = 'pointcloud'
|
||||
INTO ver;
|
||||
|
||||
IF to_version IS NULL THEN
|
||||
target_version := ver.default_version;
|
||||
ELSE
|
||||
target_version := to_version;
|
||||
END IF;
|
||||
IF to_version IS NULL THEN
|
||||
target_version := ver.default_version;
|
||||
ELSE
|
||||
target_version := to_version;
|
||||
END IF;
|
||||
|
||||
IF target_version != ver.installed_version THEN
|
||||
EXECUTE 'ALTER EXTENSION pointcloud UPDATE TO ' ||
|
||||
quote_literal(target_version);
|
||||
ELSE
|
||||
-- Use the "next" trick
|
||||
IF target_version LIKE '%next' THEN
|
||||
target_version := replace(target_version, 'next', '');
|
||||
EXECUTE 'ALTER EXTENSION pointcloud UPDATE TO ' ||
|
||||
quote_literal(target_version);
|
||||
ELSE
|
||||
-- Doubel upgrade, to get back to "next"-free
|
||||
EXECUTE 'ALTER EXTENSION pointcloud UPDATE TO ' ||
|
||||
quote_literal(target_version || 'next');
|
||||
EXECUTE 'ALTER EXTENSION pointcloud UPDATE TO ' ||
|
||||
quote_literal(target_version);
|
||||
END IF;
|
||||
END IF;
|
||||
IF target_version != ver.installed_version THEN
|
||||
EXECUTE 'ALTER EXTENSION pointcloud UPDATE TO ' ||
|
||||
quote_literal(target_version);
|
||||
ELSE
|
||||
-- Use the "next" trick
|
||||
IF target_version LIKE '%next' THEN
|
||||
target_version := replace(target_version, 'next', '');
|
||||
EXECUTE 'ALTER EXTENSION pointcloud UPDATE TO ' ||
|
||||
quote_literal(target_version);
|
||||
ELSE
|
||||
-- Double upgrade, to get back to "next"-free
|
||||
EXECUTE 'ALTER EXTENSION pointcloud UPDATE TO ' ||
|
||||
quote_literal(target_version || 'next');
|
||||
EXECUTE 'ALTER EXTENSION pointcloud UPDATE TO ' ||
|
||||
quote_literal(target_version);
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
RETURN pc_version();
|
||||
RETURN pc_version();
|
||||
END;
|
||||
$$ LANGUAGE 'plpgsql' VOLATILE;
|
||||
|
||||
@ -128,7 +128,7 @@ CREATE OR REPLACE FUNCTION pcpoint_in(cstring)
|
||||
CREATE OR REPLACE FUNCTION pcpoint_out(pcpoint)
|
||||
RETURNS cstring AS 'MODULE_PATHNAME', 'pcpoint_out'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
|
||||
CREATE TYPE pcpoint (
|
||||
internallength = variable,
|
||||
input = pcpoint_in,
|
||||
@ -145,7 +145,7 @@ CREATE TYPE pcpoint (
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_Get(pt pcpoint, dimname text)
|
||||
RETURNS numeric AS 'MODULE_PATHNAME', 'pcpoint_get_value'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
-- Availability: 1.1.0
|
||||
CREATE OR REPLACE FUNCTION PC_Get(pt pcpoint)
|
||||
@ -175,7 +175,7 @@ CREATE OR REPLACE FUNCTION pcpatch_in(cstring)
|
||||
CREATE OR REPLACE FUNCTION pcpatch_out(pcpatch)
|
||||
RETURNS cstring AS 'MODULE_PATHNAME', 'pcpatch_out'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
|
||||
CREATE TYPE pcpatch (
|
||||
internallength = variable,
|
||||
input = pcpatch_in,
|
||||
@ -199,115 +199,115 @@ CREATE OR REPLACE FUNCTION PC_Envelope(p pcpatch)
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_Uncompress(p pcpatch)
|
||||
RETURNS pcpatch AS 'MODULE_PATHNAME', 'pcpatch_uncompress'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
RETURNS pcpatch AS 'MODULE_PATHNAME', 'pcpatch_uncompress'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
-- Availability: 1.1.0
|
||||
CREATE OR REPLACE FUNCTION PC_Compress(p pcpatch, comp text default '', config text default '')
|
||||
RETURNS pcpatch AS 'MODULE_PATHNAME', 'pcpatch_compress'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
RETURNS pcpatch AS 'MODULE_PATHNAME', 'pcpatch_compress'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_NumPoints(p pcpatch)
|
||||
RETURNS int4 AS 'MODULE_PATHNAME', 'pcpatch_numpoints'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
RETURNS int4 AS 'MODULE_PATHNAME', 'pcpatch_numpoints'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
-- Availability: 1.1.0
|
||||
CREATE OR REPLACE FUNCTION PC_PCId(p pcpatch)
|
||||
RETURNS int4 AS 'MODULE_PATHNAME', 'pcpatch_pcid'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
RETURNS int4 AS 'MODULE_PATHNAME', 'pcpatch_pcid'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
-- Availability: 1.1.0
|
||||
CREATE OR REPLACE FUNCTION PC_Summary(p pcpatch)
|
||||
RETURNS text AS 'MODULE_PATHNAME', 'pcpatch_summary'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
RETURNS text AS 'MODULE_PATHNAME', 'pcpatch_summary'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_Compression(p pcpatch)
|
||||
RETURNS int4 AS 'MODULE_PATHNAME', 'pcpatch_compression'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
RETURNS int4 AS 'MODULE_PATHNAME', 'pcpatch_compression'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_Intersects(p1 pcpatch, p2 pcpatch)
|
||||
RETURNS boolean AS 'MODULE_PATHNAME', 'pcpatch_intersects'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
RETURNS boolean AS 'MODULE_PATHNAME', 'pcpatch_intersects'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_MemSize(p pcpatch)
|
||||
RETURNS int4 AS 'MODULE_PATHNAME', 'pcpatch_size'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
RETURNS int4 AS 'MODULE_PATHNAME', 'pcpatch_size'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_MemSize(p pcpoint)
|
||||
RETURNS int4 AS 'MODULE_PATHNAME', 'pcpoint_size'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
RETURNS int4 AS 'MODULE_PATHNAME', 'pcpoint_size'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
-- Availability: 1.1.0
|
||||
CREATE OR REPLACE FUNCTION PC_PCId(p pcpoint)
|
||||
RETURNS int4 AS 'MODULE_PATHNAME', 'pcpoint_pcid'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
RETURNS int4 AS 'MODULE_PATHNAME', 'pcpoint_pcid'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
-- Availability: 1.1.0
|
||||
-- @param statno 0:min 1:max 2:avg
|
||||
CREATE OR REPLACE FUNCTION _PC_PatchStat(p pcpatch, statno int)
|
||||
RETURNS pcpoint AS 'MODULE_PATHNAME', 'pcpatch_get_stat'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
-- Availability: 1.1.0
|
||||
CREATE OR REPLACE FUNCTION PC_PatchMin(p pcpatch)
|
||||
RETURNS pcpoint AS $$ SELECT _PC_PatchStat(p, 0) $$
|
||||
LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
|
||||
-- Availability: 1.1.0
|
||||
CREATE OR REPLACE FUNCTION PC_PatchMax(p pcpatch)
|
||||
RETURNS pcpoint AS $$ SELECT _PC_PatchStat(p, 1) $$
|
||||
LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
|
||||
-- Availability: 1.1.0
|
||||
CREATE OR REPLACE FUNCTION PC_PatchAvg(p pcpatch)
|
||||
RETURNS pcpoint AS $$ SELECT _PC_PatchStat(p, 2) $$
|
||||
LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
|
||||
-- Availability: 1.1.0
|
||||
-- @param statno 0:min 1:max 2:avg
|
||||
CREATE OR REPLACE FUNCTION _PC_PatchStat(p pcpatch, statno int, attr text)
|
||||
RETURNS numeric AS 'MODULE_PATHNAME', 'pcpatch_get_stat'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_PatchMin(p pcpatch, attr text, stat text default 'min')
|
||||
RETURNS numeric AS $$ SELECT _PC_PatchStat(p, 0, attr) $$
|
||||
LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_PatchMax(p pcpatch, attr text, stat text default 'max')
|
||||
RETURNS numeric AS $$ SELECT _PC_PatchStat(p, 1, attr) $$
|
||||
LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_PatchAvg(p pcpatch, attr text, stat text default 'avg')
|
||||
RETURNS numeric AS $$ SELECT _PC_PatchStat(p, 2, attr) $$
|
||||
LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_FilterLessThan(p pcpatch, attr text, v1 float8 default 0.0, v2 float8 default 0.0, mode int4 default 0)
|
||||
RETURNS pcpatch AS 'MODULE_PATHNAME', 'pcpatch_filter'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_FilterGreaterThan(p pcpatch, attr text, v1 float8 default 0.0, v2 float8 default 0.0, mode int4 default 1)
|
||||
RETURNS pcpatch AS 'MODULE_PATHNAME', 'pcpatch_filter'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_FilterEquals(p pcpatch, attr text, v1 float8 default 0.0, v2 float8 default 0.0, mode int4 default 2)
|
||||
RETURNS pcpatch AS 'MODULE_PATHNAME', 'pcpatch_filter'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_FilterBetween(p pcpatch, attr text, v1 float8 default 0.0, v2 float8 default 0.0, mode int4 default 3)
|
||||
RETURNS pcpatch AS 'MODULE_PATHNAME', 'pcpatch_filter'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_PointN(p pcpatch, n int4)
|
||||
RETURNS pcpoint AS 'MODULE_PATHNAME', 'pcpatch_pointn'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
RETURNS pcpoint AS 'MODULE_PATHNAME', 'pcpatch_pointn'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_Sort(p pcpatch, attr text[])
|
||||
RETURNS pcpatch AS 'MODULE_PATHNAME', 'pcpatch_sort'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
RETURNS pcpatch AS 'MODULE_PATHNAME', 'pcpatch_sort'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_IsSorted(p pcpatch, attr text[], strict boolean default false)
|
||||
RETURNS boolean AS 'MODULE_PATHNAME', 'pcpatch_is_sorted'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
RETURNS boolean AS 'MODULE_PATHNAME', 'pcpatch_is_sorted'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
-------------------------------------------------------------------
|
||||
-- POINTCLOUD_COLUMNS
|
||||
@ -315,39 +315,39 @@ CREATE OR REPLACE FUNCTION PC_IsSorted(p pcpatch, attr text[], strict boolean de
|
||||
|
||||
-- Last Changed: 1.0.1
|
||||
CREATE OR REPLACE VIEW pointcloud_columns AS
|
||||
SELECT
|
||||
n.nspname AS schema,
|
||||
c.relname AS table,
|
||||
a.attname AS column,
|
||||
pc_typmod_pcid(a.atttypmod) AS pcid,
|
||||
p.srid AS srid,
|
||||
t.typname AS type
|
||||
FROM
|
||||
pg_class c,
|
||||
pg_type t,
|
||||
pg_namespace n,
|
||||
pg_attribute a
|
||||
LEFT OUTER JOIN pointcloud_formats p
|
||||
ON ( pc_typmod_pcid(a.atttypmod) = p.pcid )
|
||||
WHERE t.typname IN ('pcpatch','pcpoint')
|
||||
AND a.attisdropped = false
|
||||
AND a.atttypid = t.oid
|
||||
AND a.attrelid = c.oid
|
||||
AND c.relnamespace = n.oid
|
||||
AND NOT pg_is_other_temp_schema(c.relnamespace)
|
||||
AND has_table_privilege( c.oid, 'SELECT'::text );
|
||||
SELECT
|
||||
n.nspname AS schema,
|
||||
c.relname AS table,
|
||||
a.attname AS column,
|
||||
pc_typmod_pcid(a.atttypmod) AS pcid,
|
||||
p.srid AS srid,
|
||||
t.typname AS type
|
||||
FROM
|
||||
pg_class c,
|
||||
pg_type t,
|
||||
pg_namespace n,
|
||||
pg_attribute a
|
||||
LEFT OUTER JOIN pointcloud_formats p
|
||||
ON ( pc_typmod_pcid(a.atttypmod) = p.pcid )
|
||||
WHERE t.typname IN ('pcpatch','pcpoint')
|
||||
AND a.attisdropped = false
|
||||
AND a.atttypid = t.oid
|
||||
AND a.attrelid = c.oid
|
||||
AND c.relnamespace = n.oid
|
||||
AND NOT pg_is_other_temp_schema(c.relnamespace)
|
||||
AND has_table_privilege( c.oid, 'SELECT'::text );
|
||||
|
||||
|
||||
-- Special cast for enforcing typmod restrictions
|
||||
CREATE OR REPLACE FUNCTION pcpatch(p pcpatch, typmod integer, explicit boolean)
|
||||
RETURNS pcpatch AS 'MODULE_PATHNAME', 'pcpatch_enforce_typmod'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
RETURNS pcpatch AS 'MODULE_PATHNAME', 'pcpatch_enforce_typmod'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
CREATE CAST (pcpatch AS pcpatch) WITH FUNCTION pcpatch(pcpatch, integer, boolean) AS IMPLICIT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION pcpoint(p pcpoint, typmod integer, explicit boolean)
|
||||
RETURNS pcpoint AS 'MODULE_PATHNAME', 'pcpoint_enforce_typmod'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
RETURNS pcpoint AS 'MODULE_PATHNAME', 'pcpoint_enforce_typmod'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
CREATE CAST (pcpoint AS pcpoint) WITH FUNCTION pcpoint(pcpoint, integer, boolean) AS IMPLICIT;
|
||||
|
||||
@ -391,17 +391,17 @@ CREATE OR REPLACE FUNCTION pcpoint_agg_final_pcpatch (pointcloud_abs)
|
||||
LANGUAGE 'c';
|
||||
|
||||
CREATE AGGREGATE PC_Patch (
|
||||
BASETYPE = pcpoint,
|
||||
SFUNC = pcpoint_agg_transfn,
|
||||
STYPE = pointcloud_abs,
|
||||
FINALFUNC = pcpoint_agg_final_pcpatch
|
||||
BASETYPE = pcpoint,
|
||||
SFUNC = pcpoint_agg_transfn,
|
||||
STYPE = pointcloud_abs,
|
||||
FINALFUNC = pcpoint_agg_final_pcpatch
|
||||
);
|
||||
|
||||
CREATE AGGREGATE PC_Point_Agg (
|
||||
BASETYPE = pcpoint,
|
||||
SFUNC = pcpoint_agg_transfn,
|
||||
STYPE = pointcloud_abs,
|
||||
FINALFUNC = pcpoint_agg_final_array
|
||||
BASETYPE = pcpoint,
|
||||
SFUNC = pcpoint_agg_transfn,
|
||||
STYPE = pointcloud_abs,
|
||||
FINALFUNC = pcpoint_agg_final_array
|
||||
);
|
||||
|
||||
-------------------------------------------------------------------
|
||||
@ -419,19 +419,19 @@ CREATE OR REPLACE FUNCTION pcpatch_agg_final_pcpatch (pointcloud_abs)
|
||||
CREATE OR REPLACE FUNCTION pcpatch_agg_transfn (pointcloud_abs, pcpatch)
|
||||
RETURNS pointcloud_abs AS 'MODULE_PATHNAME', 'pointcloud_agg_transfn'
|
||||
LANGUAGE 'c';
|
||||
|
||||
|
||||
CREATE AGGREGATE PC_Patch_Agg (
|
||||
BASETYPE = pcpatch,
|
||||
SFUNC = pcpatch_agg_transfn,
|
||||
STYPE = pointcloud_abs,
|
||||
FINALFUNC = pcpatch_agg_final_array
|
||||
BASETYPE = pcpatch,
|
||||
SFUNC = pcpatch_agg_transfn,
|
||||
STYPE = pointcloud_abs,
|
||||
FINALFUNC = pcpatch_agg_final_array
|
||||
);
|
||||
|
||||
CREATE AGGREGATE PC_Union (
|
||||
BASETYPE = pcpatch,
|
||||
SFUNC = pcpatch_agg_transfn,
|
||||
STYPE = pointcloud_abs,
|
||||
FINALFUNC = pcpatch_agg_final_pcpatch
|
||||
BASETYPE = pcpatch,
|
||||
SFUNC = pcpatch_agg_transfn,
|
||||
STYPE = pointcloud_abs,
|
||||
FINALFUNC = pcpatch_agg_final_pcpatch
|
||||
);
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_Explode(p pcpatch)
|
||||
|
||||
@ -1,43 +1,43 @@
|
||||
{
|
||||
"name": "pointcloud_postgis",
|
||||
"abstract": "PostGIS integration functions for Pointcloud",
|
||||
"description": "Provides GIS overlay and vector/raster hooks for point clou data.",
|
||||
"version": "1.0.0",
|
||||
"release_status": "unstable",
|
||||
"maintainer": "Paul Ramsey",
|
||||
"license": "bsd",
|
||||
"provides": {
|
||||
"pointcloud_postgis": {
|
||||
"abstract": "PostGIS integration for Pointcloud",
|
||||
"version": "1.0.0",
|
||||
"file": "",
|
||||
"docfile": ""
|
||||
}
|
||||
}
|
||||
"prereqs": {
|
||||
"runtime": {
|
||||
"requires": {
|
||||
"postgis": "2.0.0",
|
||||
"pointcloud": "1.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"generated_by": "Paul Ramsey",
|
||||
"resources": {
|
||||
"bugtracker": {
|
||||
"web": "http://github.com/pramsey/pointcloud"
|
||||
},
|
||||
"repository": {
|
||||
"url": "",
|
||||
"web": "http://github.com/pramsey/pointcloud",
|
||||
"type": "git"
|
||||
}
|
||||
},
|
||||
"meta-spec": {
|
||||
"version": "1.0.0",
|
||||
"url": "http://pgxn.org/meta/spec.txt"
|
||||
},
|
||||
"tags": [
|
||||
"gis", "lidar", "spatial", "geometry"
|
||||
]
|
||||
}
|
||||
{
|
||||
"name": "pointcloud_postgis",
|
||||
"abstract": "PostGIS integration functions for Pointcloud",
|
||||
"description": "Provides GIS overlay and vector/raster hooks for point clou data.",
|
||||
"version": "1.0.0",
|
||||
"release_status": "unstable",
|
||||
"maintainer": "Paul Ramsey",
|
||||
"license": "bsd",
|
||||
"provides": {
|
||||
"pointcloud_postgis": {
|
||||
"abstract": "PostGIS integration for Pointcloud",
|
||||
"version": "1.0.0",
|
||||
"file": "",
|
||||
"docfile": ""
|
||||
}
|
||||
}
|
||||
"prereqs": {
|
||||
"runtime": {
|
||||
"requires": {
|
||||
"postgis": "2.0.0",
|
||||
"pointcloud": "1.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"generated_by": "Paul Ramsey",
|
||||
"resources": {
|
||||
"bugtracker": {
|
||||
"web": "http://github.com/pramsey/pointcloud"
|
||||
},
|
||||
"repository": {
|
||||
"url": "",
|
||||
"web": "http://github.com/pramsey/pointcloud",
|
||||
"type": "git"
|
||||
}
|
||||
},
|
||||
"meta-spec": {
|
||||
"version": "1.0.0",
|
||||
"url": "http://pgxn.org/meta/spec.txt"
|
||||
},
|
||||
"tags": [
|
||||
"gis", "lidar", "spatial", "geometry"
|
||||
]
|
||||
}
|
||||
|
||||
@ -2,26 +2,26 @@
|
||||
-- Function to overlap polygon on patch
|
||||
--
|
||||
CREATE OR REPLACE FUNCTION PC_Intersection(pcpatch, geometry)
|
||||
RETURNS pcpatch AS
|
||||
$$
|
||||
WITH
|
||||
pts AS (SELECT PC_Explode($1) AS pt),
|
||||
pgpts AS (SELECT ST_GeomFromEWKB(PC_AsBinary(pt)) AS pgpt, pt FROM pts),
|
||||
ipts AS (SELECT pt FROM pgpts WHERE ST_Intersects(pgpt, $2)),
|
||||
ipch AS (SELECT PC_Patch(pt) AS pch FROM ipts)
|
||||
SELECT pch FROM ipch;
|
||||
$$
|
||||
LANGUAGE 'sql';
|
||||
RETURNS pcpatch AS
|
||||
$$
|
||||
WITH
|
||||
pts AS (SELECT PC_Explode($1) AS pt),
|
||||
pgpts AS (SELECT ST_GeomFromEWKB(PC_AsBinary(pt)) AS pgpt, pt FROM pts),
|
||||
ipts AS (SELECT pt FROM pgpts WHERE ST_Intersects(pgpt, $2)),
|
||||
ipch AS (SELECT PC_Patch(pt) AS pch FROM ipts)
|
||||
SELECT pch FROM ipch;
|
||||
$$
|
||||
LANGUAGE 'sql';
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Cast from pcpatch to polygon
|
||||
--
|
||||
CREATE OR REPLACE FUNCTION geometry(pcpatch)
|
||||
RETURNS geometry AS
|
||||
$$
|
||||
SELECT ST_GeomFromEWKB(PC_Envelope($1))
|
||||
$$
|
||||
LANGUAGE 'sql';
|
||||
RETURNS geometry AS
|
||||
$$
|
||||
SELECT ST_GeomFromEWKB(PC_Envelope($1))
|
||||
$$
|
||||
LANGUAGE 'sql';
|
||||
|
||||
CREATE CAST (pcpatch AS geometry) WITH FUNCTION geometry(pcpatch);
|
||||
|
||||
@ -29,11 +29,11 @@ CREATE CAST (pcpatch AS geometry) WITH FUNCTION geometry(pcpatch);
|
||||
-- Cast from pcpoint to point
|
||||
--
|
||||
CREATE OR REPLACE FUNCTION geometry(pcpoint)
|
||||
RETURNS geometry AS
|
||||
$$
|
||||
SELECT ST_GeomFromEWKB(PC_AsBinary($1))
|
||||
$$
|
||||
LANGUAGE 'sql';
|
||||
RETURNS geometry AS
|
||||
$$
|
||||
SELECT ST_GeomFromEWKB(PC_AsBinary($1))
|
||||
$$
|
||||
LANGUAGE 'sql';
|
||||
|
||||
CREATE CAST (pcpoint AS geometry) WITH FUNCTION geometry(pcpoint);
|
||||
|
||||
@ -42,16 +42,16 @@ CREATE CAST (pcpoint AS geometry) WITH FUNCTION geometry(pcpoint);
|
||||
-- Function to overlap polygon on patch
|
||||
--
|
||||
CREATE OR REPLACE FUNCTION PC_Intersects(pcpatch, geometry)
|
||||
RETURNS boolean AS
|
||||
$$
|
||||
SELECT ST_Intersects($2, geometry($1))
|
||||
$$
|
||||
LANGUAGE 'sql';
|
||||
RETURNS boolean AS
|
||||
$$
|
||||
SELECT ST_Intersects($2, geometry($1))
|
||||
$$
|
||||
LANGUAGE 'sql';
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_Intersects(geometry, pcpatch)
|
||||
RETURNS boolean AS
|
||||
$$
|
||||
SELECT PC_Intersects($2, $1)
|
||||
$$
|
||||
LANGUAGE 'sql';
|
||||
RETURNS boolean AS
|
||||
$$
|
||||
SELECT PC_Intersects($2, $1)
|
||||
$$
|
||||
LANGUAGE 'sql';
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user