+
+// ----------------------------------------------------------------------------
+// config value
+
+static int config_value_iterator(avl *a) { if(a) {}; return 0; }
+
+static int config_value_compare(void* a, void* b) {
+ if(((struct config_value *)a)->hash < ((struct config_value *)b)->hash) return -1;
+ else if(((struct config_value *)a)->hash > ((struct config_value *)b)->hash) return 1;
+ else return strcmp(((struct config_value *)a)->name, ((struct config_value *)b)->name);
+}
+
+#define config_value_index_add(co, cv) avl_insert(&((co)->values_index), (avl *)(cv))
+#define config_value_index_del(co, cv) avl_remove(&((co)->values_index), (avl *)(cv))
+
+static struct config_value *config_value_index_find(struct config *co, const char *name, uint32_t hash) {
+ struct config_value *result = NULL, tmp;
+ tmp.hash = (hash)?hash:simple_hash(name);
+ tmp.name = (char *)name;
+
+ avl_search(&(co->values_index), (avl *)&tmp, config_value_iterator, (avl **)&result);
+ return result;
+}
+
+// ----------------------------------------------------------------------------
+// config
+
+static int config_iterator(avl *a) { if(a) {}; return 0; }
+
+static int config_compare(void* a, void* b) {
+ if(((struct config *)a)->hash < ((struct config *)b)->hash) return -1;
+ else if(((struct config *)a)->hash > ((struct config *)b)->hash) return 1;
+ else return strcmp(((struct config *)a)->name, ((struct config *)b)->name);
+}
+
+avl_tree config_root_index = {
+ NULL,
+ config_compare
+};
+
+#define config_index_add(cfg) avl_insert(&config_root_index, (avl *)(cfg))
+#define config_index_del(cfg) avl_remove(&config_root_index, (avl *)(cfg))
+
+static struct config *config_index_find(const char *name, uint32_t hash) {
+ struct config *result = NULL, tmp;
+ tmp.hash = (hash)?hash:simple_hash(name);
+ tmp.name = (char *)name;
+
+ avl_search(&config_root_index, (avl *)&tmp, config_iterator, (avl **)&result);
+ return result;
+}
+