| 1387 | * Something that is not easy to test from within the outside. */ |
| 1388 | #define HLL_TEST_CYCLES 1000 |
| 1389 | void pfselftestCommand(client *c) { |
| 1390 | unsigned int j, i; |
| 1391 | sds bitcounters = sdsnewlen(NULL,HLL_DENSE_SIZE); |
| 1392 | struct hllhdr *hdr = (struct hllhdr*) bitcounters, *hdr2; |
| 1393 | robj *o = NULL; |
| 1394 | uint8_t bytecounters[HLL_REGISTERS]; |
| 1395 | |
| 1396 | /* Test 1: access registers. |
| 1397 | * The test is conceived to test that the different counters of our data |
| 1398 | * structure are accessible and that setting their values both result in |
| 1399 | * the correct value to be retained and not affect adjacent values. */ |
| 1400 | for (j = 0; j < HLL_TEST_CYCLES; j++) { |
| 1401 | /* Set the HLL counters and an array of unsigned byes of the |
| 1402 | * same size to the same set of random values. */ |
| 1403 | for (i = 0; i < HLL_REGISTERS; i++) { |
| 1404 | unsigned int r = rand() & HLL_REGISTER_MAX; |
| 1405 | |
| 1406 | bytecounters[i] = r; |
| 1407 | HLL_DENSE_SET_REGISTER(hdr->registers,i,r); |
| 1408 | } |
| 1409 | /* Check that we are able to retrieve the same values. */ |
| 1410 | for (i = 0; i < HLL_REGISTERS; i++) { |
| 1411 | unsigned int val; |
| 1412 | |
| 1413 | HLL_DENSE_GET_REGISTER(val,hdr->registers,i); |
| 1414 | if (val != bytecounters[i]) { |
| 1415 | addReplyErrorFormat(c, |
| 1416 | "TESTFAILED Register %d should be %d but is %d", |
| 1417 | i, (int) bytecounters[i], (int) val); |
| 1418 | goto cleanup; |
| 1419 | } |
| 1420 | } |
| 1421 | } |
| 1422 | |
| 1423 | /* Test 2: approximation error. |
| 1424 | * The test adds unique elements and check that the estimated value |
| 1425 | * is always reasonable bounds. |
| 1426 | * |
| 1427 | * We check that the error is smaller than a few times than the expected |
| 1428 | * standard error, to make it very unlikely for the test to fail because |
| 1429 | * of a "bad" run. |
| 1430 | * |
| 1431 | * The test is performed with both dense and sparse HLLs at the same |
| 1432 | * time also verifying that the computed cardinality is the same. */ |
| 1433 | memset(hdr->registers,0,HLL_DENSE_SIZE-HLL_HDR_SIZE); |
| 1434 | o = createHLLObject(); |
| 1435 | double relerr = 1.04/sqrt(HLL_REGISTERS); |
| 1436 | int64_t checkpoint = 1; |
| 1437 | uint64_t seed = (uint64_t)rand() | (uint64_t)rand() << 32; |
| 1438 | uint64_t ele; |
| 1439 | for (j = 1; j <= 10000000; j++) { |
| 1440 | ele = j ^ seed; |
| 1441 | hllDenseAdd(hdr->registers,(unsigned char*)&ele,sizeof(ele)); |
| 1442 | hllAdd(o,(unsigned char*)&ele,sizeof(ele)); |
| 1443 | |
| 1444 | /* Make sure that for small cardinalities we use sparse |
| 1445 | * encoding. */ |
| 1446 | if (j == checkpoint && j < server.hll_sparse_max_bytes/2) { |
nothing calls this directly
no test coverage detected