36
#define FACETS_HASH XXH64_hash_t
37
#define FACETS_HASH_FUNCTION(src, len) XXH3_64bits(src, len)
38
#define FACETS_HASH_ZERO (FACETS_HASH)0
39
-#define FACETS_HASH_UNSAMPLED (FACETS_HASH)UINT64_MAX
39
+#define FACETS_HASH_UNSAMPLED (FACETS_HASH)(UINT64_MAX - 1)
40
+#define FACETS_HASH_ESTIMATED (FACETS_HASH)UINT64_MAX
41
42
static inline void facets_hash_to_str(FACETS_HASH num, char *out) {
43
out[11] = '\0';
192
typedef struct facet_value {
193
FACETS_HASH hash;
194
const char *name;
195
+ const char *color;
196
uint32_t name_len;
197
198
bool selected;
199
bool empty;
200
bool unsampled;
201
+ bool estimated;
202
203
uint32_t rows_matching_facet_value;
204
uint32_t final_facet_value_counter;
215
FACET_KEY_VALUE_UPDATED = (1 << 0),
216
FACET_KEY_VALUE_EMPTY = (1 << 1),
217
FACET_KEY_VALUE_UNSAMPLED = (1 << 2),
215
- FACET_KEY_VALUE_COPIED = (1 << 3),
218
+ FACET_KEY_VALUE_ESTIMATED = (1 << 3),
219
+ FACET_KEY_VALUE_COPIED = (1 << 4),
220
} FACET_KEY_VALUE_FLAGS;
221
222
#define facet_key_value_updated(k) ((k)->current_value.flags & FACET_KEY_VALUE_UPDATED)
223
#define facet_key_value_empty(k) ((k)->current_value.flags & FACET_KEY_VALUE_EMPTY)
224
#define facet_key_value_unsampled(k) ((k)->current_value.flags & FACET_KEY_VALUE_UNSAMPLED)
221
-#define facet_key_value_empty_or_unsampled(k) ((k)->current_value.flags & (FACET_KEY_VALUE_EMPTY|FACET_KEY_VALUE_UNSAMPLED))
225
+#define facet_key_value_estimated(k) ((k)->current_value.flags & FACET_KEY_VALUE_ESTIMATED)
226
+#define facet_key_value_empty_or_unsampled_or_estimated(k) ((k)->current_value.flags & (FACET_KEY_VALUE_EMPTY|FACET_KEY_VALUE_UNSAMPLED|FACET_KEY_VALUE_ESTIMATED))
227
#define facet_key_value_copied(k) ((k)->current_value.flags & FACET_KEY_VALUE_COPIED)
228
229
struct facet_key {
265
FACET_VALUE *v;
266
} unsampled_value;
267
268
+ struct {
269
+ FACET_VALUE *v;
270
+ } estimated_value;
271
+
272
struct {
273
facet_dynamic_row_t cb;
274
void *data;
368
size_t evaluated;
369
size_t matched;
370
size_t unsampled;
371
+ size_t estimated;
372
size_t created;
373
size_t reused;
374
} rows;
384
size_t dynamic;
385
size_t empty;
386
size_t unsampled;
387
+ size_t estimated;
388
size_t indexed;
389
size_t inserts;
390
size_t conflicts;
394
size_t searches;
395
} fts;
396
} operations;
397
+
398
+ struct {
399
+ DICTIONARY *used_hashes_registry;
400
+ } report;
401
};
402
403
usec_t facets_row_oldest_ut(FACETS *facets) {
522
523
memcpy(v, tv, sizeof(*v));
524
510
- DOUBLE_LINKED_LIST_APPEND_ITEM_UNSAFE(k->values.ll, v, prev, next);
525
+ if(v->estimated || v->unsampled) {
526
+ if(k->values.ll && k->values.ll->estimated) {
527
+ FACET_VALUE *estimated = k->values.ll;
528
+ DOUBLE_LINKED_LIST_INSERT_ITEM_AFTER_UNSAFE(k->values.ll, estimated, v, prev, next);
529
+ }
530
+ else
531
+ DOUBLE_LINKED_LIST_PREPEND_ITEM_UNSAFE(k->values.ll, v, prev, next);
532
+ }
533
+ else
534
+ DOUBLE_LINKED_LIST_APPEND_ITEM_UNSAFE(k->values.ll, v, prev, next);
535
+
536
k->values.used++;
537
538
if(!v->selected)
558
.hash = FACETS_HASH_UNSAMPLED,
559
.name = FACET_VALUE_UNSAMPLED,
560
.name_len = sizeof(FACET_VALUE_UNSAMPLED) - 1,
561
+ .unsampled = true,
562
+ .color = "offline",
563
};
564
565
k->current_value.hash = FACETS_HASH_UNSAMPLED;
576
}
577
}
578
579
+static inline void FACET_VALUE_ADD_ESTIMATED_VALUE_TO_INDEX(FACET_KEY *k) {
580
+ static const FACET_VALUE tv = {
581
+ .hash = FACETS_HASH_ESTIMATED,
582
+ .name = FACET_VALUE_ESTIMATED,
583
+ .name_len = sizeof(FACET_VALUE_ESTIMATED) - 1,
584
+ .estimated = true,
585
+ .color = "generic",
586
+ };
587
+
588
+ k->current_value.hash = FACETS_HASH_ESTIMATED;
589
+
590
+ if(k->estimated_value.v) {
591
+ FACET_VALUE_ADD_CONFLICT(k, k->estimated_value.v, &tv);
592
+ k->current_value.v = k->estimated_value.v;
593
+ }
594
+ else {
595
+ FACET_VALUE *v = FACET_VALUE_ADD_TO_INDEX(k, &tv);
596
+ v->estimated = true;
597
+ k->estimated_value.v = v;
598
+ k->current_value.v = v;
599
+ }
600
+}
601
+
602
static inline void FACET_VALUE_ADD_EMPTY_VALUE_TO_INDEX(FACET_KEY *k) {
603
static const FACET_VALUE tv = {
604
.hash = FACETS_HASH_ZERO,
605
.name = FACET_VALUE_UNSET,
606
.name_len = sizeof(FACET_VALUE_UNSET) - 1,
607
+ .empty = true,
608
};
609
610
k->current_value.hash = FACETS_HASH_ZERO;
629
tv.name = facets_key_get_value(k);
630
tv.name_len = facets_key_get_value_length(k);
631
tv.hash = FACETS_HASH_FUNCTION(tv.name, tv.name_len);
632
+ tv.empty = false;
633
+ tv.estimated = false;
634
+ tv.unsampled = false;
635
636
k->current_value.v = FACET_VALUE_ADD_TO_INDEX(k, &tv);
637
k->facets->operations.values.indexed++;
817
818
// ----------------------------------------------------------------------------
819
820
+size_t facets_histogram_slots(FACETS *facets) {
821
+ return facets->histogram.slots;
822
+}
823
+
824
static usec_t calculate_histogram_bar_width(usec_t after_ut, usec_t before_ut) {
825
// Array of valid durations in seconds
826
static time_t valid_durations_s[] = {
850
return ut - delta_ut;
851
}
852
795
-size_t facets_histogram_slots(FACETS *facets) {
796
- return facets->histogram.slots;
797
-}
798
-
853
void facets_set_timeframe_and_histogram_by_id(FACETS *facets, const char *key_id, usec_t after_ut, usec_t before_ut) {
854
if(after_ut > before_ut) {
855
usec_t t = after_ut;
893
facets_set_timeframe_and_histogram_by_id(facets, hash_str, after_ut, before_ut);
894
}
895
842
-static inline void facets_histogram_update_value_slot(FACETS *facets, usec_t usec, FACET_VALUE *v) {
896
+static inline uint32_t facets_histogram_slot_at_time_ut(FACETS *facets, usec_t usec, FACET_VALUE *v) {
897
if(unlikely(!v->histogram))
898
v->histogram = callocz(facets->histogram.slots, sizeof(*v->histogram));
899
910
if(unlikely(slot >= facets->histogram.slots))
911
slot = facets->histogram.slots - 1;
912
913
+ return slot;
914
+}
915
+
916
+static inline void facets_histogram_update_value_slot(FACETS *facets, usec_t usec, FACET_VALUE *v) {
917
+ uint32_t slot = facets_histogram_slot_at_time_ut(facets, usec, v);
918
v->histogram[slot]++;
919
}
920
931
facets_histogram_update_value_slot(facets, usec, v);
932
}
933
934
+void facets_update_estimations(FACETS *facets, usec_t from_ut, usec_t to_ut, size_t entries) {
935
+ facets->operations.rows.evaluated += entries;
936
+ facets->operations.rows.matched += entries;
937
+ facets->operations.rows.estimated += entries;
938
+
939
+ if (!facets->histogram.enabled ||
940
+ !facets->histogram.key ||
941
+ !facets->histogram.key->values.enabled)
942
+ return;
943
+
944
+ if (from_ut < facets->histogram.after_ut)
945
+ from_ut = facets->histogram.after_ut;
946
+
947
+ if (to_ut > facets->histogram.before_ut)
948
+ to_ut = facets->histogram.before_ut;
949
+
950
+ if (!facets->histogram.key->estimated_value.v)
951
+ FACET_VALUE_ADD_ESTIMATED_VALUE_TO_INDEX(facets->histogram.key);
952
+
953
+ FACET_VALUE *v = facets->histogram.key->estimated_value.v;
954
+
955
+ size_t from_slot = facets_histogram_slot_at_time_ut(facets, from_ut, v);
956
+ size_t to_slot = facets_histogram_slot_at_time_ut(facets, to_ut, v);
957
+ size_t total_ut = to_ut - from_ut;
958
+ ssize_t remaining_entries = (ssize_t)entries;
959
+
960
+ for (size_t slot = from_slot; slot <= to_slot; slot++) {
961
+ if (unlikely(slot >= facets->histogram.slots))
962
+ break;
963
+
964
+ usec_t slot_start_ut = facets->histogram.after_ut + slot * facets->histogram.slot_width_ut;
965
+ usec_t slot_end_ut = slot_start_ut + facets->histogram.slot_width_ut;
966
+ usec_t overlap_start_ut = (from_ut > slot_start_ut) ? from_ut : slot_start_ut;
967
+ usec_t overlap_end_ut = (to_ut < slot_end_ut) ? to_ut : slot_end_ut;
968
+ usec_t overlap_ut = (overlap_end_ut > overlap_start_ut) ? (overlap_end_ut - overlap_start_ut) : 0;
969
+
970
+ size_t slot_entries = (overlap_ut * entries) / total_ut;
971
+ v->histogram[slot] += slot_entries;
972
+ remaining_entries -= (ssize_t)slot_entries;
973
+ }
974
+
975
+ // Check if all entries are assigned
976
+ // This should always be true if the distribution is correct
977
+ internal_fatal(remaining_entries < 0 || remaining_entries > (ssize_t)(to_slot - from_slot),
978
+ "distribution of estimations is not accurate - there are %zd remaining entries",
979
+ remaining_entries);
980
+}
981
+
982
void facets_row_finished_unsampled(FACETS *facets, usec_t usec) {
983
facets->operations.rows.evaluated++;
984
facets->operations.rows.matched++;
1000
facets_reset_key(facets->histogram.key);
1001
}
1002
1003
+static const char *facets_key_name_cached(FACET_KEY *k, DICTIONARY *used_hashes_registry) {
1004
+ if(k->name) {
1005
+ if(used_hashes_registry && !k->default_selected_for_values) {
1006
+ char hash_str[FACET_STRING_HASH_SIZE];
1007
+ facets_hash_to_str(k->hash, hash_str);
1008
+ dictionary_set(used_hashes_registry, hash_str, (void *)k->name, strlen(k->name) + 1);
1009
+ }
1010
+
1011
+ return k->name;
1012
+ }
1013
+
1014
+ // key has no name
1015
+ const char *name = "[UNAVAILABLE_FIELD]";
1016
+
1017
+ if(used_hashes_registry) {
1018
+ char hash_str[FACET_STRING_HASH_SIZE];
1019
+ facets_hash_to_str(k->hash, hash_str);
1020
+ const char *s = dictionary_get(used_hashes_registry, hash_str);
1021
+ if(s) name = s;
1022
+ }
1023
+
1024
+ return name;
1025
+}
1026
+
1027
+static const char *facets_key_value_cached(FACET_KEY *k, FACET_VALUE *v, DICTIONARY *used_hashes_registry) {
1028
+ if(v->empty || v->estimated || v->unsampled)
1029
+ return v->name;
1030
+
1031
+ if(v->name && v->name_len) {
1032
+ if(used_hashes_registry && !k->default_selected_for_values && v->selected) {
1033
+ char hash_str[FACET_STRING_HASH_SIZE];
1034
+ facets_hash_to_str(v->hash, hash_str);
1035
+ dictionary_set(used_hashes_registry, hash_str, (void *)v->name, v->name_len + 1);
1036
+ }
1037
+
1038
+ return v->name;
1039
+ }
1040
+
1041
+ // key has no name
1042
+ const char *name = "[unavailable field]";
1043
+
1044
+ if(used_hashes_registry) {
1045
+ char hash_str[FACET_STRING_HASH_SIZE];
1046
+ facets_hash_to_str(v->hash, hash_str);
1047
+ const char *s = dictionary_get(used_hashes_registry, hash_str);
1048
+ if(s) name = s;
1049
+ }
1050
+
1051
+ return name;
1052
+}
1053
+
1054
+static inline void facets_key_value_transformed(FACETS *facets, FACET_KEY *k, FACET_VALUE *v, BUFFER *dst, FACETS_TRANSFORMATION_SCOPE scope) {
1055
+ buffer_flush(dst);
1056
+
1057
+ if(v->empty || v->unsampled || v->estimated)
1058
+ buffer_strcat(dst, v->name);
1059
+ else if(k->transform.cb && k->transform.view_only) {
1060
+ buffer_contents_replace(dst, v->name, v->name_len);
1061
+ k->transform.cb(facets, dst, scope, k->transform.data);
1062
+ }
1063
+ else
1064
+ buffer_strcat(dst, facets_key_value_cached(k, v, facets->report.used_hashes_registry));
1065
+}
1066
+
1067
static inline void facets_histogram_value_names(BUFFER *wb, FACETS *facets __maybe_unused, FACET_KEY *k, const char *key, const char *first_key) {
897
- BUFFER *tb = NULL;
1068
+ CLEAN_BUFFER *tb = buffer_create(0, NULL);
1069
1070
buffer_json_member_add_array(wb, key);
1071
{
1078
if (unlikely(!v->histogram))
1079
continue;
1080
910
- if(!v->empty && k->transform.cb && k->transform.view_only) {
911
- if(!tb)
912
- tb = buffer_create(0, NULL);
913
-
914
- buffer_contents_replace(tb, v->name, v->name_len);
915
- k->transform.cb(facets, tb, FACETS_TRANSFORM_HISTOGRAM, k->transform.data);
916
- buffer_json_add_array_item_string(wb, buffer_tostring(tb));
917
- }
918
- else
919
- buffer_json_add_array_item_string(wb, v->name);
1081
+ facets_key_value_transformed(facets, k, v, tb, FACETS_TRANSFORM_HISTOGRAM);
1082
+ buffer_json_add_array_item_string(wb, buffer_tostring(tb));
1083
}
1084
foreach_value_in_key_done(v);
1085
}
1086
}
1087
buffer_json_array_close(wb); // key
1088
+}
1089
926
- buffer_free(tb);
1090
+static inline void facets_histogram_value_colors(BUFFER *wb, FACETS *facets __maybe_unused, FACET_KEY *k, const char *key) {
1091
+ buffer_json_member_add_array(wb, key);
1092
+ {
1093
+ if(k && k->values.enabled) {
1094
+ FACET_VALUE *v;
1095
+ foreach_value_in_key(k, v) {
1096
+ if (unlikely(!v->histogram))
1097
+ continue;
1098
+
1099
+ buffer_json_add_array_item_string(wb, v->color);
1100
+ }
1101
+ foreach_value_in_key_done(v);
1102
+ }
1103
+ }
1104
+ buffer_json_array_close(wb); // key
1105
}
1106
1107
static inline void facets_histogram_value_units(BUFFER *wb, FACETS *facets __maybe_unused, FACET_KEY *k, const char *key) {
1207
}
1208
1209
static void facets_histogram_generate(FACETS *facets, FACET_KEY *k, BUFFER *wb) {
1210
+ CLEAN_BUFFER *tmp = buffer_create(0, NULL);
1211
+
1212
size_t dimensions = 0;
1213
uint32_t min = UINT32_MAX, max = 0, sum = 0, count = 0;
1214
1250
1251
buffer_json_member_add_object(wb, "summary");
1252
{
1253
+ // summary.nodes
1254
buffer_json_member_add_array(wb, "nodes");
1255
{
1256
buffer_json_add_array_item_object(wb); // node
1297
}
1298
buffer_json_array_close(wb); // nodes
1299
1300
+ // summary.contexts
1301
buffer_json_member_add_array(wb, "contexts");
1302
{
1303
buffer_json_add_array_item_object(wb); // context
1335
}
1336
buffer_json_array_close(wb); // contexts
1337
1338
+ // summary.instances
1339
buffer_json_member_add_array(wb, "instances");
1340
{
1341
buffer_json_add_array_item_object(wb); // instance
1367
}
1368
buffer_json_array_close(wb); // instances
1369
1370
+ // summary.dimensions
1371
buffer_json_member_add_array(wb, "dimensions");
1372
if(dimensions && k && k->values.enabled) {
1373
size_t pri = 0;
1374
FACET_VALUE *v;
1375
+
1376
foreach_value_in_key(k, v) {
1377
if(unlikely(!v->histogram))
1378
continue;
1379
1380
buffer_json_add_array_item_object(wb); // dimension
1381
{
1197
- buffer_json_member_add_string(wb, "id", v->name);
1382
+ facets_key_value_transformed(facets, k, v, tmp, FACETS_TRANSFORM_HISTOGRAM);
1383
+ buffer_json_member_add_string(wb, "id", buffer_tostring(tmp));
1384
buffer_json_member_add_object(wb, "ds");
1385
{
1386
buffer_json_member_add_uint64(wb, "sl", 1);
1554
1555
facets_histogram_value_names(wb, facets, k, "ids", NULL);
1556
facets_histogram_value_names(wb, facets, k, "names", NULL);
1557
+ facets_histogram_value_colors(wb, facets, k, "colors");
1558
facets_histogram_value_units(wb, facets, k, "units");
1559
1560
buffer_json_member_add_object(wb, "sts");
1840
facets->keys_in_row.array[facets->keys_in_row.used++] = k;
1841
1842
k->current_value.flags |= FACET_KEY_VALUE_UPDATED;
1656
- k->current_value.flags &= ~(FACET_KEY_VALUE_EMPTY|FACET_KEY_VALUE_UNSAMPLED);
1843
+ k->current_value.flags &= ~(FACET_KEY_VALUE_EMPTY|FACET_KEY_VALUE_UNSAMPLED|FACET_KEY_VALUE_ESTIMATED);
1844
1845
facets->operations.values.registered++;
1846
1854
// if(strstr(buffer_tostring(k->current_value), "fprintd") != NULL)
1855
// found = true;
1856
1670
- if(facets->query && !facet_key_value_empty_or_unsampled(k) && ((k->options & FACET_KEY_OPTION_FTS) || facets->options & FACETS_OPTION_ALL_KEYS_FTS)) {
1857
+ if(facets->query && !facet_key_value_empty_or_unsampled_or_estimated(k) && ((k->options & FACET_KEY_OPTION_FTS) || facets->options & FACETS_OPTION_ALL_KEYS_FTS)) {
1858
facets->operations.fts.searches++;
1859
facets_key_value_copy_to_buffer(k);
1860
switch(simple_pattern_matches_extract(facets->query, buffer_tostring(k->current_value.b), NULL, 0)) {
1965
.empty = true,
1966
};
1967
1781
- if(facet_key_value_updated(k) && !facet_key_value_empty_or_unsampled(k)) {
1968
+ if(facet_key_value_updated(k) && !facet_key_value_empty_or_unsampled_or_estimated(k)) {
1969
t.tmp = facets_key_get_value(k);
1970
t.tmp_len = facets_key_get_value_length(k);
1971
t.empty = false;
2397
if(!k->values.enabled || !k->values.ll || !k->values.used)
2398
return 0;
2399
2213
- if(!k->transform.cb || !(k->facets->options & FACETS_OPTION_SORT_FACETS_ALPHABETICALLY))
2400
+ if(!k->transform.cb || !k->transform.view_only || !(k->facets->options & FACETS_OPTION_SORT_FACETS_ALPHABETICALLY))
2401
return facets_sort_and_reorder_values_internal(k);
2402
2403
// we have a transformation and has to be sorted alphabetically
2421
values[used].name_len = v->name_len;
2422
used++;
2423
2237
- buffer_contents_replace(tb, v->name, v->name_len);
2238
- k->transform.cb(k->facets, tb, FACETS_TRANSFORM_FACET_SORT, k->transform.data);
2424
+ facets_key_value_transformed(k->facets, k, v, tb, FACETS_TRANSFORM_FACET_SORT);
2425
v->name = strdupz(buffer_tostring(tb));
2426
v->name_len = buffer_strlen(tb);
2427
}
2459
buffer_json_object_close(wb); // pagination
2460
}
2461
2276
-static const char *facets_json_key_name_string(FACET_KEY *k, DICTIONARY *used_hashes_registry) {
2277
- if(k->name) {
2278
- if(used_hashes_registry && !k->default_selected_for_values) {
2279
- char hash_str[FACET_STRING_HASH_SIZE];
2280
- facets_hash_to_str(k->hash, hash_str);
2281
- dictionary_set(used_hashes_registry, hash_str, (void *)k->name, strlen(k->name) + 1);
2282
- }
2283
-
2284
- return k->name;
2285
- }
2286
-
2287
- // key has no name
2288
- const char *name = "[UNAVAILABLE_FIELD]";
2289
-
2290
- if(used_hashes_registry) {
2291
- char hash_str[FACET_STRING_HASH_SIZE];
2292
- facets_hash_to_str(k->hash, hash_str);
2293
- const char *s = dictionary_get(used_hashes_registry, hash_str);
2294
- if(s) name = s;
2295
- }
2296
-
2297
- return name;
2298
-}
2299
-
2300
-static const char *facets_json_key_value_string(FACET_KEY *k, FACET_VALUE *v, DICTIONARY *used_hashes_registry) {
2301
- if(v->name && v->name_len) {
2302
- if(used_hashes_registry && !k->default_selected_for_values && v->selected) {
2303
- char hash_str[FACET_STRING_HASH_SIZE];
2304
- facets_hash_to_str(v->hash, hash_str);
2305
- dictionary_set(used_hashes_registry, hash_str, (void *)v->name, v->name_len + 1);
2306
- }
2307
-
2308
- return v->name;
2309
- }
2310
-
2311
- // key has no name
2312
- const char *name = "[unavailable field]";
2313
-
2314
- if(used_hashes_registry) {
2315
- char hash_str[FACET_STRING_HASH_SIZE];
2316
- facets_hash_to_str(v->hash, hash_str);
2317
- const char *s = dictionary_get(used_hashes_registry, hash_str);
2318
- if(s) name = s;
2319
- }
2320
-
2321
- return name;
2322
-}
2323
-
2462
void facets_report(FACETS *facets, BUFFER *wb, DICTIONARY *used_hashes_registry) {
2463
+ facets->report.used_hashes_registry = used_hashes_registry;
2464
+
2465
if(!(facets->options & FACETS_OPTION_DATA_ONLY)) {
2466
facets_table_config(wb);
2467
facets_accepted_parameters_to_json_array(facets, wb, true);
2485
}
2486
2487
if(show_facets) {
2348
- BUFFER *tb = NULL;
2488
+ CLEAN_BUFFER *tb = buffer_create(0, NULL);
2489
FACET_KEY *k;
2490
foreach_key_in_facets(facets, k) {
2491
if(!k->values.enabled)
2498
buffer_json_add_array_item_object(wb); // key
2499
{
2500
buffer_json_member_add_string(wb, "id", hash_to_static_string(k->hash));
2361
- buffer_json_member_add_string(wb, "name", facets_json_key_name_string(k, used_hashes_registry));
2501
+ buffer_json_member_add_string(wb, "name", facets_key_name_cached(k
2502
+ , facets->report.used_hashes_registry
2503
+ ));
2504
2505
if(!k->order) k->order = facets->order++;
2506
buffer_json_member_add_uint64(wb, "order", k->order);
2512
if((facets->options & FACETS_OPTION_DONT_SEND_EMPTY_VALUE_FACETS) && v->empty)
2513
continue;
2514
2515
+ if(v->unsampled || v->estimated)
2516
+ continue;
2517
+
2518
buffer_json_add_array_item_object(wb);
2519
{
2520
buffer_json_member_add_string(wb, "id", hash_to_static_string(v->hash));
2521
2377
- if(!v->empty && k->transform.cb && k->transform.view_only) {
2378
- if(!tb)
2379
- tb = buffer_create(0, NULL);
2380
-
2381
- buffer_contents_replace(tb, v->name, v->name_len);
2382
- k->transform.cb(facets, tb, FACETS_TRANSFORM_FACET, k->transform.data);
2383
- buffer_json_member_add_string(wb, "name", buffer_tostring(tb));
2384
- }
2385
- else
2386
- buffer_json_member_add_string(wb, "name", facets_json_key_value_string(k, v, used_hashes_registry));
2387
-
2522
+ facets_key_value_transformed(facets, k, v, tb, FACETS_TRANSFORM_FACET);
2523
+ buffer_json_member_add_string(wb, "name", buffer_tostring(tb));
2524
buffer_json_member_add_uint64(wb, "count", v->final_facet_value_counter);
2525
buffer_json_member_add_uint64(wb, "order", v->order);
2526
}
2533
buffer_json_object_close(wb); // key
2534
}
2535
foreach_key_in_facets_done(k);
2400
- buffer_free(tb);
2536
buffer_json_array_close(wb); // facets
2537
}
2538
}
2747
buffer_json_member_add_uint64(wb, "evaluated", facets->operations.rows.evaluated);
2748
buffer_json_member_add_uint64(wb, "matched", facets->operations.rows.matched);
2749
buffer_json_member_add_uint64(wb, "unsampled", facets->operations.rows.unsampled);
2750
+ buffer_json_member_add_uint64(wb, "estimated", facets->operations.rows.estimated);
2751
buffer_json_member_add_uint64(wb, "returned", facets->items_to_return);
2752
buffer_json_member_add_uint64(wb, "max_to_return", facets->max_items_to_return);
2753
buffer_json_member_add_uint64(wb, "before", facets->operations.skips_before);
2812
buffer_json_member_add_uint64(wb, "transformed", facets->operations.values.transformed);
2813
buffer_json_member_add_uint64(wb, "dynamic", facets->operations.values.dynamic);
2814
buffer_json_member_add_uint64(wb, "empty", facets->operations.values.empty);
2815
+ buffer_json_member_add_uint64(wb, "unsampled", facets->operations.values.unsampled);
2816
+ buffer_json_member_add_uint64(wb, "estimated", facets->operations.values.estimated);
2817
buffer_json_member_add_uint64(wb, "indexed", facets->operations.values.indexed);
2818
buffer_json_member_add_uint64(wb, "inserts", facets->operations.values.inserts);
2819
buffer_json_member_add_uint64(wb, "conflicts", facets->operations.values.conflicts);