aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2018-02-14 11:42:36 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2018-02-14 14:45:25 +0000
commit9f0a4220decbb0adaf8aa63d506cf01c55e3204c (patch)
treebc1f044bb9b48872137b31b383ff7d89ab9d06a6
parenta755e38112262b462ee2c95eedb71299c688ee5e (diff)
downloadrspamd-9f0a4220decbb0adaf8aa63d506cf01c55e3204c.tar.gz
rspamd-9f0a4220decbb0adaf8aa63d506cf01c55e3204c.zip
[Feature] Allow to reserve elements in libucl
-rw-r--r--contrib/libucl/lua_ucl.c3
-rw-r--r--contrib/libucl/ucl.h7
-rw-r--r--contrib/libucl/ucl_hash.c22
-rw-r--r--contrib/libucl/ucl_hash.h6
-rw-r--r--contrib/libucl/ucl_util.c15
5 files changed, 52 insertions, 1 deletions
diff --git a/contrib/libucl/lua_ucl.c b/contrib/libucl/lua_ucl.c
index 7611ecffb..52e787ee5 100644
--- a/contrib/libucl/lua_ucl.c
+++ b/contrib/libucl/lua_ucl.c
@@ -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
diff --git a/contrib/libucl/ucl.h b/contrib/libucl/ucl.h
index 7c069e794..8f6d6beb6 100644
--- a/contrib/libucl/ucl.h
+++ b/contrib/libucl/ucl.h
@@ -463,6 +463,13 @@ UCL_EXTERN bool ucl_object_insert_key_merged (ucl_object_t *top, ucl_object_t *e
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)
* @param elt element to append (must NOT be NULL)
diff --git a/contrib/libucl/ucl_hash.c b/contrib/libucl/ucl_hash.c
index 0bb8759f6..ce2a4fdb5 100644
--- a/contrib/libucl/ucl_hash.c
+++ b/contrib/libucl/ucl_hash.c
@@ -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
diff --git a/contrib/libucl/ucl_hash.h b/contrib/libucl/ucl_hash.h
index 92021e340..f474b462a 100644
--- a/contrib/libucl/ucl_hash.h
+++ b/contrib/libucl/ucl_hash.h
@@ -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
diff --git a/contrib/libucl/ucl_util.c b/contrib/libucl/ucl_util.c
index 85b700a4d..8f5231e2f 100644
--- a/contrib/libucl/ucl_util.c
+++ b/contrib/libucl/ucl_util.c
@@ -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,