indentation normalization

This commit is contained in:
Mathieu Brédif 2017-02-12 23:52:15 +01:00
parent 2b87e90d49
commit ef5fc167d8
34 changed files with 2597 additions and 2583 deletions

View File

@ -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

View File

@ -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
};

View File

@ -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
};

View File

@ -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
};

View File

@ -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
};

View File

@ -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
};

View File

@ -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;

View File

@ -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.
*/

View File

@ -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.
*/

View File

@ -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 */

View File

@ -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 */

View File

@ -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__);
}
}
}

View File

@ -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, "]}");

View File

@ -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__);

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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
}

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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)

View File

@ -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;
}
/**

View File

@ -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

View File

@ -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"
]
}

View File

@ -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);
}

View File

@ -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++)
{

View File

@ -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 )
{

View File

@ -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)

View File

@ -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"
]
}

View File

@ -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';