diff --git a/ext/nokogiri/nokogiri.h b/ext/nokogiri/nokogiri.h index 92d450b35d..e7be6c921c 100644 --- a/ext/nokogiri/nokogiri.h +++ b/ext/nokogiri/nokogiri.h @@ -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; \ }) diff --git a/ext/nokogiri/xml_document.c b/ext/nokogiri/xml_document.c index 171238eb4e..9b89742149 100644 --- a/ext/nokogiri/xml_document.c +++ b/ext/nokogiri/xml_document.c @@ -1,32 +1,29 @@ #include +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; @@ -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 ; diff --git a/ext/nokogiri/xml_document.h b/ext/nokogiri/xml_document.h index b9102143c4..8a978de4a4 100644 --- a/ext/nokogiri/xml_document.h +++ b/ext/nokogiri/xml_document.h @@ -2,10 +2,11 @@ #define NOKOGIRI_XML_DOCUMENT #include +#include "st.h" struct _nokogiriTuple { xmlDocPtr doc; - xmlNodeSetPtr unlinkedNodes; + st_table *unlinkedNodes; VALUE node_cache; }; typedef struct _nokogiriTuple nokogiriTuple; @@ -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 ;