Commit 3f967317 authored by Nikias Bassen's avatar Nikias Bassen

plist: Improve plist_dict_next_item() drastically by iterating on node list directly

As Xiao Deng pointed out in #131, plist_dict_next_item() was very inefficient.
For each iteration, node_nth_child() was called with the iterator value, which
would walk through the child node list on EVERY iteration. If the dictionary
is large this makes things very slow. More than that, after reaching the key
node the code was calling node_nth_child() AGAIN (with iterator value + 1) to
reach the value node, which would walk through the node list once more.
This commit changes the iterator to be a node_t pointer so that the iteration
is done on the node list directly.
parent 92e5c858
......@@ -471,15 +471,15 @@ PLIST_API void plist_dict_new_iter(plist_t node, plist_dict_iter *iter)
{
if (iter && *iter == NULL)
{
*iter = malloc(sizeof(uint32_t));
*((uint32_t*)(*iter)) = 0;
*iter = malloc(sizeof(node_t*));
*((node_t**)(*iter)) = node_first_child(node);
}
return;
}
PLIST_API void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val)
{
uint32_t* iter_int = (uint32_t*) iter;
node_t** iter_node = (node_t**)iter;
if (key)
{
......@@ -490,20 +490,18 @@ PLIST_API void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **k
*val = NULL;
}
if (node && PLIST_DICT == plist_get_node_type(node) && *iter_int < node_n_children(node))
if (node && PLIST_DICT == plist_get_node_type(node) && *iter_node)
{
if (key)
{
plist_get_key_val((plist_t)node_nth_child(node, *iter_int), key);
plist_get_key_val((plist_t)(*iter_node), key);
}
*iter_node = node_next_sibling(*iter_node);
if (val)
{
*val = (plist_t) node_nth_child(node, *iter_int + 1);
*val = (plist_t)(*iter_node);
}
*iter_int += 2;
*iter_node = node_next_sibling(*iter_node);
}
return;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment