Index: /test/regfi-threadtest.c
===================================================================
--- /test/regfi-threadtest.c	(revision 249)
+++ /test/regfi-threadtest.c	(revision 250)
@@ -44,5 +44,8 @@
 #include "common.c"
 
-
+static bool keysEqual(const REGFI_NK* x, const REGFI_NK* y)
+{
+  return (x != NULL && y != NULL && x->offset == y->offset);
+}
 
 void traverseValueList(REGFI_ITERATOR* iter)
@@ -57,5 +60,5 @@
     value = regfi_iterator_cur_value(iter);
     printMsgs(iter->f);
-    regfi_free_record(value);
+    regfi_free_record(iter->f, value);
   }
 }
@@ -70,5 +73,7 @@
   bool print_this = true;
 
-  root = cur = regfi_iterator_cur_key(iter);
+  root = regfi_iterator_cur_key(iter);
+  regfi_reference_record(iter->f, root);
+  cur = root;
   regfi_iterator_first_subkey(iter);
   sub = regfi_iterator_cur_subkey(iter);
@@ -85,8 +90,9 @@
     if(sub == NULL)
     {
-      if(cur != root)
+      if(!keysEqual(cur,root))
       {
 	/* We're done with this sub-tree, going up and hitting other branches. */
-        regfi_free_record(cur);
+        regfi_free_record(iter->f, cur);
+        cur = NULL;
 	if(!regfi_iterator_up(iter))
 	{
@@ -102,5 +108,5 @@
 	sk = regfi_fetch_sk(iter->f, cur);
 	printMsgs(iter->f);
-        regfi_free_record(sk);
+        regfi_free_record(iter->f, sk);
 
 	regfi_iterator_next_subkey(iter);
@@ -113,5 +119,6 @@
        * Let's move down and print this first sub-tree out. 
        */
-      regfi_free_record(cur);
+      regfi_free_record(iter->f, cur);
+      cur = NULL;
       if(!regfi_iterator_down(iter))
       {
@@ -122,5 +129,5 @@
       cur = regfi_iterator_cur_key(iter);
       printMsgs(iter->f);
-      regfi_free_record(sub);
+      regfi_free_record(iter->f, sub);
 
       regfi_iterator_first_subkey(iter);
@@ -130,6 +137,8 @@
     }
     printMsgs(iter->f);
-  } while(!((cur == root) && (sub == NULL)));
-  regfi_free_record(root);
+  } while(!(keysEqual(cur,root) && (sub == NULL)));
+  if(cur != NULL)
+    regfi_free_record(iter->f, cur);
+  regfi_free_record(iter->f, root);
 
   if(print_verbose)
Index: /trunk/doc/devel/TODO
===================================================================
--- /trunk/doc/devel/TODO	(revision 249)
+++ /trunk/doc/devel/TODO	(revision 250)
@@ -46,8 +46,4 @@
 Add fields/methods for accessing security descriptors in pyregfi
 
-Key caching
-
-Add function to obtain path list from iterator
-
 convert MTIME structure to uint64_t if possible
 
Index: /trunk/include/regfi.h
===================================================================
--- /trunk/include/regfi.h	(revision 249)
+++ /trunk/include/regfi.h	(revision 250)
@@ -141,6 +141,7 @@
 /******************************************************************************/
 
-/* Flags determining whether or not to cache various record types internally */
-#define REGFI_CACHE_SK             0
+/* Flags determining how many records to cache internally */
+#define REGFI_CACHE_SK_MAX         64
+#define REGFI_CACHE_NK_MAX         1024
 
 /* This maximum depth is described here:
@@ -815,9 +816,15 @@
   pthread_rwlock_t hbins_lock;
 
-  /* SK record cached since they're repeatedly reused */
+  /* Small number of SK records cached */
   lru_cache* sk_cache;
 
   /* Need exclusive access for LRUs, since lookups make changes */
   pthread_mutex_t sk_lock;
+
+  /* Limited number of keys cached */
+  lru_cache* nk_cache;
+
+  /* Need exclusive access for LRUs, since lookups make changes */
+  pthread_mutex_t nk_lock;
 
   /* Needed to protect various talloc calls */
Index: /trunk/lib/lru_cache.c
===================================================================
--- /trunk/lib/lru_cache.c	(revision 249)
+++ /trunk/lib/lru_cache.c	(revision 250)
@@ -151,5 +151,5 @@
 {
   ht->secret = 0;
-  talloc_free(ht);
+  talloc_unlink(NULL, ht);
 }
 
@@ -257,5 +257,4 @@
     e->index_len = index_len;
 
-    /* Insert at beginning of chain, in a vaguely LRU style */
     e->next = ht->table[hash];
     ht->table[hash] = e;
Index: /trunk/lib/regfi.c
===================================================================
--- /trunk/lib/regfi.c	(revision 249)
+++ /trunk/lib/regfi.c	(revision 250)
@@ -1343,4 +1343,22 @@
   int32_t max_size;
 
+  if(file->nk_cache != NULL)
+  {
+    /* First, check to see if we have this key in our cache */
+    if(!regfi_lock(file, &file->mem_lock, "regfi_load_nk"))
+      return NULL;
+    regfi_lock(file, &file->nk_lock, "regfi_load_nk");
+    
+    nk = (REGFI_NK*)lru_cache_find(file->nk_cache, &offset, 4);
+    if(nk != NULL)
+      nk = talloc_reference(NULL, nk);
+
+    regfi_unlock(file, &file->nk_lock, "regfi_load_nk");
+    regfi_unlock(file, &file->mem_lock, "regfi_load_nk");
+    if(nk != NULL)
+      return nk;
+  }
+
+  /* Not cached currently, proceed with loading it */
   max_size = regfi_calc_maxsize(file, offset);
   if (max_size < 0) 
@@ -1371,5 +1389,4 @@
       else
 	nk->values = NULL;
-
     }
     else
