Browse Source

Revert "Optimizations Part 2" (#15279)

Revert "Optimizations Part 2 (#15267)"

This reverts commit b52a989497f68cddeeb0282f5fd650c4e373e477.
Costa Tsaousis 1 year ago
parent
commit
a88c968b9c

+ 29 - 38
collectors/plugins.d/gperf-config.txt

@@ -1,52 +1,43 @@
-%struct-type
-%omit-struct-type
-%define hash-function-name gperf_keyword_hash_function
-%define lookup-function-name gperf_lookup_keyword
-%define word-array-name gperf_keywords
-%define constants-prefix GPERF_PARSER_
-%define slot-name keyword
-%global-table
-%null-strings
 PARSER_KEYWORD;
 %%
 #
 # Plugins Only Keywords
 #
-FLUSH,                  97, PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 1
-DISABLE,                98, PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 2
-EXIT,                   99, PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 3
-HOST,                   71, PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 4
-HOST_DEFINE,            72, PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 5
-HOST_DEFINE_END,        73, PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 6
-HOST_LABEL,             74, PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 7
+FLUSH,                  pluginsd_flush,                             PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 1
+DISABLE,                pluginsd_disable,                           PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 2
+EXIT,                   pluginsd_exit,                              PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 3
+HOST,                   pluginsd_host,                              PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 4
+HOST_DEFINE,            pluginsd_host_define,                       PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 5
+HOST_DEFINE_END,        pluginsd_host_define_end,                   PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 6
+HOST_LABEL,             pluginsd_host_labels,                       PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 7
 #
 # Common keywords
 #
-BEGIN,                  12, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 8
-CHART,                  32, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 9
-CLABEL,                 34, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 10
-CLABEL_COMMIT,          35, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 11
-DIMENSION,              31, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 12
-END,                    13, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 13
-FUNCTION,               41, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 14
-FUNCTION_RESULT_BEGIN,  42, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 15
-LABEL,                  51, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 16
-OVERWRITE,              52, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 17
-SET,                    11, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 18
-VARIABLE,               53, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 19
+BEGIN,                  pluginsd_begin,                             PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 8
+CHART,                  pluginsd_chart,                             PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 9
+CLABEL,                 pluginsd_clabel,                            PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 10
+CLABEL_COMMIT,          pluginsd_clabel_commit,                     PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 11
+DIMENSION,              pluginsd_dimension,                         PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 12
+END,                    pluginsd_end,                               PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 13
+FUNCTION,               pluginsd_function,                          PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 14
+FUNCTION_RESULT_BEGIN,  pluginsd_function_result_begin,             PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 15
+LABEL,                  pluginsd_label,                             PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 16
+OVERWRITE,              pluginsd_overwrite,                         PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 17
+SET,                    pluginsd_set,                               PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 18
+VARIABLE,               pluginsd_variable,                          PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 19
 #
 # Streaming only keywords
 #
-CLAIMED_ID,             61, PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 20
-BEGIN2,                  2, PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 21
-SET2,                    1, PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 22
-END2,                    3, PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 23
+CLAIMED_ID,             streaming_claimed_id,                       PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 20
+BEGIN2,                 pluginsd_begin_v2,                          PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 21
+SET2,                   pluginsd_set_v2,                            PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 22
+END2,                   pluginsd_end_v2,                            PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 23
 #
 # Streaming Replication keywords
 #
-CHART_DEFINITION_END,   33, PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 24
-RBEGIN,                 22, PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 25
-RDSTATE,                23, PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 26
-REND,                   25, PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 27
-RSET,                   21, PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 28
-RSSTATE,                24, PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 29
+CHART_DEFINITION_END,   pluginsd_chart_definition_end,              PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 24
+RBEGIN,                 pluginsd_replay_begin,                      PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 25
+RDSTATE,                pluginsd_replay_rrddim_collection_state,    PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 26
+REND,                   pluginsd_replay_end,                        PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 27
+RSET,                   pluginsd_replay_set,                        PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 28
+RSSTATE,                pluginsd_replay_rrdset_collection_state,    PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 29

+ 56 - 55
collectors/plugins.d/gperf-hashtable.h

@@ -1,5 +1,6 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
 /* ANSI-C code produced by gperf version 3.1 */
-/* Command-line: gperf --multiple-iterations=1000 --output-file=gperf-hashtable.h gperf-config.txt  */
+/* Command-line: gperf --multiple-iterations=1000 --hash-function-name=gperf_keyword_hash_function --lookup-function-name=gperf_lookup_keyword --word-array-name=gperf_keywords --constants-prefix=GPERF_PARSER_ --struct-type --slot-name=keyword --global-table --null-strings --omit-struct-type --output-file=gperf-hashtable.h gperf-config.txt  */
 /* Computed positions: -k'1-2' */
 
 #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
@@ -82,66 +83,66 @@ gperf_keyword_hash_function (register const char *str, register size_t len)
 static PARSER_KEYWORD gperf_keywords[] =
   {
     {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
-#line 18 "gperf-config.txt"
-    {"HOST",                   71, PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 4},
-#line 51 "gperf-config.txt"
-    {"RSET",                   21, PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 28},
-#line 26 "gperf-config.txt"
-    {"CHART",                  32, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 9},
-    {(char*)0},
-#line 52 "gperf-config.txt"
-    {"RSSTATE",                24, PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 29},
-#line 49 "gperf-config.txt"
-    {"RDSTATE",                23, PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 26},
-#line 21 "gperf-config.txt"
-    {"HOST_LABEL",             74, PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 7},
-#line 19 "gperf-config.txt"
-    {"HOST_DEFINE",            72, PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 5},
-#line 35 "gperf-config.txt"
-    {"SET",                    11, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 18},
+#line 9 "gperf-config.txt"
+    {"HOST",                   pluginsd_host,                              PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 4},
 #line 42 "gperf-config.txt"
-    {"SET2",                    1, PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 22},
-#line 50 "gperf-config.txt"
-    {"REND",                   25, PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 27},
-#line 20 "gperf-config.txt"
-    {"HOST_DEFINE_END",        73, PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 6},
-#line 27 "gperf-config.txt"
-    {"CLABEL",                 34, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 10},
-#line 48 "gperf-config.txt"
-    {"RBEGIN",                 22, PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 25},
-#line 15 "gperf-config.txt"
-    {"FLUSH",                  97, PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 1},
-#line 31 "gperf-config.txt"
-    {"FUNCTION",               41, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 14},
+    {"RSET",                   pluginsd_replay_set,                        PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 28},
+#line 17 "gperf-config.txt"
+    {"CHART",                  pluginsd_chart,                             PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 9},
+    {(char*)0},
+#line 43 "gperf-config.txt"
+    {"RSSTATE",                pluginsd_replay_rrdset_collection_state,    PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 29},
 #line 40 "gperf-config.txt"
-    {"CLAIMED_ID",             61, PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 20},
-#line 47 "gperf-config.txt"
-    {"CHART_DEFINITION_END",   33, PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 24},
-#line 34 "gperf-config.txt"
-    {"OVERWRITE",              52, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 17},
-#line 28 "gperf-config.txt"
-    {"CLABEL_COMMIT",          35, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 11},
-#line 25 "gperf-config.txt"
-    {"BEGIN",                  12, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 8},
+    {"RDSTATE",                pluginsd_replay_rrddim_collection_state,    PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 26},
+#line 12 "gperf-config.txt"
+    {"HOST_LABEL",             pluginsd_host_labels,                       PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 7},
+#line 10 "gperf-config.txt"
+    {"HOST_DEFINE",            pluginsd_host_define,                       PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 5},
+#line 26 "gperf-config.txt"
+    {"SET",                    pluginsd_set,                               PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 18},
+#line 33 "gperf-config.txt"
+    {"SET2",                   pluginsd_set_v2,                            PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 22},
 #line 41 "gperf-config.txt"
-    {"BEGIN2",                  2, PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 21},
-#line 30 "gperf-config.txt"
-    {"END",                    13, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 13},
-#line 43 "gperf-config.txt"
-    {"END2",                    3, PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 23},
+    {"REND",                   pluginsd_replay_end,                        PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 27},
+#line 11 "gperf-config.txt"
+    {"HOST_DEFINE_END",        pluginsd_host_define_end,                   PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 6},
+#line 18 "gperf-config.txt"
+    {"CLABEL",                 pluginsd_clabel,                            PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 10},
+#line 39 "gperf-config.txt"
+    {"RBEGIN",                 pluginsd_replay_begin,                      PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 25},
+#line 6 "gperf-config.txt"
+    {"FLUSH",                  pluginsd_flush,                             PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 1},
+#line 22 "gperf-config.txt"
+    {"FUNCTION",               pluginsd_function,                          PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 14},
+#line 31 "gperf-config.txt"
+    {"CLAIMED_ID",             streaming_claimed_id,                       PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 20},
+#line 38 "gperf-config.txt"
+    {"CHART_DEFINITION_END",   pluginsd_chart_definition_end,              PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 24},
+#line 25 "gperf-config.txt"
+    {"OVERWRITE",              pluginsd_overwrite,                         PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 17},
+#line 19 "gperf-config.txt"
+    {"CLABEL_COMMIT",          pluginsd_clabel_commit,                     PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 11},
 #line 16 "gperf-config.txt"
-    {"DISABLE",                98, PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 2},
-#line 33 "gperf-config.txt"
-    {"LABEL",                  51, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 16},
-#line 29 "gperf-config.txt"
-    {"DIMENSION",              31, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 12},
-#line 17 "gperf-config.txt"
-    {"EXIT",                   99, PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 3},
+    {"BEGIN",                  pluginsd_begin,                             PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 8},
 #line 32 "gperf-config.txt"
-    {"FUNCTION_RESULT_BEGIN",  42, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 15},
+    {"BEGIN2",                 pluginsd_begin_v2,                          PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 21},
+#line 21 "gperf-config.txt"
+    {"END",                    pluginsd_end,                               PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 13},
+#line 34 "gperf-config.txt"
+    {"END2",                   pluginsd_end_v2,                            PARSER_INIT_STREAMING,                       WORKER_PARSER_FIRST_JOB + 23},
+#line 7 "gperf-config.txt"
+    {"DISABLE",                pluginsd_disable,                           PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 2},
+#line 24 "gperf-config.txt"
+    {"LABEL",                  pluginsd_label,                             PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 16},
+#line 20 "gperf-config.txt"
+    {"DIMENSION",              pluginsd_dimension,                         PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 12},
+#line 8 "gperf-config.txt"
+    {"EXIT",                   pluginsd_exit,                              PARSER_INIT_PLUGINSD,                       WORKER_PARSER_FIRST_JOB + 3},
+#line 23 "gperf-config.txt"
+    {"FUNCTION_RESULT_BEGIN",  pluginsd_function_result_begin,             PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 15},
     {(char*)0}, {(char*)0}, {(char*)0},
-#line 36 "gperf-config.txt"
-    {"VARIABLE",               53, PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 19}
+#line 27 "gperf-config.txt"
+    {"VARIABLE",               pluginsd_variable,                          PARSER_INIT_PLUGINSD|PARSER_INIT_STREAMING, WORKER_PARSER_FIRST_JOB + 19}
   };
 
 PARSER_KEYWORD *

+ 0 - 94
collectors/plugins.d/pluginsd_parser.c

@@ -2026,100 +2026,6 @@ PARSER *parser_init(struct parser_user_object *user, FILE *fp_input, FILE *fp_ou
     return parser;
 }
 
-PARSER_RC parser_execute(PARSER *parser, PARSER_KEYWORD *keyword, char **words, size_t num_words) {
-    switch(keyword->id) {
-        case 1:
-            return pluginsd_set_v2(words, num_words, parser);
-
-        case 2:
-            return pluginsd_begin_v2(words, num_words, parser);
-
-        case 3:
-            return pluginsd_end_v2(words, num_words, parser);
-
-        case 11:
-            return pluginsd_set(words, num_words, parser);
-
-        case 12:
-            return pluginsd_begin(words, num_words, parser);
-
-        case 13:
-            return pluginsd_end(words, num_words, parser);
-
-        case 21:
-            return pluginsd_replay_set(words, num_words, parser);
-
-        case 22:
-            return pluginsd_replay_begin(words, num_words, parser);
-
-        case 23:
-            return pluginsd_replay_rrddim_collection_state(words, num_words, parser);
-
-        case 24:
-            return pluginsd_replay_rrdset_collection_state(words, num_words, parser);
-
-        case 25:
-            return pluginsd_replay_end(words, num_words, parser);
-
-        case 31:
-            return pluginsd_dimension(words, num_words, parser);
-
-        case 32:
-            return pluginsd_chart(words, num_words, parser);
-
-        case 33:
-            return pluginsd_chart_definition_end(words, num_words, parser);
-
-        case 34:
-            return pluginsd_clabel(words, num_words, parser);
-
-        case 35:
-            return pluginsd_clabel_commit(words, num_words, parser);
-
-        case 41:
-            return pluginsd_function(words, num_words, parser);
-
-        case 42:
-            return pluginsd_function_result_begin(words, num_words, parser);
-
-        case 51:
-            return pluginsd_label(words, num_words, parser);
-
-        case 52:
-            return pluginsd_overwrite(words, num_words, parser);
-
-        case 53:
-            return pluginsd_variable(words, num_words, parser);
-
-        case 61:
-            return streaming_claimed_id(words, num_words, parser);
-
-        case 71:
-            return pluginsd_host(words, num_words, parser);
-
-        case 72:
-            return pluginsd_host_define(words, num_words, parser);
-
-        case 73:
-            return pluginsd_host_define_end(words, num_words, parser);
-
-        case 74:
-            return pluginsd_host_labels(words, num_words, parser);
-
-        case 97:
-            return pluginsd_flush(words, num_words, parser);
-
-        case 98:
-            return pluginsd_disable(words, num_words, parser);
-
-        case 99:
-            return pluginsd_exit(words, num_words, parser);
-
-        default:
-            fatal("Unknown keyword '%s' with id %zu", keyword->keyword, keyword->id);
-    }
-}
-
 #include "gperf-hashtable.h"
 
 void parser_init_repertoire(PARSER *parser, PARSER_REPERTOIRE repertoire) {

+ 9 - 11
collectors/plugins.d/pluginsd_parser.h

@@ -32,7 +32,7 @@ typedef PARSER_RC (*keyword_function)(char **words, size_t num_words, struct par
 
 typedef struct parser_keyword {
     char *keyword;
-    size_t id;
+    keyword_function func;
     PARSER_REPERTOIRE repertoire;
     size_t worker_job_id;
 } PARSER_KEYWORD;
@@ -113,14 +113,6 @@ typedef struct parser {
 
 } PARSER;
 
-PARSER *parser_init(struct parser_user_object *user, FILE *fp_input, FILE *fp_output, int fd, PARSER_INPUT_TYPE flags, void *ssl);
-void parser_init_repertoire(PARSER *parser, PARSER_REPERTOIRE repertoire);
-void parser_destroy(PARSER *working_parser);
-void pluginsd_cleanup_v2(PARSER *parser);
-void inflight_functions_init(PARSER *parser);
-void pluginsd_keywords_init(PARSER *parser, PARSER_REPERTOIRE repertoire);
-PARSER_RC parser_execute(PARSER *parser, PARSER_KEYWORD *keyword, char **words, size_t num_words);
-
 static inline int find_first_keyword(const char *src, char *dst, int dst_size, bool *isspace_map) {
     const char *s = src, *keyword_start;
 
@@ -189,8 +181,7 @@ static inline int parser_action(PARSER *parser, char *input) {
     PARSER_KEYWORD *t = parser_find_keyword(parser, command);
     if(likely(t)) {
         worker_is_busy(t->worker_job_id);
-        rc = parser_execute(parser, t, words, num_words);
-        // rc = (*t->func)(words, num_words, parser);
+        rc = (*t->func)(words, num_words, parser);
         worker_is_idle();
     }
     else
@@ -216,4 +207,11 @@ static inline int parser_action(PARSER *parser, char *input) {
     return (rc == PARSER_RC_ERROR || rc == PARSER_RC_STOP);
 }
 
+PARSER *parser_init(struct parser_user_object *user, FILE *fp_input, FILE *fp_output, int fd, PARSER_INPUT_TYPE flags, void *ssl);
+void parser_init_repertoire(PARSER *parser, PARSER_REPERTOIRE repertoire);
+void parser_destroy(PARSER *working_parser);
+void pluginsd_cleanup_v2(PARSER *parser);
+void inflight_functions_init(PARSER *parser);
+void pluginsd_keywords_init(PARSER *parser, PARSER_REPERTOIRE repertoire);
+
 #endif //NETDATA_PLUGINSD_PARSER_H

+ 0 - 3
daemon/common.c

@@ -58,9 +58,6 @@ long get_netdata_cpus(void) {
 
     processors = cores_user_configured;
 
-    if(processors < 1)
-        processors = 1;
-
     return processors;
 }
 

+ 86 - 61
database/engine/metric.c

@@ -28,16 +28,27 @@ struct metric {
 static struct aral_statistics mrg_aral_statistics;
 
 struct mrg {
-    size_t partitions;
+    ARAL *aral[MRG_PARTITIONS];
 
-    struct mrg_partition {
-        ARAL *aral;                 // not protected by our spinlock - it has its own
+    struct pgc_index {
+        MRG_CACHE_LINE_PADDING(0);
 
         RW_SPINLOCK rw_spinlock;
-        Pvoid_t uuid_judy;          // JudyHS: each UUID has a JudyL of sections (tiers)
+
+        MRG_CACHE_LINE_PADDING(1);
+
+        Pvoid_t uuid_judy;          // each UUID has a JudyL of sections (tiers)
+
+        MRG_CACHE_LINE_PADDING(2);
 
         struct mrg_statistics stats;
-    } index[];
+
+        MRG_CACHE_LINE_PADDING(3);
+    } index[MRG_PARTITIONS];
+
+#ifdef NETDATA_INTERNAL_CHECKS
+    size_t entries_per_partition[MRG_PARTITIONS];
+#endif
 };
 
 static inline void MRG_STATS_DUPLICATE_ADD(MRG *mrg, size_t partition) {
@@ -48,12 +59,20 @@ static inline void MRG_STATS_ADDED_METRIC(MRG *mrg, size_t partition) {
     mrg->index[partition].stats.entries++;
     mrg->index[partition].stats.additions++;
     mrg->index[partition].stats.size += sizeof(METRIC);
+
+#ifdef NETDATA_INTERNAL_CHECKS
+    __atomic_add_fetch(&mrg->entries_per_partition[partition], 1, __ATOMIC_RELAXED);
+#endif
 }
 
 static inline void MRG_STATS_DELETED_METRIC(MRG *mrg, size_t partition) {
     mrg->index[partition].stats.entries--;
     mrg->index[partition].stats.size -= sizeof(METRIC);
     mrg->index[partition].stats.deletions++;
+
+#ifdef NETDATA_INTERNAL_CHECKS
+    __atomic_sub_fetch(&mrg->entries_per_partition[partition], 1, __ATOMIC_RELAXED);
+#endif
 }
 
 static inline void MRG_STATS_SEARCH_HIT(MRG *mrg, size_t partition) {
@@ -68,13 +87,18 @@ static inline void MRG_STATS_DELETE_MISS(MRG *mrg, size_t partition) {
     mrg->index[partition].stats.delete_misses++;
 }
 
-#define mrg_index_read_lock(mrg, partition) rw_spinlock_read_lock(&(mrg)->index[partition].rw_spinlock)
-#define mrg_index_read_unlock(mrg, partition) rw_spinlock_read_unlock(&(mrg)->index[partition].rw_spinlock)
-#define mrg_index_write_lock(mrg, partition) rw_spinlock_write_lock(&(mrg)->index[partition].rw_spinlock)
-#define mrg_index_write_unlock(mrg, partition) rw_spinlock_write_unlock(&(mrg)->index[partition].rw_spinlock)
-
-#define metric_lock(metric) spinlock_lock(&(metric)->spinlock)
-#define metric_unlock(metric) spinlock_unlock(&(metric)->spinlock)
+static inline void mrg_index_read_lock(MRG *mrg, size_t partition) {
+    rw_spinlock_read_lock(&mrg->index[partition].rw_spinlock);
+}
+static inline void mrg_index_read_unlock(MRG *mrg, size_t partition) {
+    rw_spinlock_read_unlock(&mrg->index[partition].rw_spinlock);
+}
+static inline void mrg_index_write_lock(MRG *mrg, size_t partition) {
+    rw_spinlock_write_lock(&mrg->index[partition].rw_spinlock);
+}
+static inline void mrg_index_write_unlock(MRG *mrg, size_t partition) {
+    rw_spinlock_write_unlock(&mrg->index[partition].rw_spinlock);
+}
 
 static inline void mrg_stats_size_judyl_change(MRG *mrg, size_t mem_before_judyl, size_t mem_after_judyl, size_t partition) {
     if(mem_after_judyl > mem_before_judyl)
@@ -93,8 +117,7 @@ static inline void mrg_stats_size_judyhs_removed_uuid(MRG *mrg, size_t partition
 
 static inline size_t uuid_partition(MRG *mrg __maybe_unused, uuid_t *uuid) {
     uint8_t *u = (uint8_t *)uuid;
-    size_t *n = (size_t *)&u[UUID_SZ - sizeof(size_t)];
-    return *n % mrg->partitions;
+    return u[UUID_SZ - 1] % MRG_PARTITIONS;
 }
 
 static inline bool metric_has_retention_unsafe(MRG *mrg __maybe_unused, METRIC *metric) {
@@ -119,7 +142,7 @@ static inline REFCOUNT metric_acquire(MRG *mrg __maybe_unused, METRIC *metric, b
     REFCOUNT refcount;
 
     if(!having_spinlock)
-        metric_lock(metric);
+        spinlock_lock(&metric->spinlock);
 
     if(unlikely(metric->refcount < 0))
         fatal("METRIC: refcount is %d (negative) during acquire", metric->refcount);
@@ -130,7 +153,7 @@ static inline REFCOUNT metric_acquire(MRG *mrg __maybe_unused, METRIC *metric, b
     metric_has_retention_unsafe(mrg, metric);
 
     if(!having_spinlock)
-        metric_unlock(metric);
+        spinlock_unlock(&metric->spinlock);
 
     if(refcount == 1)
         __atomic_add_fetch(&mrg->index[partition].stats.entries_referenced, 1, __ATOMIC_RELAXED);
@@ -145,7 +168,7 @@ static inline bool metric_release_and_can_be_deleted(MRG *mrg __maybe_unused, ME
     size_t partition = metric->partition;
     REFCOUNT refcount;
 
-    metric_lock(metric);
+    spinlock_lock(&metric->spinlock);
 
     if(unlikely(metric->refcount <= 0))
         fatal("METRIC: refcount is %d (zero or negative) during release", metric->refcount);
@@ -155,7 +178,7 @@ static inline bool metric_release_and_can_be_deleted(MRG *mrg __maybe_unused, ME
     if(likely(metric_has_retention_unsafe(mrg, metric) || refcount != 0))
         ret = false;
 
-    metric_unlock(metric);
+    spinlock_unlock(&metric->spinlock);
 
     if(unlikely(!refcount))
         __atomic_sub_fetch(&mrg->index[partition].stats.entries_referenced, 1, __ATOMIC_RELAXED);
@@ -168,7 +191,7 @@ static inline bool metric_release_and_can_be_deleted(MRG *mrg __maybe_unused, ME
 static inline METRIC *metric_add_and_acquire(MRG *mrg, MRG_ENTRY *entry, bool *ret) {
     size_t partition = uuid_partition(mrg, &entry->uuid);
 
-    METRIC *allocation = aral_mallocz(mrg->index[partition].aral);
+    METRIC *allocation = aral_mallocz(mrg->aral[partition]);
 
     mrg_index_write_lock(mrg, partition);
 
@@ -201,7 +224,7 @@ static inline METRIC *metric_add_and_acquire(MRG *mrg, MRG_ENTRY *entry, bool *r
         if(ret)
             *ret = false;
 
-        aral_freez(mrg->index[partition].aral, allocation);
+        aral_freez(mrg->aral[partition], allocation);
 
         return metric;
     }
@@ -303,7 +326,7 @@ static inline bool acquired_metric_del(MRG *mrg, METRIC *metric) {
 
     mrg_index_write_unlock(mrg, partition);
 
-    aral_freez(mrg->index[partition].aral, metric);
+    aral_freez(mrg->aral[partition], metric);
 
     return true;
 }
@@ -311,20 +334,22 @@ static inline bool acquired_metric_del(MRG *mrg, METRIC *metric) {
 // ----------------------------------------------------------------------------
 // public API
 
-inline MRG *mrg_create(size_t partitions) {
-    if(partitions < 1)
-        partitions = get_netdata_cpus();
-
-    MRG *mrg = callocz(1, sizeof(MRG) + sizeof(struct mrg_partition) * partitions);
-    mrg->partitions = partitions;
+inline MRG *mrg_create(void) {
+    MRG *mrg = callocz(1, sizeof(MRG));
 
-    for(size_t i = 0; i < mrg->partitions ; i++) {
+    for(size_t i = 0; i < MRG_PARTITIONS ; i++) {
         rw_spinlock_init(&mrg->index[i].rw_spinlock);
 
         char buf[ARAL_MAX_NAME + 1];
         snprintfz(buf, ARAL_MAX_NAME, "mrg[%zu]", i);
 
-        mrg->index[i].aral = aral_create(buf, sizeof(METRIC), 0, 16384, &mrg_aral_statistics, NULL, NULL, false, false);
+        mrg->aral[i] = aral_create(buf,
+                                   sizeof(METRIC),
+                                   0,
+                                   16384,
+                                   &mrg_aral_statistics,
+                                   NULL, NULL, false,
+                                   false);
     }
 
     return mrg;
@@ -390,10 +415,10 @@ inline bool mrg_metric_set_first_time_s(MRG *mrg __maybe_unused, METRIC *metric,
     if(unlikely(first_time_s < 0))
         return false;
 
-    metric_lock(metric);
+    spinlock_lock(&metric->spinlock);
     metric->first_time_s = first_time_s;
     metric_has_retention_unsafe(mrg, metric);
-    metric_unlock(metric);
+    spinlock_unlock(&metric->spinlock);
 
     return true;
 }
@@ -418,7 +443,7 @@ inline void mrg_metric_expand_retention(MRG *mrg __maybe_unused, METRIC *metric,
     if(unlikely(!first_time_s && !last_time_s && !update_every_s))
         return;
 
-    metric_lock(metric);
+    spinlock_lock(&metric->spinlock);
 
     if(unlikely(first_time_s && (!metric->first_time_s || first_time_s < metric->first_time_s)))
         metric->first_time_s = first_time_s;
@@ -433,7 +458,7 @@ inline void mrg_metric_expand_retention(MRG *mrg __maybe_unused, METRIC *metric,
         metric->latest_update_every_s = (uint32_t) update_every_s;
 
     metric_has_retention_unsafe(mrg, metric);
-    metric_unlock(metric);
+    spinlock_unlock(&metric->spinlock);
 }
 
 inline bool mrg_metric_set_first_time_s_if_bigger(MRG *mrg __maybe_unused, METRIC *metric, time_t first_time_s) {
@@ -441,13 +466,13 @@ inline bool mrg_metric_set_first_time_s_if_bigger(MRG *mrg __maybe_unused, METRI
 
     bool ret = false;
 
-    metric_lock(metric);
+    spinlock_lock(&metric->spinlock);
     if(first_time_s > metric->first_time_s) {
         metric->first_time_s = first_time_s;
         ret = true;
     }
     metric_has_retention_unsafe(mrg, metric);
-    metric_unlock(metric);
+    spinlock_unlock(&metric->spinlock);
 
     return ret;
 }
@@ -455,7 +480,7 @@ inline bool mrg_metric_set_first_time_s_if_bigger(MRG *mrg __maybe_unused, METRI
 inline time_t mrg_metric_get_first_time_s(MRG *mrg __maybe_unused, METRIC *metric) {
     time_t first_time_s;
 
-    metric_lock(metric);
+    spinlock_lock(&metric->spinlock);
 
     if(unlikely(!metric->first_time_s)) {
         if(metric->latest_time_s_clean)
@@ -467,13 +492,13 @@ inline time_t mrg_metric_get_first_time_s(MRG *mrg __maybe_unused, METRIC *metri
 
     first_time_s = metric->first_time_s;
 
-    metric_unlock(metric);
+    spinlock_unlock(&metric->spinlock);
 
     return first_time_s;
 }
 
 inline void mrg_metric_get_retention(MRG *mrg __maybe_unused, METRIC *metric, time_t *first_time_s, time_t *last_time_s, time_t *update_every_s) {
-    metric_lock(metric);
+    spinlock_lock(&metric->spinlock);
 
     if(unlikely(!metric->first_time_s)) {
         if(metric->latest_time_s_clean)
@@ -487,7 +512,7 @@ inline void mrg_metric_get_retention(MRG *mrg __maybe_unused, METRIC *metric, ti
     *last_time_s = MAX(metric->latest_time_s_clean, metric->latest_time_s_hot);
     *update_every_s = metric->latest_update_every_s;
 
-    metric_unlock(metric);
+    spinlock_unlock(&metric->spinlock);
 }
 
 inline bool mrg_metric_set_clean_latest_time_s(MRG *mrg __maybe_unused, METRIC *metric, time_t latest_time_s) {
@@ -496,7 +521,7 @@ inline bool mrg_metric_set_clean_latest_time_s(MRG *mrg __maybe_unused, METRIC *
     if(unlikely(latest_time_s < 0))
         return false;
 
-    metric_lock(metric);
+    spinlock_lock(&metric->spinlock);
 
 //    internal_fatal(latest_time_s > max_acceptable_collected_time(),
 //                   "DBENGINE METRIC: metric latest time is in the future");
@@ -510,7 +535,7 @@ inline bool mrg_metric_set_clean_latest_time_s(MRG *mrg __maybe_unused, METRIC *
         metric->first_time_s = latest_time_s;
 
     metric_has_retention_unsafe(mrg, metric);
-    metric_unlock(metric);
+    spinlock_unlock(&metric->spinlock);
     return true;
 }
 
@@ -548,7 +573,7 @@ inline bool mrg_metric_zero_disk_retention(MRG *mrg __maybe_unused, METRIC *metr
         if (min_first_time_s == LONG_MAX)
             min_first_time_s = 0;
 
-        metric_lock(metric);
+        spinlock_lock(&metric->spinlock);
         if (--countdown && !min_first_time_s && metric->latest_time_s_hot)
             do_again = true;
         else {
@@ -560,7 +585,7 @@ inline bool mrg_metric_zero_disk_retention(MRG *mrg __maybe_unused, METRIC *metr
 
             ret = metric_has_retention_unsafe(mrg, metric);
         }
-        metric_unlock(metric);
+        spinlock_unlock(&metric->spinlock);
     } while(do_again);
 
     return ret;
@@ -575,22 +600,22 @@ inline bool mrg_metric_set_hot_latest_time_s(MRG *mrg __maybe_unused, METRIC *me
     if(unlikely(latest_time_s < 0))
         return false;
 
-    metric_lock(metric);
+    spinlock_lock(&metric->spinlock);
     metric->latest_time_s_hot = latest_time_s;
 
     if(unlikely(!metric->first_time_s))
         metric->first_time_s = latest_time_s;
 
     metric_has_retention_unsafe(mrg, metric);
-    metric_unlock(metric);
+    spinlock_unlock(&metric->spinlock);
     return true;
 }
 
 inline time_t mrg_metric_get_latest_time_s(MRG *mrg __maybe_unused, METRIC *metric) {
     time_t max;
-    metric_lock(metric);
+    spinlock_lock(&metric->spinlock);
     max = MAX(metric->latest_time_s_clean, metric->latest_time_s_hot);
-    metric_unlock(metric);
+    spinlock_unlock(&metric->spinlock);
     return max;
 }
 
@@ -600,9 +625,9 @@ inline bool mrg_metric_set_update_every(MRG *mrg __maybe_unused, METRIC *metric,
     if(update_every_s <= 0)
         return false;
 
-    metric_lock(metric);
+    spinlock_lock(&metric->spinlock);
     metric->latest_update_every_s = (uint32_t) update_every_s;
-    metric_unlock(metric);
+    spinlock_unlock(&metric->spinlock);
 
     return true;
 }
@@ -613,10 +638,10 @@ inline bool mrg_metric_set_update_every_s_if_zero(MRG *mrg __maybe_unused, METRI
     if(update_every_s <= 0)
         return false;
 
-    metric_lock(metric);
+    spinlock_lock(&metric->spinlock);
     if(!metric->latest_update_every_s)
         metric->latest_update_every_s = (uint32_t) update_every_s;
-    metric_unlock(metric);
+    spinlock_unlock(&metric->spinlock);
 
     return true;
 }
@@ -624,16 +649,16 @@ inline bool mrg_metric_set_update_every_s_if_zero(MRG *mrg __maybe_unused, METRI
 inline time_t mrg_metric_get_update_every_s(MRG *mrg __maybe_unused, METRIC *metric) {
     time_t update_every_s;
 
-    metric_lock(metric);
+    spinlock_lock(&metric->spinlock);
     update_every_s = metric->latest_update_every_s;
-    metric_unlock(metric);
+    spinlock_unlock(&metric->spinlock);
 
     return update_every_s;
 }
 
 inline bool mrg_metric_set_writer(MRG *mrg, METRIC *metric) {
     bool done = false;
-    metric_lock(metric);
+    spinlock_lock(&metric->spinlock);
     if(!metric->writer) {
         metric->writer = gettid();
         __atomic_add_fetch(&mrg->index[metric->partition].stats.writers, 1, __ATOMIC_RELAXED);
@@ -641,19 +666,19 @@ inline bool mrg_metric_set_writer(MRG *mrg, METRIC *metric) {
     }
     else
         __atomic_add_fetch(&mrg->index[metric->partition].stats.writers_conflicts, 1, __ATOMIC_RELAXED);
-    metric_unlock(metric);
+    spinlock_unlock(&metric->spinlock);
     return done;
 }
 
 inline bool mrg_metric_clear_writer(MRG *mrg, METRIC *metric) {
     bool done = false;
-    metric_lock(metric);
+    spinlock_lock(&metric->spinlock);
     if(metric->writer) {
         metric->writer = 0;
         __atomic_sub_fetch(&mrg->index[metric->partition].stats.writers, 1, __ATOMIC_RELAXED);
         done = true;
     }
-    metric_unlock(metric);
+    spinlock_unlock(&metric->spinlock);
     return done;
 }
 
@@ -709,7 +734,7 @@ inline void mrg_update_metric_retention_and_granularity_by_uuid(
 inline void mrg_get_statistics(MRG *mrg, struct mrg_statistics *s) {
     memset(s, 0, sizeof(struct mrg_statistics));
 
-    for(size_t i = 0; i < mrg->partitions ;i++) {
+    for(int i = 0; i < MRG_PARTITIONS ;i++) {
         s->entries += __atomic_load_n(&mrg->index[i].stats.entries, __ATOMIC_RELAXED);
         s->entries_referenced += __atomic_load_n(&mrg->index[i].stats.entries_referenced, __ATOMIC_RELAXED);
         s->entries_with_retention += __atomic_load_n(&mrg->index[i].stats.entries_with_retention, __ATOMIC_RELAXED);
@@ -726,7 +751,7 @@ inline void mrg_get_statistics(MRG *mrg, struct mrg_statistics *s) {
         s->writers_conflicts += __atomic_load_n(&mrg->index[i].stats.writers_conflicts, __ATOMIC_RELAXED);
     }
 
-    s->size += sizeof(MRG) + sizeof(struct mrg_partition) * mrg->partitions;
+    s->size += sizeof(MRG);
 }
 
 // ----------------------------------------------------------------------------
@@ -783,7 +808,7 @@ static void *mrg_stress(void *ptr) {
 }
 
 int mrg_unittest(void) {
-    MRG *mrg = mrg_create(0);
+    MRG *mrg = mrg_create();
     METRIC *m1_t0, *m2_t0, *m3_t0, *m4_t0;
     METRIC *m1_t1, *m2_t1, *m3_t1, *m4_t1;
     bool ret;
@@ -864,7 +889,7 @@ int mrg_unittest(void) {
         fatal("DBENGINE METRIC: invalid entries counter");
 
     size_t entries = 1000000;
-    size_t threads = mrg->partitions / 3 + 1;
+    size_t threads = MRG_PARTITIONS / 3 + 1;
     size_t tiers = 3;
     size_t run_for_secs = 5;
     info("preparing stress test of %zu entries...", entries);

+ 7 - 7
database/engine/metric.h

@@ -3,6 +3,8 @@
 
 #include "../rrd.h"
 
+#define MRG_PARTITIONS 10
+
 #define MRG_CACHE_LINE_PADDING(x) uint8_t padding##x[64]
 
 typedef struct metric METRIC;
@@ -17,10 +19,9 @@ typedef struct mrg_entry {
 } MRG_ENTRY;
 
 struct mrg_statistics {
-    // --- non-atomic --- under a write lock
-
+    // non-atomic - under a write lock
     size_t entries;
-    size_t size;    // total memory used, with indexing
+    size_t size;                // total memory used, with indexing
 
     size_t additions;
     size_t additions_duplicate;
@@ -29,10 +30,9 @@ struct mrg_statistics {
     size_t delete_having_retention_or_referenced;
     size_t delete_misses;
 
-    MRG_CACHE_LINE_PADDING(0);
-
-    // --- atomic --- multiple readers / writers
+    // atomic - multiple readers / writers
 
+    MRG_CACHE_LINE_PADDING(0);
     size_t entries_referenced;
 
     MRG_CACHE_LINE_PADDING(1);
@@ -50,7 +50,7 @@ struct mrg_statistics {
     size_t writers_conflicts;
 };
 
-MRG *mrg_create(size_t partitions);
+MRG *mrg_create(void);
 void mrg_destroy(MRG *mrg);
 
 METRIC *mrg_metric_dup(MRG *mrg, METRIC *metric);

+ 1 - 1
database/engine/pagecache.c

@@ -1083,7 +1083,7 @@ size_t dynamic_extent_cache_size(void) {
 
 void pgc_and_mrg_initialize(void)
 {
-    main_mrg = mrg_create(0);
+    main_mrg = mrg_create();
 
     size_t target_cache_size = (size_t)default_rrdeng_page_cache_mb * 1024ULL * 1024ULL;
     size_t main_cache_size = (target_cache_size / 100) * 95;

+ 2 - 2
database/engine/rrdengineapi.c

@@ -1079,8 +1079,8 @@ static void rrdeng_populate_mrg(struct rrdengine_instance *ctx) {
     if(cpus > (size_t)libuv_worker_threads)
         cpus = (size_t)libuv_worker_threads;
 
-    if(cpus >= (size_t)get_netdata_cpus() / 2)
-        cpus = get_netdata_cpus()/ 2 - 1;
+    if(cpus >= MRG_PARTITIONS / 2)
+        cpus = MRG_PARTITIONS / 2 - 1;
 
     if(cpus < 1)
         cpus = 1;