Skip to content

Commit

Permalink
removing O(n) penalty in node new/unlink/reparent by replace xmlXPath…
Browse files Browse the repository at this point in the history
…NodeSet with a hash. closes #101.
  • Loading branch information
flavorjones committed Jul 18, 2009
1 parent 9c72f1e commit f34f3bd
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 25 deletions.
3 changes: 1 addition & 2 deletions ext/nokogiri/nokogiri.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,7 @@ extern VALUE mNokogiriXslt ;
#define NOKOGIRI_ROOT_NODE(_node) \
({ \
nokogiriTuplePtr tuple = (nokogiriTuplePtr)(_node->doc->_private); \
xmlNodeSetPtr node_set = (xmlNodeSetPtr)(tuple->unlinkedNodes); \
xmlXPathNodeSetAdd(node_set, _node); \
st_insert(tuple->unlinkedNodes, (st_data_t)_node, (st_data_t)_node); \
_node; \
})

Expand Down
39 changes: 18 additions & 21 deletions ext/nokogiri/xml_document.c
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
#include <xml_document.h>

static int dealloc_node_i(xmlNodePtr key, xmlNodePtr node, xmlDocPtr doc)
{
switch(node->type) {
case XML_ATTRIBUTE_NODE:
xmlFreePropList((xmlAttrPtr)node);
break;
default:
if(node->parent == NULL) {
xmlAddChild((xmlNodePtr)doc, node);
}
}
return ST_CONTINUE;
}

static void dealloc(xmlDocPtr doc)
{
NOKOGIRI_DEBUG_START(doc);

nokogiriTuplePtr tuple = doc->_private;
xmlNodeSetPtr node_set = tuple->unlinkedNodes;
st_table *node_hash = DOC_UNLINKED_NODE_HASH(doc);

xmlDeregisterNodeFunc func = xmlDeregisterNodeDefault(NULL);

int j ;
for(j = 0 ; j < node_set->nodeNr ; j++) {
xmlNodePtr node = node_set->nodeTab[j];
switch(node->type)
{
case XML_ATTRIBUTE_NODE:
xmlFreePropList((xmlAttrPtr)node);
break;
default:
if(node->parent == NULL) {
xmlAddChild((xmlNodePtr)doc, node);
}
}
}

if (node_set->nodeTab != NULL)
xmlFree(node_set->nodeTab);
xmlFree(node_set);
st_foreach(node_hash, dealloc_node_i, (st_data_t)doc);
st_free_table(node_hash);

free(doc->_private);
doc->_private = NULL;
Expand Down Expand Up @@ -313,7 +310,7 @@ VALUE Nokogiri_wrap_xml_document(VALUE klass, xmlDocPtr doc)
rb_funcall(rb_doc, rb_intern("initialize"), 0);

tuple->doc = (void *)rb_doc;
tuple->unlinkedNodes = xmlXPathNodeSetCreate(NULL);
tuple->unlinkedNodes = st_init_numtable_with_size(128);
tuple->node_cache = cache;
doc->_private = tuple ;

Expand Down
5 changes: 3 additions & 2 deletions ext/nokogiri/xml_document.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
#define NOKOGIRI_XML_DOCUMENT

#include <nokogiri.h>
#include "st.h"

struct _nokogiriTuple {
xmlDocPtr doc;
xmlNodeSetPtr unlinkedNodes;
st_table *unlinkedNodes;
VALUE node_cache;
};
typedef struct _nokogiriTuple nokogiriTuple;
Expand All @@ -16,7 +17,7 @@ VALUE Nokogiri_wrap_xml_document(VALUE klass, xmlDocPtr doc);

#define DOC_RUBY_OBJECT_TEST(x) ((nokogiriTuplePtr)(x->_private))
#define DOC_RUBY_OBJECT(x) ((VALUE)((nokogiriTuplePtr)(x->_private))->doc)
#define DOC_UNLINKED_NODE_SET(x) ((xmlNodeSetPtr)((nokogiriTuplePtr)(x->_private))->unlinkedNodes)
#define DOC_UNLINKED_NODE_HASH(x) (((nokogiriTuplePtr)(x->_private))->unlinkedNodes)
#define DOC_NODE_CACHE(x) ((VALUE)((nokogiriTuplePtr)(x->_private))->node_cache)

extern VALUE cNokogiriXmlDocument ;
Expand Down

0 comments on commit f34f3bd

Please sign in to comment.