@@ -1421,4 +1438,17 @@
   }
 
+  if(file->nk_cache != NULL)
+  {
+    /* All is well, so let us cache this key for later */
+    if(!regfi_lock(file, &file->mem_lock, "regfi_load_nk"))
+      return NULL;
+    regfi_lock(file, &file->nk_lock, "regfi_load_nk");
+    
+    lru_cache_update(file->nk_cache, &offset, 4, nk);
+    
+    regfi_unlock(file, &file->nk_lock, "regfi_load_nk");
+    regfi_unlock(file, &file->mem_lock, "regfi_load_nk");
+  }
+
   return nk;
 }
@@ -1440,6 +1470,7 @@
     return regfi_parse_sk(file, offset, max_size, strict);
 
-  if(!regfi_lock(file, &file->sk_lock, "regfi_load_sk"))
-    return NULL;
+  if(!regfi_lock(file, &file->mem_lock, "regfi_load_sk"))
+    return NULL;
+  regfi_lock(file, &file->sk_lock, "regfi_load_sk");
 
   /* First look if we have already parsed it */
@@ -1448,5 +1479,8 @@
   /* Bail out if we have previously cached a parse failure at this offset. */
   if(ret_val == (void*)REGFI_OFFSET_NONE)
-    return NULL;
+  {
+    ret_val = NULL;
+    goto unlock;
+  }
 
   if(ret_val == NULL)
@@ -1457,5 +1491,6 @@
       failure_ptr = talloc(NULL, uint32_t);
       if(failure_ptr == NULL)
-	return NULL;
+	goto unlock;
+
       *(uint32_t*)failure_ptr = REGFI_OFFSET_NONE;
       lru_cache_update(file->sk_cache, &offset, 4, failure_ptr);
@@ -1463,13 +1498,10 @@
       /* Let the cache be the only owner of this */
       talloc_unlink(NULL, failure_ptr);
-      return NULL;
-    }
-  }
-
-  if(!regfi_unlock(file, &file->sk_lock, "regfi_load_sk"))
-  {
-    talloc_unlink(NULL, ret_val);
-    return NULL;
-  }
+    }
+  }
+
+ unlock:
+  regfi_unlock(file, &file->sk_lock, "regfi_load_sk");
+  regfi_unlock(file, &file->mem_lock, "regfi_load_sk");
 
   return ret_val;
@@ -1565,4 +1597,6 @@
   pthread_rwlock_destroy(&file->hbins_lock);
   pthread_mutex_destroy(&file->sk_lock);
