]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Allow to reserve elements in libucl
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 14 Feb 2018 11:42:36 +0000 (11:42 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 14 Feb 2018 14:45:25 +0000 (14:45 +0000)
contrib/libucl/lua_ucl.c
contrib/libucl/ucl.h
contrib/libucl/ucl_hash.c
contrib/libucl/ucl_hash.h
contrib/libucl/ucl_util.c

index 7611ecffb6e4e46907fb050f25d0939d1a574f33..52e787ee5a68ff7818adb5abf77b45398054c04e 100644 (file)
@@ -355,7 +355,8 @@ ucl_object_lua_fromtable (lua_State *L, int idx, ucl_string_flags_t flags)
                        lua_pop (L, 1);
                }
        }
-       else if (is_array) {
+
+       if (is_array) {
 #if LUA_VERSION_NUM >= 502
                max = lua_rawlen (L, idx);
 #else
index 7c069e79441cfb138314f78e4801aca56b82d5d8..8f6d6beb661a21045cecd82bbed8f7f38c09641e 100644 (file)
@@ -462,6 +462,13 @@ UCL_EXTERN ucl_object_t* ucl_object_pop_key (ucl_object_t *top, const char *key)
 UCL_EXTERN bool ucl_object_insert_key_merged (ucl_object_t *top, ucl_object_t *elt,
                const char *key, size_t keylen, bool copy_key);
 
+/**
+ * Reserve space in ucl array or object for `elt` elements
+ * @param obj object to reserve
+ * @param reserved size to reserve in an object
+ */
+UCL_EXTERN void ucl_object_reserve (ucl_object_t *obj, size_t reserved);
+
 /**
  * Append an element to the end of array object
  * @param top destination object (must NOT be NULL)
index 0bb8759f6f19cd696040ef864174d57c4fafc400..ce2a4fdb5adf480c7ccbd798a21abb3db75fc570 100644 (file)
@@ -395,3 +395,25 @@ ucl_hash_delete (ucl_hash_t* hashlin, const ucl_object_t *obj)
                }
        }
 }
+
+void ucl_hash_reserve (ucl_hash_t *hashlin, size_t sz)
+{
+       if (hashlin == NULL) {
+               return;
+       }
+
+       if (sz > hashlin->ar.m) {
+               kv_resize (const ucl_object_t *, hashlin->ar, sz);
+
+               if (hashlin->caseless) {
+                       khash_t(ucl_hash_caseless_node) *h = (khash_t(
+                                       ucl_hash_caseless_node) *)
+                                       hashlin->hash;
+                       kh_resize (ucl_hash_caseless_node, h, sz);
+               } else {
+                       khash_t(ucl_hash_node) *h = (khash_t(ucl_hash_node) *)
+                                       hashlin->hash;
+                       kh_resize (ucl_hash_node, h, sz);
+               }
+       }
+}
\ No newline at end of file
index 92021e34075ec06ca9b572f2edb184a21776d3ed..f474b462a1335548d7d40568b3d5265e259d0e4d 100644 (file)
@@ -90,4 +90,10 @@ const void* ucl_hash_iterate (ucl_hash_t *hashlin, ucl_hash_iter_t *iter);
  */
 bool ucl_hash_iter_has_next (ucl_hash_t *hashlin, ucl_hash_iter_t iter);
 
+/**
+ * Reserves space in hash
+ * @param hashlin
+ */
+void ucl_hash_reserve (ucl_hash_t *hashlin, size_t sz);
+
 #endif
index 85b700a4dda9a4ddc3fdab77b3bca4d0ddd8b5ff..8f5231e2fdfb9eeae806d84e302068977e263af8 100644 (file)
@@ -2755,6 +2755,21 @@ ucl_object_new_full (ucl_type_t type, unsigned priority)
        return new;
 }
 
+void ucl_object_reserve (ucl_object_t *obj, size_t reserved)
+{
+       if (obj->type == UCL_ARRAY) {
+               UCL_ARRAY_GET (vec, obj);
+
+               if (vec->m < reserved) {
+                       /* Preallocate some space for arrays */
+                       kv_resize (ucl_object_t *, *vec, reserved);
+               }
+       }
+       else if (obj->type == UCL_OBJECT) {
+               ucl_hash_reserve (obj->value.ov, reserved);
+       }
+}
+
 ucl_object_t*
 ucl_object_new_userdata (ucl_userdata_dtor dtor,
                ucl_userdata_emitter emitter,