+  pthread_mutex_destroy(&file->nk_lock);
+  pthread_mutex_destroy(&file->mem_lock);
 
   return 0;
@@ -1629,4 +1663,10 @@
   }
 
+  if(pthread_mutex_init(&rb->nk_lock, NULL) != 0)
+  {
+    regfi_log_add(REGFI_LOG_ERROR, "Failed to create nk_lock mutex.");
+    goto fail;
+  }
+
   if(pthread_mutex_init(&rb->mem_lock, NULL) != 0)
   {
@@ -1662,8 +1702,13 @@
   cache_secret = 0x15DEAD05^time(NULL)^(getpid()<<16);
 
-  if(REGFI_CACHE_SK)
-    rb->sk_cache = lru_cache_create_ctx(rb, 64, cache_secret, true);
-  else
-    rb->sk_cache = NULL;
+  rb->sk_cache = NULL;
+  if(REGFI_CACHE_SK_MAX > 0)
+    rb->sk_cache = lru_cache_create_ctx(rb, REGFI_CACHE_SK_MAX, 
+                                        cache_secret, true);
+
+  rb->nk_cache = NULL;
+  if(REGFI_CACHE_NK_MAX > 0)
+    rb->nk_cache = lru_cache_create_ctx(rb, REGFI_CACHE_NK_MAX, 
+                                        cache_secret, true);
 
   /* success */
@@ -1675,4 +1720,5 @@
   pthread_rwlock_destroy(&rb->hbins_lock);
   pthread_mutex_destroy(&rb->sk_lock);
+  pthread_mutex_destroy(&rb->nk_lock);
   pthread_mutex_destroy(&rb->mem_lock);
 
@@ -2010,10 +2056,6 @@
 {
   const REGFI_NK* ret_val = NULL;
-  if(!regfi_lock(i->f, &i->f->mem_lock, "regfi_iterator_cur_key"))
-    return ret_val;
 
   ret_val = regfi_load_key(i->f, i->cur->offset, i->f->string_encoding, true);
-
-  regfi_unlock(i->f, &i->f->mem_lock, "regfi_iterator_cur_key");  
   return ret_val;
 }
@@ -2138,7 +2180,8 @@
   void_stack_iterator* iter;
   const REGFI_ITER_POSITION* cur;
-  uint16_t k;
-
-  ret_val = talloc_array(NULL, REGFI_NK*, void_stack_size(i->key_positions)+2);
+  uint16_t k, num_keys;
+
+  num_keys = void_stack_size(i->key_positions)+1;
+  ret_val = talloc_array(NULL, REGFI_NK*, num_keys+1);
   if(ret_val == NULL)
     return NULL;
@@ -2150,5 +2193,14 @@
     return NULL;
   }
-  
+
+  k=0;
+  for(cur=void_stack_iterator_next(iter);
+      cur != NULL; cur=void_stack_iterator_next(iter))
+  { 
+    ret_val[k++] = regfi_load_key(i->f, cur->offset, i->f->string_encoding, true); 
+  }
+  ret_val[k] = regfi_load_key(i->f, i->cur->offset, i->f->string_encoding, true);
+  void_stack_iterator_free(iter);
+
   if(!regfi_lock(i->f, &i->f->mem_lock, "regfi_cur_path"))
   {
@@ -2157,17 +2209,10 @@
   }
 
-  for(cur=void_stack_iterator_next(iter), k=0; 
-      cur != NULL; cur=void_stack_iterator_next(iter), k++)
-  {
-    ret_val[k] = regfi_load_key(i->f, cur->offset, i->f->string_encoding, true);
+  for(k=0; k<num_keys; k++)
     talloc_reparent(NULL, ret_val, ret_val[k]);
-  }
-  ret_val[k] = regfi_load_key(i->f, i->cur->offset, i->f->string_encoding, true);
-  talloc_reparent(NULL, ret_val, ret_val[k]);
 
   regfi_unlock(i->f, &i->f->mem_lock, "regfi_cur_path");
-  void_stack_iterator_free(iter);
-
-  ret_val[++k] = NULL;
+
+  ret_val[k] = NULL;
   return (const REGFI_NK**)ret_val;
 }
