You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2013/07/17 16:12:21 UTC

[lucy-commits] [01/34] git commit: refs/heads/master - Hack in IVARS.

Updated Branches:
  refs/heads/master 6f661d5d2 -> adacb96f4


Hack in IVARS.

Create FooIVARS struct which is typedef'd to Foo and a Foo_IVARS inline
function which simply performs a cast.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/59bd0cd7
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/59bd0cd7
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/59bd0cd7

Branch: refs/heads/master
Commit: 59bd0cd783781c6b603ce6f59fc7ad0fc0bf5cb3
Parents: 6f661d5
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Wed Jun 26 16:34:01 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 15:48:58 2013 -0700

----------------------------------------------------------------------
 clownfish/compiler/src/CFCBindClass.c | 30 +++++++++++++++++++++++++++++-
 clownfish/compiler/src/CFCClass.c     | 16 ++++++++++++++++
 clownfish/compiler/src/CFCClass.h     |  6 ++++++
 3 files changed, 51 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/59bd0cd7/clownfish/compiler/src/CFCBindClass.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCBindClass.c b/clownfish/compiler/src/CFCBindClass.c
index 2cd5efd..a1b3ac6 100644
--- a/clownfish/compiler/src/CFCBindClass.c
+++ b/clownfish/compiler/src/CFCBindClass.c
@@ -152,11 +152,37 @@ S_to_c_header_inert(CFCBindClass *self) {
 }
 
 static char*
+S_ivars_hack(CFCBindClass *self) {
+    const char *full_struct = CFCClass_full_struct_sym(self->client);
+    const char *full_ivars  = CFCClass_full_ivars_name(self->client);
+    const char *short_ivars = CFCClass_short_ivars_name(self->client);
+    const char *prefix      = CFCClass_get_PREFIX(self->client);
+    const char *class_cnick = CFCClass_get_cnick(self->client);
+    char pattern[] =
+        "typedef struct %s %s;\n"
+        "static CHY_INLINE %s*\n"
+        "%s%s_IVARS(%s *self) {\n"
+        "   return (%s*)self;\n"
+        "}\n"
+        "#ifdef %sUSE_SHORT_NAMES\n"
+        "  #define %s %s\n"
+        "  #define %s_IVARS %s%s_IVARS\n"
+        "#endif\n";
+    char *content
+        = CFCUtil_sprintf(pattern, full_struct, full_ivars, full_ivars, prefix,
+                          class_cnick, full_struct, full_ivars, prefix,
+                          short_ivars, full_ivars, class_cnick, prefix,
+                          class_cnick);
+    return content;
+}
+
+static char*
 S_to_c_header_dynamic(CFCBindClass *self) {
     const char *privacy_symbol  = CFCClass_privacy_symbol(self->client);
     const char *vt_var          = CFCClass_full_vtable_var(self->client);
     const char *prefix          = CFCClass_get_prefix(self->client);
     const char *PREFIX          = CFCClass_get_PREFIX(self->client);
+    char *ivars                 = S_ivars_hack(self);
     char *struct_def            = S_struct_definition(self);
     char *parent_include        = S_parent_include(self);
     char *sub_declarations      = S_sub_declarations(self);
@@ -178,6 +204,7 @@ S_to_c_header_dynamic(CFCBindClass *self) {
         "\n"
         "#ifdef %s\n"
         "%s\n"
+        "%s\n"
         "#endif /* %s */\n"
         "\n"
         "/* Declare this class's inert variables.\n"
@@ -214,10 +241,11 @@ S_to_c_header_dynamic(CFCBindClass *self) {
         "\n";
     char *content
         = CFCUtil_sprintf(pattern, prefix, parent_include, privacy_symbol,
-                          struct_def, privacy_symbol, inert_var_defs,
+                          ivars, struct_def, privacy_symbol, inert_var_defs,
                           sub_declarations, method_typedefs, method_defs,
                           PREFIX, vt_var, short_names);
 
+    FREEMEM(ivars);
     FREEMEM(struct_def);
     FREEMEM(parent_include);
     FREEMEM(sub_declarations);

http://git-wip-us.apache.org/repos/asf/lucy/blob/59bd0cd7/clownfish/compiler/src/CFCClass.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCClass.c b/clownfish/compiler/src/CFCClass.c
index 9c90f68..790fd72 100644
--- a/clownfish/compiler/src/CFCClass.c
+++ b/clownfish/compiler/src/CFCClass.c
@@ -77,6 +77,8 @@ struct CFCClass {
     int is_inert;
     char *struct_sym;
     char *full_struct_sym;
+    char *ivars_name;
+    char *full_ivars_name;
     char *short_vtable_var;
     char *full_vtable_var;
     char *privacy_symbol;
@@ -174,6 +176,8 @@ CFCClass_do_create(CFCClass *self, struct CFCParcel *parcel,
     }
     self->short_vtable_var[struct_sym_len] = '\0';
     self->full_struct_sym = CFCUtil_sprintf("%s%s", prefix, self->struct_sym);
+    self->ivars_name      = CFCUtil_sprintf("%sIVARS", self->struct_sym);
+    self->full_ivars_name = CFCUtil_sprintf("%sIVARS", self->full_struct_sym);
     size_t full_struct_sym_len = strlen(self->full_struct_sym);
     self->full_vtable_var = (char*)MALLOCATE(full_struct_sym_len + 1);
     for (i = 0; self->full_struct_sym[i] != '\0'; i++) {
@@ -250,6 +254,8 @@ CFCClass_destroy(CFCClass *self) {
     FREEMEM(self->autocode);
     FREEMEM(self->parent_class_name);
     FREEMEM(self->struct_sym);
+    FREEMEM(self->ivars_name);
+    FREEMEM(self->full_ivars_name);
     FREEMEM(self->short_vtable_var);
     FREEMEM(self->full_struct_sym);
     FREEMEM(self->full_vtable_var);
@@ -823,6 +829,16 @@ CFCClass_full_struct_sym(CFCClass *self) {
 }
 
 const char*
+CFCClass_short_ivars_name(CFCClass *self) {
+    return self->ivars_name;
+}
+
+const char*
+CFCClass_full_ivars_name(CFCClass *self) {
+    return self->full_ivars_name;
+}
+
+const char*
 CFCClass_short_vtable_var(CFCClass *self) {
     return self->short_vtable_var;
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/59bd0cd7/clownfish/compiler/src/CFCClass.h
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCClass.h b/clownfish/compiler/src/CFCClass.h
index cb484d8..d45e883 100644
--- a/clownfish/compiler/src/CFCClass.h
+++ b/clownfish/compiler/src/CFCClass.h
@@ -246,6 +246,12 @@ CFCClass_get_struct_sym(CFCClass *self);
 const char*
 CFCClass_full_struct_sym(CFCClass *self);
 
+const char*
+CFCClass_short_ivars_name(CFCClass *self);
+
+const char*
+CFCClass_full_ivars_name(CFCClass *self);
+
 /** The short name of the global VTable object for this class.
  */
 const char*


[lucy-commits] [08/34] git commit: refs/heads/master - Use accessors for Spans.

Posted by ma...@apache.org.
Use accessors for Spans.

Go through accessors when accessing Span member variables from HeatMap
and Highlighter, rather than using direct struct member access.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/6827b4fa
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/6827b4fa
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/6827b4fa

Branch: refs/heads/master
Commit: 6827b4fad9c7c911797b52bb4ba464e9383a1f12
Parents: 9645b2e
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Fri Jun 28 10:15:01 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 15:50:07 2013 -0700

----------------------------------------------------------------------
 core/Lucy/Highlight/HeatMap.c     | 34 +++++++++++++++++++---------------
 core/Lucy/Highlight/Highlighter.c | 25 +++++++++++++------------
 2 files changed, 32 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/6827b4fa/core/Lucy/Highlight/HeatMap.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Highlight/HeatMap.c b/core/Lucy/Highlight/HeatMap.c
index 164ca9f..0d976e9 100644
--- a/core/Lucy/Highlight/HeatMap.c
+++ b/core/Lucy/Highlight/HeatMap.c
@@ -15,7 +15,6 @@
  */
 
 #define C_LUCY_HEATMAP
-#define C_LUCY_SPAN
 #include "Lucy/Util/ToolSet.h"
 
 #include "Lucy/Highlight/HeatMap.h"
@@ -70,8 +69,8 @@ S_flattened_but_empty_spans(VArray *spans) {
     // Assemble a list of all unique start/end boundaries.
     for (uint32_t i = 0; i < num_spans; i++) {
         Span *span            = (Span*)VA_Fetch(spans, i);
-        bounds[i]             = span->offset;
-        bounds[i + num_spans] = span->offset + span->length;
+        bounds[i]             = Span_Get_Offset(span);
+        bounds[i + num_spans] = Span_Get_Offset(span) + Span_Get_Length(span);
     }
     Sort_quicksort(bounds, num_spans * 2, sizeof(uint32_t),
                    S_compare_i32, NULL);
@@ -113,14 +112,15 @@ HeatMap_flatten_spans(HeatMap *self, VArray *spans) {
         uint32_t dest_tick = 0;
         for (uint32_t i = 0; i < num_spans; i++) {
             Span *source_span = (Span*)VA_Fetch(spans, i);
-            int32_t source_span_end
-                = source_span->offset + source_span->length;
+            int32_t source_span_offset = Span_Get_Offset(source_span);
+            int32_t source_span_len    = Span_Get_Length(source_span);
+            int32_t source_span_end    = source_span_offset + source_span_len;
 
             // Get the location of the flattened span that shares the source
             // span's offset.
             for (; dest_tick < num_raw_flattened; dest_tick++) {
                 Span *dest_span = (Span*)VA_Fetch(flattened, dest_tick);
-                if (dest_span->offset == source_span->offset) {
+                if (Span_Get_Offset(dest_span) == source_span_offset) {
                     break;
                 }
             }
@@ -128,11 +128,13 @@ HeatMap_flatten_spans(HeatMap *self, VArray *spans) {
             // Fill in scores.
             for (uint32_t j = dest_tick; j < num_raw_flattened; j++) {
                 Span *dest_span = (Span*)VA_Fetch(flattened, j);
-                if (dest_span->offset == source_span_end) {
+                if (Span_Get_Offset(dest_span) == source_span_end) {
                     break;
                 }
                 else {
-                    dest_span->weight += source_span->weight;
+                    float new_weight = Span_Get_Weight(dest_span)
+                                       + Span_Get_Weight(source_span);
+                    Span_Set_Weight(dest_span, new_weight);
                 }
             }
         }
@@ -141,7 +143,7 @@ HeatMap_flatten_spans(HeatMap *self, VArray *spans) {
         dest_tick = 0;
         for (uint32_t i = 0; i < num_raw_flattened; i++) {
             Span *span = (Span*)VA_Fetch(flattened, i);
-            if (span->weight) {
+            if (Span_Get_Weight(span)) {
                 VA_Store(flattened, dest_tick++, INCREF(span));
             }
         }
@@ -156,8 +158,8 @@ HeatMap_calc_proximity_boost(HeatMap *self, Span *span1, Span *span2) {
     int32_t comparison = Span_Compare_To(span1, (Obj*)span2);
     Span *lower = comparison <= 0 ? span1 : span2;
     Span *upper = comparison >= 0 ? span1 : span2;
-    int32_t lower_end_offset = lower->offset + lower->length;
-    int32_t distance = upper->offset - lower_end_offset;
+    int32_t lower_end_offset = Span_Get_Offset(lower) + Span_Get_Length(lower);
+    int32_t distance = Span_Get_Offset(upper) - lower_end_offset;
 
     // If spans overlap, set distance to 0.
     if (distance < 0) { distance = 0; }
@@ -169,7 +171,7 @@ HeatMap_calc_proximity_boost(HeatMap *self, Span *span1, Span *span2) {
         float factor = (self->window - distance) / (float)self->window;
         // Damp boost with greater distance.
         factor *= factor;
-        return factor * (lower->weight + upper->weight);
+        return factor * (Span_Get_Weight(lower) + Span_Get_Weight(upper));
     }
 }
 
@@ -190,10 +192,12 @@ HeatMap_generate_proximity_boosts(HeatMap *self, VArray *spans) {
                     break;
                 }
                 else {
-                    int32_t length = (span2->offset - span1->offset)
-                                     + span2->length;
+                    int32_t length = Span_Get_Offset(span2)
+                                     - Span_Get_Offset(span1)
+                                     + Span_Get_Length(span2);
                     VA_Push(boosts,
-                            (Obj*)Span_new(span1->offset, length, prox_score));
+                            (Obj*)Span_new(Span_Get_Offset(span1), length,
+                                           prox_score));
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/lucy/blob/6827b4fa/core/Lucy/Highlight/Highlighter.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Highlight/Highlighter.c b/core/Lucy/Highlight/Highlighter.c
index 555979f..85afe29 100644
--- a/core/Lucy/Highlight/Highlighter.c
+++ b/core/Lucy/Highlight/Highlighter.c
@@ -15,7 +15,6 @@
  */
 
 #define C_LUCY_HIGHLIGHTER
-#define C_LUCY_SPAN
 #include <ctype.h>
 #include "Lucy/Util/ToolSet.h"
 
@@ -198,9 +197,9 @@ S_hottest(HeatMap *heat_map) {
     VArray *spans = HeatMap_Get_Spans(heat_map);
     for (uint32_t i = VA_Get_Size(spans); i--;) {
         Span *span = (Span*)VA_Fetch(spans, i);
-        if (span->weight >= max_score) {
-            retval = span->offset;
-            max_score = span->weight;
+        if (Span_Get_Weight(span) >= max_score) {
+            retval = Span_Get_Offset(span);
+            max_score = Span_Get_Weight(span);
         }
     }
     return retval;
@@ -269,8 +268,8 @@ S_has_heat(HeatMap *heat_map, int32_t offset, int32_t length) {
 
     for (uint32_t i = 0; i < num_spans; i++) {
         Span *span  = (Span*)VA_Fetch(spans, i);
-        int32_t span_start = span->offset;
-        int32_t span_end   = span_start + span->length;
+        int32_t span_start = Span_Get_Offset(span);
+        int32_t span_end   = span_start + Span_Get_Length(span);;
         if (offset >= span_start && offset <  span_end) { return true; }
         if (end    >  span_start && end    <= span_end) { return true; }
         if (offset <= span_start && end    >= span_end) { return true; }
@@ -298,7 +297,7 @@ Highlighter_raw_excerpt(Highlighter *self, const CharBuf *field_val,
     if (num_sentences) {
         for (uint32_t i = 0; i < num_sentences; i++) {
             Span *sentence = (Span*)VA_Fetch(sentences, i);
-            int32_t candidate = sentence->offset;
+            int32_t candidate = Span_Get_Offset(sentence);;
 
             if (candidate > top + (int32_t)self->window_width) {
                 break;
@@ -328,7 +327,8 @@ Highlighter_raw_excerpt(Highlighter *self, const CharBuf *field_val,
 
         for (uint32_t i = num_sentences; i--;) {
             Span    *sentence  = (Span*)VA_Fetch(sentences, i);
-            int32_t  last_edge = sentence->offset + sentence->length;
+            int32_t  last_edge = Span_Get_Offset(sentence)
+                                 + Span_Get_Length(sentence);
 
             if (last_edge <= start) {
                 break;
@@ -491,15 +491,16 @@ Highlighter_highlight_excerpt(Highlighter *self, VArray *spans,
 
     for (uint32_t i = 0, max = VA_Get_Size(spans); i < max; i++) {
         Span *span = (Span*)VA_Fetch(spans, i);
-        if (span->offset < top) {
+        int32_t offset = Span_Get_Offset(span);
+        if (offset < top) {
             continue;
         }
-        else if (span->offset >= raw_excerpt_end) {
+        else if (offset >= raw_excerpt_end) {
             break;
         }
         else {
-            int32_t relative_start = span->offset - top;
-            int32_t relative_end   = relative_start + span->length;
+            int32_t relative_start = offset - top;
+            int32_t relative_end   = relative_start + Span_Get_Length(span);
 
             if (relative_start <= hl_end) {
                 if (relative_end > hl_end) {


[lucy-commits] [12/34] Migrate Lucy's index classes to IVARS.

Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/IndexManager.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/IndexManager.c b/core/Lucy/Index/IndexManager.c
index 61bb761..684e476 100644
--- a/core/Lucy/Index/IndexManager.c
+++ b/core/Lucy/Index/IndexManager.c
@@ -40,26 +40,28 @@ IxManager_new(const CharBuf *host, LockFactory *lock_factory) {
 IndexManager*
 IxManager_init(IndexManager *self, const CharBuf *host,
                LockFactory *lock_factory) {
-    self->host                = host
+    IndexManagerIVARS *const ivars = IxManager_IVARS(self);
+    ivars->host                = host
                                 ? CB_Clone(host)
                                 : CB_new_from_trusted_utf8("", 0);
-    self->lock_factory        = (LockFactory*)INCREF(lock_factory);
-    self->folder              = NULL;
-    self->write_lock_timeout  = 1000;
-    self->write_lock_interval = 100;
-    self->merge_lock_timeout  = 0;
-    self->merge_lock_interval = 1000;
-    self->deletion_lock_timeout  = 1000;
-    self->deletion_lock_interval = 100;
+    ivars->lock_factory        = (LockFactory*)INCREF(lock_factory);
+    ivars->folder              = NULL;
+    ivars->write_lock_timeout  = 1000;
+    ivars->write_lock_interval = 100;
+    ivars->merge_lock_timeout  = 0;
+    ivars->merge_lock_interval = 1000;
+    ivars->deletion_lock_timeout  = 1000;
+    ivars->deletion_lock_interval = 100;
 
     return self;
 }
 
 void
 IxManager_destroy(IndexManager *self) {
-    DECREF(self->host);
-    DECREF(self->folder);
-    DECREF(self->lock_factory);
+    IndexManagerIVARS *const ivars = IxManager_IVARS(self);
+    DECREF(ivars->host);
+    DECREF(ivars->folder);
+    DECREF(ivars->lock_factory);
     SUPER_DESTROY(self, INDEXMANAGER);
 }
 
@@ -81,7 +83,8 @@ IxManager_highest_seg_num(IndexManager *self, Snapshot *snapshot) {
 
 CharBuf*
 IxManager_make_snapshot_filename(IndexManager *self) {
-    Folder *folder = (Folder*)CERTIFY(self->folder, FOLDER);
+    IndexManagerIVARS *const ivars = IxManager_IVARS(self);
+    Folder *folder = (Folder*)CERTIFY(ivars->folder, FOLDER);
     DirHandle *dh = Folder_Open_Dir(folder, NULL);
     uint64_t max_gen = 0;
 
@@ -216,49 +219,54 @@ IxManager_choose_sparse(IndexManager *self, I32Array *doc_counts) {
 
 static LockFactory*
 S_obtain_lock_factory(IndexManager *self) {
-    if (!self->lock_factory) {
-        if (!self->folder) {
+    IndexManagerIVARS *const ivars = IxManager_IVARS(self);
+    if (!ivars->lock_factory) {
+        if (!ivars->folder) {
             THROW(ERR, "Can't create a LockFactory without a Folder");
         }
-        self->lock_factory = LockFact_new(self->folder, self->host);
+        ivars->lock_factory = LockFact_new(ivars->folder, ivars->host);
     }
-    return self->lock_factory;
+    return ivars->lock_factory;
 }
 
 Lock*
 IxManager_make_write_lock(IndexManager *self) {
+    IndexManagerIVARS *const ivars = IxManager_IVARS(self);
     ZombieCharBuf *write_lock_name = ZCB_WRAP_STR("write", 5);
     LockFactory *lock_factory = S_obtain_lock_factory(self);
     return LockFact_Make_Lock(lock_factory, (CharBuf*)write_lock_name,
-                              self->write_lock_timeout,
-                              self->write_lock_interval);
+                              ivars->write_lock_timeout,
+                              ivars->write_lock_interval);
 }
 
 Lock*
 IxManager_make_deletion_lock(IndexManager *self) {
+    IndexManagerIVARS *const ivars = IxManager_IVARS(self);
     ZombieCharBuf *lock_name = ZCB_WRAP_STR("deletion", 8);
     LockFactory *lock_factory = S_obtain_lock_factory(self);
     return LockFact_Make_Lock(lock_factory, (CharBuf*)lock_name,
-                              self->deletion_lock_timeout,
-                              self->deletion_lock_interval);
+                              ivars->deletion_lock_timeout,
+                              ivars->deletion_lock_interval);
 }
 
 Lock*
 IxManager_make_merge_lock(IndexManager *self) {
+    IndexManagerIVARS *const ivars = IxManager_IVARS(self);
     ZombieCharBuf *merge_lock_name = ZCB_WRAP_STR("merge", 5);
     LockFactory *lock_factory = S_obtain_lock_factory(self);
     return LockFact_Make_Lock(lock_factory, (CharBuf*)merge_lock_name,
-                              self->merge_lock_timeout,
-                              self->merge_lock_interval);
+                              ivars->merge_lock_timeout,
+                              ivars->merge_lock_interval);
 }
 
 void
 IxManager_write_merge_data(IndexManager *self, int64_t cutoff) {
+    IndexManagerIVARS *const ivars = IxManager_IVARS(self);
     ZombieCharBuf *merge_json = ZCB_WRAP_STR("merge.json", 10);
     Hash *data = Hash_new(1);
     bool success;
     Hash_Store_Str(data, "cutoff", 6, (Obj*)CB_newf("%i64", cutoff));
-    success = Json_spew_json((Obj*)data, self->folder, (CharBuf*)merge_json);
+    success = Json_spew_json((Obj*)data, ivars->folder, (CharBuf*)merge_json);
     DECREF(data);
     if (!success) {
         THROW(ERR, "Failed to write to %o", merge_json);
@@ -267,10 +275,11 @@ IxManager_write_merge_data(IndexManager *self, int64_t cutoff) {
 
 Hash*
 IxManager_read_merge_data(IndexManager *self) {
+    IndexManagerIVARS *const ivars = IxManager_IVARS(self);
     ZombieCharBuf *merge_json = ZCB_WRAP_STR("merge.json", 10);
-    if (Folder_Exists(self->folder, (CharBuf*)merge_json)) {
+    if (Folder_Exists(ivars->folder, (CharBuf*)merge_json)) {
         Hash *stuff
-            = (Hash*)Json_slurp_json(self->folder, (CharBuf*)merge_json);
+            = (Hash*)Json_slurp_json(ivars->folder, (CharBuf*)merge_json);
         if (stuff) {
             CERTIFY(stuff, HASH);
             return stuff;
@@ -286,8 +295,9 @@ IxManager_read_merge_data(IndexManager *self) {
 
 bool
 IxManager_remove_merge_data(IndexManager *self) {
+    IndexManagerIVARS *const ivars = IxManager_IVARS(self);
     ZombieCharBuf *merge_json = ZCB_WRAP_STR("merge.json", 10);
-    return Folder_Delete(self->folder, (CharBuf*)merge_json) != 0;
+    return Folder_Delete(ivars->folder, (CharBuf*)merge_json) != 0;
 }
 
 Lock*
@@ -310,78 +320,79 @@ IxManager_make_snapshot_read_lock(IndexManager *self,
 
 void
 IxManager_set_folder(IndexManager *self, Folder *folder) {
-    DECREF(self->folder);
-    self->folder = (Folder*)INCREF(folder);
+    IndexManagerIVARS *const ivars = IxManager_IVARS(self);
+    DECREF(ivars->folder);
+    ivars->folder = (Folder*)INCREF(folder);
 }
 
 Folder*
 IxManager_get_folder(IndexManager *self) {
-    return self->folder;
+    return IxManager_IVARS(self)->folder;
 }
 
 CharBuf*
 IxManager_get_host(IndexManager *self) {
-    return self->host;
+    return IxManager_IVARS(self)->host;
 }
 
 uint32_t
 IxManager_get_write_lock_timeout(IndexManager *self) {
-    return self->write_lock_timeout;
+    return IxManager_IVARS(self)->write_lock_timeout;
 }
 
 uint32_t
 IxManager_get_write_lock_interval(IndexManager *self) {
-    return self->write_lock_interval;
+    return IxManager_IVARS(self)->write_lock_interval;
 }
 
 uint32_t
 IxManager_get_merge_lock_timeout(IndexManager *self) {
-    return self->merge_lock_timeout;
+    return IxManager_IVARS(self)->merge_lock_timeout;
 }
 
 uint32_t
 IxManager_get_merge_lock_interval(IndexManager *self) {
-    return self->merge_lock_interval;
+    return IxManager_IVARS(self)->merge_lock_interval;
 }
 
 uint32_t
 IxManager_get_deletion_lock_timeout(IndexManager *self) {
-    return self->deletion_lock_timeout;
+    return IxManager_IVARS(self)->deletion_lock_timeout;
 }
 
 uint32_t
 IxManager_get_deletion_lock_interval(IndexManager *self) {
-    return self->deletion_lock_interval;
+    return IxManager_IVARS(self)->deletion_lock_interval;
 }
 
 void
 IxManager_set_write_lock_timeout(IndexManager *self, uint32_t timeout) {
-    self->write_lock_timeout = timeout;
+    IxManager_IVARS(self)->write_lock_timeout = timeout;
 }
 
 void
 IxManager_set_write_lock_interval(IndexManager *self, uint32_t interval) {
-    self->write_lock_interval = interval;
+    IxManager_IVARS(self)->write_lock_interval = interval;
 }
 
 void
 IxManager_set_merge_lock_timeout(IndexManager *self, uint32_t timeout) {
-    self->merge_lock_timeout = timeout;
+    IxManager_IVARS(self)->merge_lock_timeout = timeout;
 }
 
 void
 IxManager_set_merge_lock_interval(IndexManager *self, uint32_t interval) {
-    self->merge_lock_interval = interval;
+    IxManager_IVARS(self)->merge_lock_interval = interval;
 }
 
 void
 IxManager_set_deletion_lock_timeout(IndexManager *self, uint32_t timeout) {
-    self->deletion_lock_timeout = timeout;
+    IxManager_IVARS(self)->deletion_lock_timeout = timeout;
 }
 
 void
 IxManager_set_deletion_lock_interval(IndexManager *self, uint32_t interval) {
-    self->deletion_lock_interval = interval;
+    IxManager_IVARS(self)->deletion_lock_interval = interval;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/IndexReader.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/IndexReader.c b/core/Lucy/Index/IndexReader.c
index 99250c2..9f81db2 100644
--- a/core/Lucy/Index/IndexReader.c
+++ b/core/Lucy/Index/IndexReader.c
@@ -52,62 +52,66 @@ IxReader_init(IndexReader *self, Schema *schema, Folder *folder,
     DataReader_init((DataReader*)self, schema, folder, snapshot, segments,
                     seg_tick);
     DECREF(snapshot);
-    self->components     = Hash_new(0);
-    self->read_lock      = NULL;
-    self->deletion_lock  = NULL;
+    IndexReaderIVARS *const ivars = IxReader_IVARS(self);
+    ivars->components     = Hash_new(0);
+    ivars->read_lock      = NULL;
+    ivars->deletion_lock  = NULL;
     if (manager) {
-        self->manager = (IndexManager*)INCREF(manager);
-        IxManager_Set_Folder(self->manager, self->folder);
+        ivars->manager = (IndexManager*)INCREF(manager);
+        IxManager_Set_Folder(ivars->manager, ivars->folder);
     }
     else {
-        self->manager = NULL;
+        ivars->manager = NULL;
     }
     return self;
 }
 
 void
 IxReader_close(IndexReader *self) {
-    if (self->components) {
+    IndexReaderIVARS *const ivars = IxReader_IVARS(self);
+    if (ivars->components) {
         CharBuf *key;
         DataReader *component;
-        Hash_Iterate(self->components);
-        while (Hash_Next(self->components, (Obj**)&key,
+        Hash_Iterate(ivars->components);
+        while (Hash_Next(ivars->components, (Obj**)&key,
                          (Obj**)&component)
               ) {
             if (Obj_Is_A((Obj*)component, DATAREADER)) {
                 DataReader_Close(component);
             }
         }
-        Hash_Clear(self->components);
+        Hash_Clear(ivars->components);
     }
-    if (self->read_lock) {
-        Lock_Release(self->read_lock);
-        DECREF(self->read_lock);
-        self->read_lock = NULL;
+    if (ivars->read_lock) {
+        Lock_Release(ivars->read_lock);
+        DECREF(ivars->read_lock);
+        ivars->read_lock = NULL;
     }
 }
 
 void
 IxReader_destroy(IndexReader *self) {
-    DECREF(self->components);
-    if (self->read_lock) {
-        Lock_Release(self->read_lock);
-        DECREF(self->read_lock);
+    IndexReaderIVARS *const ivars = IxReader_IVARS(self);
+    DECREF(ivars->components);
+    if (ivars->read_lock) {
+        Lock_Release(ivars->read_lock);
+        DECREF(ivars->read_lock);
     }
-    DECREF(self->manager);
-    DECREF(self->deletion_lock);
+    DECREF(ivars->manager);
+    DECREF(ivars->deletion_lock);
     SUPER_DESTROY(self, INDEXREADER);
 }
 
 Hash*
 IxReader_get_components(IndexReader *self) {
-    return self->components;
+    return IxReader_IVARS(self)->components;
 }
 
 DataReader*
 IxReader_obtain(IndexReader *self, const CharBuf *api) {
+    IndexReaderIVARS *const ivars = IxReader_IVARS(self);
     DataReader *component
-        = (DataReader*)Hash_Fetch(self->components, (Obj*)api);
+        = (DataReader*)Hash_Fetch(ivars->components, (Obj*)api);
     if (!component) {
         THROW(ERR, "No component registered for '%o'", api);
     }
@@ -116,7 +120,8 @@ IxReader_obtain(IndexReader *self, const CharBuf *api) {
 
 DataReader*
 IxReader_fetch(IndexReader *self, const CharBuf *api) {
-    return (DataReader*)Hash_Fetch(self->components, (Obj*)api);
+    IndexReaderIVARS *const ivars = IxReader_IVARS(self);
+    return (DataReader*)Hash_Fetch(ivars->components, (Obj*)api);
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/Indexer.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/Indexer.c b/core/Lucy/Index/Indexer.c
index 1a9076d..803b7db 100644
--- a/core/Lucy/Index/Indexer.c
+++ b/core/Lucy/Index/Indexer.c
@@ -70,33 +70,34 @@ Indexer_new(Schema *schema, Obj *index, IndexManager *manager, int32_t flags) {
 Indexer*
 Indexer_init(Indexer *self, Schema *schema, Obj *index,
              IndexManager *manager, int32_t flags) {
+    IndexerIVARS *const ivars = Indexer_IVARS(self);
     bool      create   = (flags & Indexer_CREATE)   ? true : false;
     bool      truncate = (flags & Indexer_TRUNCATE) ? true : false;
     Folder   *folder   = S_init_folder(index, create);
     Snapshot *latest_snapshot = Snapshot_new();
 
     // Init.
-    self->stock_doc     = Doc_new(NULL, 0);
-    self->truncate      = false;
-    self->optimize      = false;
-    self->prepared      = false;
-    self->needs_commit  = false;
-    self->snapfile      = NULL;
-    self->merge_lock    = NULL;
+    ivars->stock_doc     = Doc_new(NULL, 0);
+    ivars->truncate      = false;
+    ivars->optimize      = false;
+    ivars->prepared      = false;
+    ivars->needs_commit  = false;
+    ivars->snapfile      = NULL;
+    ivars->merge_lock    = NULL;
 
     // Assign.
-    self->folder       = folder;
-    self->manager      = manager
+    ivars->folder       = folder;
+    ivars->manager      = manager
                          ? (IndexManager*)INCREF(manager)
                          : IxManager_new(NULL, NULL);
-    IxManager_Set_Folder(self->manager, folder);
+    IxManager_Set_Folder(ivars->manager, folder);
 
     // Get a write lock for this folder.
-    Lock *write_lock = IxManager_Make_Write_Lock(self->manager);
+    Lock *write_lock = IxManager_Make_Write_Lock(ivars->manager);
     Lock_Clear_Stale(write_lock);
     if (Lock_Obtain(write_lock)) {
         // Only assign if successful, otherwise DESTROY unlocks -- bad!
-        self->write_lock = write_lock;
+        ivars->write_lock = write_lock;
     }
     else {
         DECREF(write_lock);
@@ -112,7 +113,7 @@ Indexer_init(Indexer *self, Schema *schema, Obj *index,
 
     // Look for an existing Schema if one wasn't supplied.
     if (schema) {
-        self->schema = (Schema*)INCREF(schema);
+        ivars->schema = (Schema*)INCREF(schema);
     }
     else {
         if (!latest_snapfile) {
@@ -123,10 +124,10 @@ Indexer_init(Indexer *self, Schema *schema, Obj *index,
             CharBuf *schema_file = S_find_schema_file(latest_snapshot);
             Hash *dump = (Hash*)Json_slurp_json(folder, schema_file);
             if (dump) { // read file successfully
-                self->schema = (Schema*)CERTIFY(
+                ivars->schema = (Schema*)CERTIFY(
                                    VTable_Load_Obj(SCHEMA, (Obj*)dump),
                                    SCHEMA);
-                schema = self->schema;
+                schema = ivars->schema;
                 DECREF(dump);
                 schema_file = NULL;
             }
@@ -140,21 +141,21 @@ Indexer_init(Indexer *self, Schema *schema, Obj *index,
     // PolyReader.  Otherwise, start with the most recent Snapshot and an
     // up-to-date PolyReader.
     if (truncate) {
-        self->snapshot = Snapshot_new();
-        self->polyreader = PolyReader_new(schema, folder, NULL, NULL, NULL);
-        self->truncate = true;
+        ivars->snapshot = Snapshot_new();
+        ivars->polyreader = PolyReader_new(schema, folder, NULL, NULL, NULL);
+        ivars->truncate = true;
     }
     else {
         // TODO: clone most recent snapshot rather than read it twice.
-        self->snapshot = (Snapshot*)INCREF(latest_snapshot);
-        self->polyreader = latest_snapfile
+        ivars->snapshot = (Snapshot*)INCREF(latest_snapshot);
+        ivars->polyreader = latest_snapfile
                            ? PolyReader_open((Obj*)folder, NULL, NULL)
                            : PolyReader_new(schema, folder, NULL, NULL, NULL);
 
         if (latest_snapfile) {
             // Make sure than any existing fields which may have been
             // dynamically added during past indexing sessions get added.
-            Schema *old_schema = PolyReader_Get_Schema(self->polyreader);
+            Schema *old_schema = PolyReader_Get_Schema(ivars->polyreader);
             Schema_Eat(schema, old_schema);
         }
     }
@@ -163,18 +164,18 @@ Indexer_init(Indexer *self, Schema *schema, Obj *index,
     // Note: we have to feed FilePurger with the most recent snapshot file
     // now, but with the Indexer's snapshot later.
     FilePurger *file_purger
-        = FilePurger_new(folder, latest_snapshot, self->manager);
+        = FilePurger_new(folder, latest_snapshot, ivars->manager);
     FilePurger_Purge(file_purger);
     DECREF(file_purger);
 
     // Create a new segment.
     int64_t new_seg_num
-        = IxManager_Highest_Seg_Num(self->manager, latest_snapshot) + 1;
-    Lock *merge_lock = IxManager_Make_Merge_Lock(self->manager);
+        = IxManager_Highest_Seg_Num(ivars->manager, latest_snapshot) + 1;
+    Lock *merge_lock = IxManager_Make_Merge_Lock(ivars->manager);
     if (Lock_Is_Locked(merge_lock)) {
         // If there's a background merge process going on, stay out of its
         // way.
-        Hash *merge_data = IxManager_Read_Merge_Data(self->manager);
+        Hash *merge_data = IxManager_Read_Merge_Data(ivars->manager);
         Obj *cutoff_obj = merge_data
                           ? Hash_Fetch_Str(merge_data, "cutoff", 6)
                           : NULL;
@@ -191,27 +192,27 @@ Indexer_init(Indexer *self, Schema *schema, Obj *index,
         }
         DECREF(merge_data);
     }
-    self->segment = Seg_new(new_seg_num);
+    ivars->segment = Seg_new(new_seg_num);
 
     // Add all known fields to Segment.
     VArray *fields = Schema_All_Fields(schema);
     for (uint32_t i = 0, max = VA_Get_Size(fields); i < max; i++) {
-        Seg_Add_Field(self->segment, (CharBuf*)VA_Fetch(fields, i));
+        Seg_Add_Field(ivars->segment, (CharBuf*)VA_Fetch(fields, i));
     }
     DECREF(fields);
 
     DECREF(merge_lock);
 
     // Create new SegWriter and FilePurger.
-    self->file_purger
-        = FilePurger_new(folder, self->snapshot, self->manager);
-    self->seg_writer = SegWriter_new(self->schema, self->snapshot,
-                                     self->segment, self->polyreader);
-    SegWriter_Prep_Seg_Dir(self->seg_writer);
+    ivars->file_purger
+        = FilePurger_new(folder, ivars->snapshot, ivars->manager);
+    ivars->seg_writer = SegWriter_new(ivars->schema, ivars->snapshot,
+                                     ivars->segment, ivars->polyreader);
+    SegWriter_Prep_Seg_Dir(ivars->seg_writer);
 
     // Grab a local ref to the DeletionsWriter.
-    self->del_writer = (DeletionsWriter*)INCREF(
-                           SegWriter_Get_Del_Writer(self->seg_writer));
+    ivars->del_writer = (DeletionsWriter*)INCREF(
+                           SegWriter_Get_Del_Writer(ivars->seg_writer));
 
     DECREF(latest_snapfile);
     DECREF(latest_snapshot);
@@ -221,20 +222,21 @@ Indexer_init(Indexer *self, Schema *schema, Obj *index,
 
 void
 Indexer_destroy(Indexer *self) {
+    IndexerIVARS *const ivars = Indexer_IVARS(self);
     S_release_merge_lock(self);
     S_release_write_lock(self);
-    DECREF(self->schema);
-    DECREF(self->folder);
-    DECREF(self->segment);
-    DECREF(self->manager);
-    DECREF(self->stock_doc);
-    DECREF(self->polyreader);
-    DECREF(self->del_writer);
-    DECREF(self->snapshot);
-    DECREF(self->seg_writer);
-    DECREF(self->file_purger);
-    DECREF(self->write_lock);
-    DECREF(self->snapfile);
+    DECREF(ivars->schema);
+    DECREF(ivars->folder);
+    DECREF(ivars->segment);
+    DECREF(ivars->manager);
+    DECREF(ivars->stock_doc);
+    DECREF(ivars->polyreader);
+    DECREF(ivars->del_writer);
+    DECREF(ivars->snapshot);
+    DECREF(ivars->seg_writer);
+    DECREF(ivars->file_purger);
+    DECREF(ivars->write_lock);
+    DECREF(ivars->snapfile);
     SUPER_DESTROY(self, INDEXER);
 }
 
@@ -268,12 +270,14 @@ S_init_folder(Obj *index, bool create) {
 
 void
 Indexer_add_doc(Indexer *self, Doc *doc, float boost) {
-    SegWriter_Add_Doc(self->seg_writer, doc, boost);
+    IndexerIVARS *const ivars = Indexer_IVARS(self);
+    SegWriter_Add_Doc(ivars->seg_writer, doc, boost);
 }
 
 void
 Indexer_delete_by_term(Indexer *self, CharBuf *field, Obj *term) {
-    Schema    *schema = self->schema;
+    IndexerIVARS *const ivars = Indexer_IVARS(self);
+    Schema    *schema = ivars->schema;
     FieldType *type   = Schema_Fetch_Type(schema, field);
 
     // Raise exception if the field isn't indexed.
@@ -288,28 +292,31 @@ Indexer_delete_by_term(Indexer *self, CharBuf *field, Obj *term) {
         VArray *terms = Analyzer_Split(analyzer, (CharBuf*)term);
         Obj *analyzed_term = VA_Fetch(terms, 0);
         if (analyzed_term) {
-            DelWriter_Delete_By_Term(self->del_writer, field,
+            DelWriter_Delete_By_Term(ivars->del_writer, field,
                                      analyzed_term);
         }
         DECREF(terms);
     }
     else {
-        DelWriter_Delete_By_Term(self->del_writer, field, term);
+        DelWriter_Delete_By_Term(ivars->del_writer, field, term);
     }
 }
 
 void
 Indexer_delete_by_query(Indexer *self, Query *query) {
-    DelWriter_Delete_By_Query(self->del_writer, query);
+    IndexerIVARS *const ivars = Indexer_IVARS(self);
+    DelWriter_Delete_By_Query(ivars->del_writer, query);
 }
 
 void
 Indexer_delete_by_doc_id(Indexer *self, int32_t doc_id) {
-    DelWriter_Delete_By_Doc_ID(self->del_writer, doc_id);
+    IndexerIVARS *const ivars = Indexer_IVARS(self);
+    DelWriter_Delete_By_Doc_ID(ivars->del_writer, doc_id);
 }
 
 void
 Indexer_add_index(Indexer *self, Obj *index) {
+    IndexerIVARS *const ivars = Indexer_IVARS(self);
     Folder *other_folder = NULL;
     IndexReader *reader  = NULL;
 
@@ -328,7 +335,7 @@ Indexer_add_index(Indexer *self, Obj *index) {
         THROW(ERR, "Index doesn't seem to contain any data");
     }
     else {
-        Schema *schema       = self->schema;
+        Schema *schema       = ivars->schema;
         Schema *other_schema = IxReader_Get_Schema(reader);
         VArray *other_fields = Schema_All_Fields(other_schema);
         VArray *seg_readers  = IxReader_Seg_Readers(reader);
@@ -339,7 +346,7 @@ Indexer_add_index(Indexer *self, Obj *index) {
         // Add fields to Segment.
         for (uint32_t i = 0, max = VA_Get_Size(other_fields); i < max; i++) {
             CharBuf *other_field = (CharBuf*)VA_Fetch(other_fields, i);
-            Seg_Add_Field(self->segment, other_field);
+            Seg_Add_Field(ivars->segment, other_field);
         }
         DECREF(other_fields);
 
@@ -353,10 +360,10 @@ Indexer_add_index(Indexer *self, Obj *index) {
                                  ? DelReader_Iterator(del_reader)
                                  : NULL;
             I32Array *doc_map = DelWriter_Generate_Doc_Map(
-                                    self->del_writer, deletions,
+                                    ivars->del_writer, deletions,
                                     SegReader_Doc_Max(seg_reader),
-                                    (int32_t)Seg_Get_Count(self->segment));
-            SegWriter_Add_Segment(self->seg_writer, seg_reader, doc_map);
+                                    (int32_t)Seg_Get_Count(ivars->segment));
+            SegWriter_Add_Segment(ivars->seg_writer, seg_reader, doc_map);
             DECREF(deletions);
             DECREF(doc_map);
         }
@@ -369,7 +376,7 @@ Indexer_add_index(Indexer *self, Obj *index) {
 
 void
 Indexer_optimize(Indexer *self) {
-    self->optimize = true;
+    Indexer_IVARS(self)->optimize = true;
 }
 
 static CharBuf*
@@ -391,19 +398,20 @@ S_find_schema_file(Snapshot *snapshot) {
 
 static bool
 S_maybe_merge(Indexer *self, VArray *seg_readers) {
+    IndexerIVARS *const ivars = Indexer_IVARS(self);
     bool      merge_happened  = false;
     uint32_t  num_seg_readers = VA_Get_Size(seg_readers);
-    Lock     *merge_lock      = IxManager_Make_Merge_Lock(self->manager);
+    Lock     *merge_lock      = IxManager_Make_Merge_Lock(ivars->manager);
     bool      got_merge_lock  = Lock_Obtain(merge_lock);
     int64_t   cutoff;
 
     if (got_merge_lock) {
-        self->merge_lock = merge_lock;
+        ivars->merge_lock = merge_lock;
         cutoff = 0;
     }
     else {
         // If something else holds the merge lock, don't interfere.
-        Hash *merge_data = IxManager_Read_Merge_Data(self->manager);
+        Hash *merge_data = IxManager_Read_Merge_Data(ivars->manager);
         if (merge_data) {
             Obj *cutoff_obj = Hash_Fetch_Str(merge_data, "cutoff", 6);
             if (cutoff_obj) {
@@ -422,8 +430,8 @@ S_maybe_merge(Indexer *self, VArray *seg_readers) {
 
     // Get a list of segments to recycle.  Validate and confirm that there are
     // no dupes in the list.
-    VArray *to_merge = IxManager_Recycle(self->manager, self->polyreader,
-                                         self->del_writer, cutoff, self->optimize);
+    VArray *to_merge = IxManager_Recycle(ivars->manager, ivars->polyreader,
+                                         ivars->del_writer, cutoff, ivars->optimize);
 
     Hash *seen = Hash_new(VA_Get_Size(to_merge));
     for (uint32_t i = 0, max = VA_Get_Size(to_merge); i < max; i++) {
@@ -445,26 +453,26 @@ S_maybe_merge(Indexer *self, VArray *seg_readers) {
         SegReader *seg_reader = (SegReader*)VA_Fetch(to_merge, i);
         int64_t seg_num = SegReader_Get_Seg_Num(seg_reader);
         Matcher *deletions
-            = DelWriter_Seg_Deletions(self->del_writer, seg_reader);
+            = DelWriter_Seg_Deletions(ivars->del_writer, seg_reader);
         I32Array *doc_map = DelWriter_Generate_Doc_Map(
-                                self->del_writer, deletions,
+                                ivars->del_writer, deletions,
                                 SegReader_Doc_Max(seg_reader),
-                                (int32_t)Seg_Get_Count(self->segment));
+                                (int32_t)Seg_Get_Count(ivars->segment));
         if (seg_num <= cutoff) {
             THROW(ERR, "Segment %o violates cutoff (%i64 <= %i64)",
                   SegReader_Get_Seg_Name(seg_reader), seg_num, cutoff);
         }
-        SegWriter_Merge_Segment(self->seg_writer, seg_reader, doc_map);
+        SegWriter_Merge_Segment(ivars->seg_writer, seg_reader, doc_map);
         merge_happened = true;
         DECREF(deletions);
         DECREF(doc_map);
     }
 
     // Write out new deletions.
-    if (DelWriter_Updated(self->del_writer)) {
+    if (DelWriter_Updated(ivars->del_writer)) {
         // Only write out if they haven't all been applied.
         if (VA_Get_Size(to_merge) != num_seg_readers) {
-            DelWriter_Finish(self->del_writer);
+            DelWriter_Finish(ivars->del_writer);
         }
     }
 
@@ -474,11 +482,12 @@ S_maybe_merge(Indexer *self, VArray *seg_readers) {
 
 void
 Indexer_prepare_commit(Indexer *self) {
-    VArray   *seg_readers     = PolyReader_Get_Seg_Readers(self->polyreader);
+    IndexerIVARS *const ivars = Indexer_IVARS(self);
+    VArray   *seg_readers     = PolyReader_Get_Seg_Readers(ivars->polyreader);
     uint32_t  num_seg_readers = VA_Get_Size(seg_readers);
     bool      merge_happened  = false;
 
-    if (!self->write_lock || self->prepared) {
+    if (!ivars->write_lock || ivars->prepared) {
         THROW(ERR, "Can't call Prepare_Commit() more than once");
     }
 
@@ -488,26 +497,26 @@ Indexer_prepare_commit(Indexer *self) {
     }
 
     // Add a new segment and write a new snapshot file if...
-    if (Seg_Get_Count(self->segment)             // Docs/segs added.
+    if (Seg_Get_Count(ivars->segment)             // Docs/segs added.
         || merge_happened                        // Some segs merged.
-        || !Snapshot_Num_Entries(self->snapshot) // Initializing index.
-        || DelWriter_Updated(self->del_writer)
+        || !Snapshot_Num_Entries(ivars->snapshot) // Initializing index.
+        || DelWriter_Updated(ivars->del_writer)
        ) {
-        Folder   *folder   = self->folder;
-        Schema   *schema   = self->schema;
-        Snapshot *snapshot = self->snapshot;
+        Folder   *folder   = ivars->folder;
+        Schema   *schema   = ivars->schema;
+        Snapshot *snapshot = ivars->snapshot;
 
         // Derive snapshot and schema file names.
-        DECREF(self->snapfile);
-        self->snapfile = IxManager_Make_Snapshot_Filename(self->manager);
-        CB_Cat_Trusted_Str(self->snapfile, ".temp", 5);
-        uint64_t schema_gen = IxFileNames_extract_gen(self->snapfile);
+        DECREF(ivars->snapfile);
+        ivars->snapfile = IxManager_Make_Snapshot_Filename(ivars->manager);
+        CB_Cat_Trusted_Str(ivars->snapfile, ".temp", 5);
+        uint64_t schema_gen = IxFileNames_extract_gen(ivars->snapfile);
         char base36[StrHelp_MAX_BASE36_BYTES];
         StrHelp_to_base36(schema_gen, &base36);
         CharBuf *new_schema_name = CB_newf("schema_%s.json", base36);
 
         // Finish the segment, write schema file.
-        SegWriter_Finish(self->seg_writer);
+        SegWriter_Finish(ivars->seg_writer);
         Schema_Write(schema, folder, new_schema_name);
         CharBuf *old_schema_name = S_find_schema_file(snapshot);
         if (old_schema_name) {
@@ -517,42 +526,44 @@ Indexer_prepare_commit(Indexer *self) {
         DECREF(new_schema_name);
 
         // Write temporary snapshot file.
-        Folder_Delete(folder, self->snapfile);
-        Snapshot_Write_File(snapshot, folder, self->snapfile);
+        Folder_Delete(folder, ivars->snapfile);
+        Snapshot_Write_File(snapshot, folder, ivars->snapfile);
 
-        self->needs_commit = true;
+        ivars->needs_commit = true;
     }
 
     // Close reader, so that we can delete its files if appropriate.
-    PolyReader_Close(self->polyreader);
+    PolyReader_Close(ivars->polyreader);
 
-    self->prepared = true;
+    ivars->prepared = true;
 }
 
 void
 Indexer_commit(Indexer *self) {
+    IndexerIVARS *const ivars = Indexer_IVARS(self);
+
     // Safety check.
-    if (!self->write_lock) {
+    if (!ivars->write_lock) {
         THROW(ERR, "Can't call commit() more than once");
     }
 
-    if (!self->prepared) {
+    if (!ivars->prepared) {
         Indexer_Prepare_Commit(self);
     }
 
-    if (self->needs_commit) {
+    if (ivars->needs_commit) {
         bool success;
 
         // Rename temp snapshot file.
-        CharBuf *temp_snapfile = CB_Clone(self->snapfile);
-        CB_Chop(self->snapfile, sizeof(".temp") - 1);
-        Snapshot_Set_Path(self->snapshot, self->snapfile);
-        success = Folder_Rename(self->folder, temp_snapfile, self->snapfile);
+        CharBuf *temp_snapfile = CB_Clone(ivars->snapfile);
+        CB_Chop(ivars->snapfile, sizeof(".temp") - 1);
+        Snapshot_Set_Path(ivars->snapshot, ivars->snapfile);
+        success = Folder_Rename(ivars->folder, temp_snapfile, ivars->snapfile);
         DECREF(temp_snapfile);
         if (!success) { RETHROW(INCREF(Err_get_error())); }
 
         // Purge obsolete files.
-        FilePurger_Purge(self->file_purger);
+        FilePurger_Purge(ivars->file_purger);
     }
 
     // Release locks, invalidating the Indexer.
@@ -562,34 +573,36 @@ Indexer_commit(Indexer *self) {
 
 Schema*
 Indexer_get_schema(Indexer *self) {
-    return self->schema;
+    return Indexer_IVARS(self)->schema;
 }
 
 SegWriter*
 Indexer_get_seg_writer(Indexer *self) {
-    return self->seg_writer;
+    return Indexer_IVARS(self)->seg_writer;
 }
 
 Doc*
 Indexer_get_stock_doc(Indexer *self) {
-    return self->stock_doc;
+    return Indexer_IVARS(self)->stock_doc;
 }
 
 static void
 S_release_write_lock(Indexer *self) {
-    if (self->write_lock) {
-        Lock_Release(self->write_lock);
-        DECREF(self->write_lock);
-        self->write_lock = NULL;
+    IndexerIVARS *const ivars = Indexer_IVARS(self);
+    if (ivars->write_lock) {
+        Lock_Release(ivars->write_lock);
+        DECREF(ivars->write_lock);
+        ivars->write_lock = NULL;
     }
 }
 
 static void
 S_release_merge_lock(Indexer *self) {
-    if (self->merge_lock) {
-        Lock_Release(self->merge_lock);
-        DECREF(self->merge_lock);
-        self->merge_lock = NULL;
+    IndexerIVARS *const ivars = Indexer_IVARS(self);
+    if (ivars->merge_lock) {
+        Lock_Release(ivars->merge_lock);
+        DECREF(ivars->merge_lock);
+        ivars->merge_lock = NULL;
     }
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/Inverter.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/Inverter.c b/core/Lucy/Index/Inverter.c
index 10077ed..77c0bcc 100644
--- a/core/Lucy/Index/Inverter.c
+++ b/core/Lucy/Index/Inverter.c
@@ -40,138 +40,155 @@ Inverter_new(Schema *schema, Segment *segment) {
 
 Inverter*
 Inverter_init(Inverter *self, Schema *schema, Segment *segment) {
+    InverterIVARS *const ivars = Inverter_IVARS(self);
+
     // Init.
-    self->tick       = -1;
-    self->doc        = NULL;
-    self->sorted     = false;
-    self->blank      = InvEntry_new(NULL, NULL, 0);
-    self->current    = self->blank;
+    ivars->tick       = -1;
+    ivars->doc        = NULL;
+    ivars->sorted     = false;
+    ivars->blank      = InvEntry_new(NULL, NULL, 0);
+    ivars->current    = ivars->blank;
 
     // Derive.
-    self->entry_pool = VA_new(Schema_Num_Fields(schema));
-    self->entries    = VA_new(Schema_Num_Fields(schema));
+    ivars->entry_pool = VA_new(Schema_Num_Fields(schema));
+    ivars->entries    = VA_new(Schema_Num_Fields(schema));
 
     // Assign.
-    self->schema  = (Schema*)INCREF(schema);
-    self->segment = (Segment*)INCREF(segment);
+    ivars->schema  = (Schema*)INCREF(schema);
+    ivars->segment = (Segment*)INCREF(segment);
 
     return self;
 }
 
 void
 Inverter_destroy(Inverter *self) {
+    InverterIVARS *const ivars = Inverter_IVARS(self);
     Inverter_Clear(self);
-    DECREF(self->blank);
-    DECREF(self->entries);
-    DECREF(self->entry_pool);
-    DECREF(self->schema);
-    DECREF(self->segment);
+    DECREF(ivars->blank);
+    DECREF(ivars->entries);
+    DECREF(ivars->entry_pool);
+    DECREF(ivars->schema);
+    DECREF(ivars->segment);
     SUPER_DESTROY(self, INVERTER);
 }
 
 uint32_t
 Inverter_iterate(Inverter *self) {
-    self->tick = -1;
-    if (!self->sorted) {
-        VA_Sort(self->entries, NULL, NULL);
-        self->sorted = true;
+    InverterIVARS *const ivars = Inverter_IVARS(self);
+    ivars->tick = -1;
+    if (!ivars->sorted) {
+        VA_Sort(ivars->entries, NULL, NULL);
+        ivars->sorted = true;
     }
-    return VA_Get_Size(self->entries);
+    return VA_Get_Size(ivars->entries);
 }
 
 int32_t
 Inverter_next(Inverter *self) {
-    self->current = (InverterEntry*)VA_Fetch(self->entries, ++self->tick);
-    if (!self->current) { self->current = self->blank; } // Exhausted.
-    return self->current->field_num;
+    InverterIVARS *const ivars = Inverter_IVARS(self);
+    ivars->current = (InverterEntry*)VA_Fetch(ivars->entries, ++ivars->tick);
+    if (!ivars->current) { ivars->current = ivars->blank; } // Exhausted.
+    return InvEntry_IVARS(ivars->current)->field_num;
 }
 
 void
 Inverter_set_doc(Inverter *self, Doc *doc) {
+    InverterIVARS *const ivars = Inverter_IVARS(self);
     Inverter_Clear(self); // Zap all cached field values and Inversions.
-    self->doc = (Doc*)INCREF(doc);
+    ivars->doc = (Doc*)INCREF(doc);
 }
 
 void
 Inverter_set_boost(Inverter *self, float boost) {
-    self->boost = boost;
+    Inverter_IVARS(self)->boost = boost;
 }
 
 float
 Inverter_get_boost(Inverter *self) {
-    return self->boost;
+    return Inverter_IVARS(self)->boost;
 }
 
 Doc*
 Inverter_get_doc(Inverter *self) {
-    return self->doc;
+    return Inverter_IVARS(self)->doc;
 }
 
 CharBuf*
 Inverter_get_field_name(Inverter *self) {
-    return self->current->field;
+    InverterEntry *current = Inverter_IVARS(self)->current;
+    return InvEntry_IVARS(current)->field;
 }
 
 Obj*
 Inverter_get_value(Inverter *self) {
-    return self->current->value;
+    InverterEntry *current = Inverter_IVARS(self)->current;
+    return InvEntry_IVARS(current)->value;
 }
 
 FieldType*
 Inverter_get_type(Inverter *self) {
-    return self->current->type;
+    InverterEntry *current = Inverter_IVARS(self)->current;
+    return InvEntry_IVARS(current)->type;
 }
 
 Analyzer*
 Inverter_get_analyzer(Inverter *self) {
-    return self->current->analyzer;
+    InverterEntry *current = Inverter_IVARS(self)->current;
+    return InvEntry_IVARS(current)->analyzer;
 }
 
 Similarity*
 Inverter_get_similarity(Inverter *self) {
-    return self->current->sim;
+    InverterEntry *current = Inverter_IVARS(self)->current;
+    return InvEntry_IVARS(current)->sim;
 }
 
 Inversion*
 Inverter_get_inversion(Inverter *self) {
-    return self->current->inversion;
+    InverterEntry *current = Inverter_IVARS(self)->current;
+    return InvEntry_IVARS(current)->inversion;
 }
 
 
 void
 Inverter_add_field(Inverter *self, InverterEntry *entry) {
+    InverterIVARS *const ivars = Inverter_IVARS(self);
+    InverterEntryIVARS *const entry_ivars = InvEntry_IVARS(entry);
+
     // Get an Inversion, going through analyzer if appropriate.
-    if (entry->analyzer) {
-        DECREF(entry->inversion);
-        entry->inversion = Analyzer_Transform_Text(entry->analyzer,
-                                                   (CharBuf*)entry->value);
-        Inversion_Invert(entry->inversion);
+    if (entry_ivars->analyzer) {
+        DECREF(entry_ivars->inversion);
+        entry_ivars->inversion
+            = Analyzer_Transform_Text(entry_ivars->analyzer,
+                                      (CharBuf*)entry_ivars->value);
+        Inversion_Invert(entry_ivars->inversion);
     }
-    else if (entry->indexed || entry->highlightable) {
-        ViewCharBuf *value = (ViewCharBuf*)entry->value;
+    else if (entry_ivars->indexed || entry_ivars->highlightable) {
+        ViewCharBuf *value = (ViewCharBuf*)entry_ivars->value;
         size_t token_len = ViewCB_Get_Size(value);
         Token *seed = Token_new((char*)ViewCB_Get_Ptr8(value),
                                 token_len, 0, token_len, 1.0f, 1);
-        DECREF(entry->inversion);
-        entry->inversion = Inversion_new(seed);
+        DECREF(entry_ivars->inversion);
+        entry_ivars->inversion = Inversion_new(seed);
         DECREF(seed);
-        Inversion_Invert(entry->inversion); // Nearly a no-op.
+        Inversion_Invert(entry_ivars->inversion); // Nearly a no-op.
     }
 
     // Prime the iterator.
-    VA_Push(self->entries, INCREF(entry));
-    self->sorted = false;
+    VA_Push(ivars->entries, INCREF(entry));
+    ivars->sorted = false;
 }
 
 void
 Inverter_clear(Inverter *self) {
-    for (uint32_t i = 0, max = VA_Get_Size(self->entries); i < max; i++) {
-        InvEntry_Clear(VA_Fetch(self->entries, i));
+    InverterIVARS *const ivars = Inverter_IVARS(self);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->entries); i < max; i++) {
+        InvEntry_Clear(VA_Fetch(ivars->entries, i));
     }
-    VA_Clear(self->entries);
-    self->tick = -1;
-    DECREF(self->doc);
-    self->doc = NULL;
+    VA_Clear(ivars->entries);
+    ivars->tick = -1;
+    DECREF(ivars->doc);
+    ivars->doc = NULL;
 }
 
 InverterEntry*
@@ -183,49 +200,50 @@ InvEntry_new(Schema *schema, const CharBuf *field, int32_t field_num) {
 InverterEntry*
 InvEntry_init(InverterEntry *self, Schema *schema, const CharBuf *field,
               int32_t field_num) {
-    self->field_num  = field_num;
-    self->field      = field ? CB_Clone(field) : NULL;
-    self->inversion  = NULL;
+    InverterEntryIVARS *const ivars = InvEntry_IVARS(self);
+    ivars->field_num  = field_num;
+    ivars->field      = field ? CB_Clone(field) : NULL;
+    ivars->inversion  = NULL;
 
     if (schema) {
-        self->analyzer
+        ivars->analyzer
             = (Analyzer*)INCREF(Schema_Fetch_Analyzer(schema, field));
-        self->sim  = (Similarity*)INCREF(Schema_Fetch_Sim(schema, field));
-        self->type = (FieldType*)INCREF(Schema_Fetch_Type(schema, field));
-        if (!self->type) { THROW(ERR, "Unknown field: '%o'", field); }
+        ivars->sim  = (Similarity*)INCREF(Schema_Fetch_Sim(schema, field));
+        ivars->type = (FieldType*)INCREF(Schema_Fetch_Type(schema, field));
+        if (!ivars->type) { THROW(ERR, "Unknown field: '%o'", field); }
 
-        uint8_t prim_id = FType_Primitive_ID(self->type);
+        uint8_t prim_id = FType_Primitive_ID(ivars->type);
         switch (prim_id & FType_PRIMITIVE_ID_MASK) {
             case FType_TEXT:
-                self->value = (Obj*)ViewCB_new_from_trusted_utf8(NULL, 0);
+                ivars->value = (Obj*)ViewCB_new_from_trusted_utf8(NULL, 0);
                 break;
             case FType_BLOB:
-                self->value = (Obj*)ViewBB_new(NULL, 0);
+                ivars->value = (Obj*)ViewBB_new(NULL, 0);
                 break;
             case FType_INT32:
-                self->value = (Obj*)Int32_new(0);
+                ivars->value = (Obj*)Int32_new(0);
                 break;
             case FType_INT64:
-                self->value = (Obj*)Int64_new(0);
+                ivars->value = (Obj*)Int64_new(0);
                 break;
             case FType_FLOAT32:
-                self->value = (Obj*)Float32_new(0);
+                ivars->value = (Obj*)Float32_new(0);
                 break;
             case FType_FLOAT64:
-                self->value = (Obj*)Float64_new(0);
+                ivars->value = (Obj*)Float64_new(0);
                 break;
             default:
                 THROW(ERR, "Unrecognized primitive id: %i8", prim_id);
         }
 
-        self->indexed = FType_Indexed(self->type);
-        if (self->indexed && FType_Is_A(self->type, NUMERICTYPE)) {
+        ivars->indexed = FType_Indexed(ivars->type);
+        if (ivars->indexed && FType_Is_A(ivars->type, NUMERICTYPE)) {
             THROW(ERR, "Field '%o' spec'd as indexed, but numerical types cannot "
                   "be indexed yet", field);
         }
-        if (FType_Is_A(self->type, FULLTEXTTYPE)) {
-            self->highlightable
-                = FullTextType_Highlightable((FullTextType*)self->type);
+        if (FType_Is_A(ivars->type, FULLTEXTTYPE)) {
+            ivars->highlightable
+                = FullTextType_Highlightable((FullTextType*)ivars->type);
         }
     }
     return self;
@@ -233,26 +251,29 @@ InvEntry_init(InverterEntry *self, Schema *schema, const CharBuf *field,
 
 void
 InvEntry_destroy(InverterEntry *self) {
-    DECREF(self->field);
-    DECREF(self->value);
-    DECREF(self->analyzer);
-    DECREF(self->type);
-    DECREF(self->sim);
-    DECREF(self->inversion);
+    InverterEntryIVARS *const ivars = InvEntry_IVARS(self);
+    DECREF(ivars->field);
+    DECREF(ivars->value);
+    DECREF(ivars->analyzer);
+    DECREF(ivars->type);
+    DECREF(ivars->sim);
+    DECREF(ivars->inversion);
     SUPER_DESTROY(self, INVERTERENTRY);
 }
 
 void
 InvEntry_clear(InverterEntry *self) {
-    DECREF(self->inversion);
-    self->inversion = NULL;
+    InverterEntryIVARS *const ivars = InvEntry_IVARS(self);
+    DECREF(ivars->inversion);
+    ivars->inversion = NULL;
 }
 
 int32_t
 InvEntry_compare_to(InverterEntry *self, Obj *other) {
-    InverterEntry *competitor
-        = (InverterEntry*)CERTIFY(other, INVERTERENTRY);
-    return self->field_num - competitor->field_num;
+    CERTIFY(other, INVERTERENTRY);
+    InverterEntryIVARS *const ivars = InvEntry_IVARS(self);
+    InverterEntryIVARS *const ovars = InvEntry_IVARS((InverterEntry*)other);
+    return ivars->field_num - ovars->field_num;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/LexIndex.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/LexIndex.c b/core/Lucy/Index/LexIndex.c
index dca9adf..3d3200e 100644
--- a/core/Lucy/Index/LexIndex.c
+++ b/core/Lucy/Index/LexIndex.c
@@ -50,41 +50,42 @@ LexIndex_init(LexIndex *self, Schema *schema, Folder *folder,
 
     // Init.
     Lex_init((Lexicon*)self, field);
-    self->tinfo        = TInfo_new(0);
-    self->tick         = 0;
+    LexIndexIVARS *const ivars = LexIndex_IVARS(self);
+    ivars->tinfo        = TInfo_new(0);
+    ivars->tick         = 0;
 
     // Derive
-    self->field_type = Schema_Fetch_Type(schema, field);
-    if (!self->field_type) {
+    ivars->field_type = Schema_Fetch_Type(schema, field);
+    if (!ivars->field_type) {
         CharBuf *mess = MAKE_MESS("Unknown field: '%o'", field);
         DECREF(ix_file);
         DECREF(ixix_file);
         DECREF(self);
         Err_throw_mess(ERR, mess);
     }
-    INCREF(self->field_type);
-    self->term_stepper = FType_Make_Term_Stepper(self->field_type);
-    self->ixix_in = Folder_Open_In(folder, ixix_file);
-    if (!self->ixix_in) {
+    INCREF(ivars->field_type);
+    ivars->term_stepper = FType_Make_Term_Stepper(ivars->field_type);
+    ivars->ixix_in = Folder_Open_In(folder, ixix_file);
+    if (!ivars->ixix_in) {
         Err *error = (Err*)INCREF(Err_get_error());
         DECREF(ix_file);
         DECREF(ixix_file);
         DECREF(self);
         RETHROW(error);
     }
-    self->ix_in = Folder_Open_In(folder, ix_file);
-    if (!self->ix_in) {
+    ivars->ix_in = Folder_Open_In(folder, ix_file);
+    if (!ivars->ix_in) {
         Err *error = (Err*)INCREF(Err_get_error());
         DECREF(ix_file);
         DECREF(ixix_file);
         DECREF(self);
         RETHROW(error);
     }
-    self->index_interval = Arch_Index_Interval(arch);
-    self->skip_interval  = Arch_Skip_Interval(arch);
-    self->size    = (int32_t)(InStream_Length(self->ixix_in) / sizeof(int64_t));
-    self->offsets = (int64_t*)InStream_Buf(self->ixix_in,
-                                           (size_t)InStream_Length(self->ixix_in));
+    ivars->index_interval = Arch_Index_Interval(arch);
+    ivars->skip_interval  = Arch_Skip_Interval(arch);
+    ivars->size    = (int32_t)(InStream_Length(ivars->ixix_in) / sizeof(int64_t));
+    ivars->offsets = (int64_t*)InStream_Buf(ivars->ixix_in,
+                                           (size_t)InStream_Length(ivars->ixix_in));
 
     DECREF(ixix_file);
     DECREF(ix_file);
@@ -94,55 +95,60 @@ LexIndex_init(LexIndex *self, Schema *schema, Folder *folder,
 
 void
 LexIndex_destroy(LexIndex *self) {
-    DECREF(self->field_type);
-    DECREF(self->ixix_in);
-    DECREF(self->ix_in);
-    DECREF(self->term_stepper);
-    DECREF(self->tinfo);
+    LexIndexIVARS *const ivars = LexIndex_IVARS(self);
+    DECREF(ivars->field_type);
+    DECREF(ivars->ixix_in);
+    DECREF(ivars->ix_in);
+    DECREF(ivars->term_stepper);
+    DECREF(ivars->tinfo);
     SUPER_DESTROY(self, LEXINDEX);
 }
 
 int32_t
 LexIndex_get_term_num(LexIndex *self) {
-    return (self->index_interval * self->tick) - 1;
+    LexIndexIVARS *const ivars = LexIndex_IVARS(self);
+    return (ivars->index_interval * ivars->tick) - 1;
 }
 
 Obj*
 LexIndex_get_term(LexIndex *self) {
-    return TermStepper_Get_Value(self->term_stepper);
+    LexIndexIVARS *const ivars = LexIndex_IVARS(self);
+    return TermStepper_Get_Value(ivars->term_stepper);
 }
 
 TermInfo*
 LexIndex_get_term_info(LexIndex *self) {
-    return self->tinfo;
+    return LexIndex_IVARS(self)->tinfo;
 }
 
 static void
 S_read_entry(LexIndex *self) {
-    InStream *ix_in  = self->ix_in;
-    TermInfo *tinfo  = self->tinfo;
-    int64_t offset = (int64_t)NumUtil_decode_bigend_u64(self->offsets + self->tick);
+    LexIndexIVARS *const ivars = LexIndex_IVARS(self);
+    InStream *ix_in  = ivars->ix_in;
+    TermInfoIVARS *const tinfo_ivars = TInfo_IVARS(ivars->tinfo);
+    int64_t offset = (int64_t)NumUtil_decode_bigend_u64(ivars->offsets + ivars->tick);
     InStream_Seek(ix_in, offset);
-    TermStepper_Read_Key_Frame(self->term_stepper, ix_in);
-    tinfo->doc_freq     = InStream_Read_C32(ix_in);
-    tinfo->post_filepos = InStream_Read_C64(ix_in);
-    tinfo->skip_filepos = tinfo->doc_freq >= self->skip_interval
+    TermStepper_Read_Key_Frame(ivars->term_stepper, ix_in);
+    tinfo_ivars->doc_freq     = InStream_Read_C32(ix_in);
+    tinfo_ivars->post_filepos = InStream_Read_C64(ix_in);
+    tinfo_ivars->skip_filepos = tinfo_ivars->doc_freq >= ivars->skip_interval
                           ? InStream_Read_C64(ix_in)
                           : 0;
-    tinfo->lex_filepos  = InStream_Read_C64(ix_in);
+    tinfo_ivars->lex_filepos  = InStream_Read_C64(ix_in);
 }
 
 void
 LexIndex_seek(LexIndex *self, Obj *target) {
-    TermStepper *term_stepper = self->term_stepper;
-    InStream    *ix_in        = self->ix_in;
-    FieldType   *type         = self->field_type;
+    LexIndexIVARS *const ivars = LexIndex_IVARS(self);
+    TermStepper *term_stepper = ivars->term_stepper;
+    InStream    *ix_in        = ivars->ix_in;
+    FieldType   *type         = ivars->field_type;
     int32_t      lo           = 0;
-    int32_t      hi           = self->size - 1;
+    int32_t      hi           = ivars->size - 1;
     int32_t      result       = -100;
 
-    if (target == NULL || self->size == 0) {
-        self->tick = 0;
+    if (target == NULL || ivars->size == 0) {
+        ivars->tick = 0;
         return;
     }
     else {
@@ -163,12 +169,12 @@ LexIndex_seek(LexIndex *self, Obj *target) {
     while (hi >= lo) {
         const int32_t mid = lo + ((hi - lo) / 2);
         const int64_t offset
-            = (int64_t)NumUtil_decode_bigend_u64(self->offsets + mid);
+            = (int64_t)NumUtil_decode_bigend_u64(ivars->offsets + mid);
         InStream_Seek(ix_in, offset);
         TermStepper_Read_Key_Frame(term_stepper, ix_in);
 
         // Compare values.  There is no need for a NULL-check because the term
-        // number is alway between 0 and self->size - 1.
+        // number is alway between 0 and ivars->size - 1.
         Obj *value = TermStepper_Get_Value(term_stepper);
         int32_t comparison = FType_Compare_Values(type, target, value);
 
@@ -185,7 +191,7 @@ LexIndex_seek(LexIndex *self, Obj *target) {
     }
 
     // Record the index of the entry we've seeked to, then read entry.
-    self->tick = hi == -1 // indicating that target lt first entry
+    ivars->tick = hi == -1 // indicating that target lt first entry
                  ? 0
                  : result == -100 // if result is still -100, it wasn't set
                  ? hi

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/Lexicon.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/Lexicon.c b/core/Lucy/Index/Lexicon.c
index c26b1e0..d1fd76a 100644
--- a/core/Lucy/Index/Lexicon.c
+++ b/core/Lucy/Index/Lexicon.c
@@ -21,19 +21,21 @@
 
 Lexicon*
 Lex_init(Lexicon *self, const CharBuf *field) {
-    self->field = CB_Clone(field);
+    LexiconIVARS *const ivars = Lex_IVARS(self);
+    ivars->field = CB_Clone(field);
     ABSTRACT_CLASS_CHECK(self, LEXICON);
     return self;
 }
 
 CharBuf*
 Lex_get_field(Lexicon *self) {
-    return self->field;
+    return Lex_IVARS(self)->field;
 }
 
 void
 Lex_destroy(Lexicon *self) {
-    DECREF(self->field);
+    LexiconIVARS *const ivars = Lex_IVARS(self);
+    DECREF(ivars->field);
     SUPER_DESTROY(self, LEXICON);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/LexiconReader.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/LexiconReader.c b/core/Lucy/Index/LexiconReader.c
index 9a82ef6..e08bea2 100644
--- a/core/Lucy/Index/LexiconReader.c
+++ b/core/Lucy/Index/LexiconReader.c
@@ -61,27 +61,30 @@ PolyLexReader_init(PolyLexiconReader *self, VArray *readers,
         if (!schema) { schema = LexReader_Get_Schema(reader); }
     }
     LexReader_init((LexiconReader*)self, schema, NULL, NULL, NULL, -1);
-    self->readers = (VArray*)INCREF(readers);
-    self->offsets = (I32Array*)INCREF(offsets);
+    PolyLexiconReaderIVARS *const ivars = PolyLexReader_IVARS(self);
+    ivars->readers = (VArray*)INCREF(readers);
+    ivars->offsets = (I32Array*)INCREF(offsets);
     return self;
 }
 
 void
 PolyLexReader_close(PolyLexiconReader *self) {
-    if (self->readers) {
-        for (uint32_t i = 0, max = VA_Get_Size(self->readers); i < max; i++) {
+    PolyLexiconReaderIVARS *const ivars = PolyLexReader_IVARS(self);
+    if (ivars->readers) {
+        for (uint32_t i = 0, max = VA_Get_Size(ivars->readers); i < max; i++) {
             LexiconReader *reader
-                = (LexiconReader*)VA_Fetch(self->readers, i);
+                = (LexiconReader*)VA_Fetch(ivars->readers, i);
             if (reader) { LexReader_Close(reader); }
         }
-        VA_Clear(self->readers);
+        VA_Clear(ivars->readers);
     }
 }
 
 void
 PolyLexReader_destroy(PolyLexiconReader *self) {
-    DECREF(self->readers);
-    DECREF(self->offsets);
+    PolyLexiconReaderIVARS *const ivars = PolyLexReader_IVARS(self);
+    DECREF(ivars->readers);
+    DECREF(ivars->offsets);
     SUPER_DESTROY(self, POLYLEXICONREADER);
 }
 
@@ -94,7 +97,8 @@ PolyLexReader_lexicon(PolyLexiconReader *self, const CharBuf *field,
         Schema *schema = PolyLexReader_Get_Schema(self);
         FieldType *type = Schema_Fetch_Type(schema, field);
         if (type != NULL) {
-            lexicon = PolyLex_new(field, self->readers);
+            PolyLexiconReaderIVARS *const ivars = PolyLexReader_IVARS(self);
+            lexicon = PolyLex_new(field, ivars->readers);
             if (!PolyLex_Get_Num_Seg_Lexicons(lexicon)) {
                 DECREF(lexicon);
                 return NULL;
@@ -109,9 +113,10 @@ PolyLexReader_lexicon(PolyLexiconReader *self, const CharBuf *field,
 uint32_t
 PolyLexReader_doc_freq(PolyLexiconReader *self, const CharBuf *field,
                        Obj *term) {
+    PolyLexiconReaderIVARS *const ivars = PolyLexReader_IVARS(self);
     uint32_t doc_freq = 0;
-    for (uint32_t i = 0, max = VA_Get_Size(self->readers); i < max; i++) {
-        LexiconReader *reader = (LexiconReader*)VA_Fetch(self->readers, i);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->readers); i < max; i++) {
+        LexiconReader *reader = (LexiconReader*)VA_Fetch(ivars->readers, i);
         if (reader) {
             doc_freq += LexReader_Doc_Freq(reader, field, term);
         }
@@ -157,15 +162,16 @@ DefLexReader_init(DefaultLexiconReader *self, Schema *schema, Folder *folder,
     // Init.
     LexReader_init((LexiconReader*)self, schema, folder, snapshot, segments,
                    seg_tick);
+    DefaultLexiconReaderIVARS *const ivars = DefLexReader_IVARS(self);
     Segment *segment = DefLexReader_Get_Segment(self);
 
     // Build an array of SegLexicon objects.
-    self->lexicons = VA_new(Schema_Num_Fields(schema));
+    ivars->lexicons = VA_new(Schema_Num_Fields(schema));
     for (uint32_t i = 1, max = Schema_Num_Fields(schema) + 1; i < max; i++) {
         CharBuf *field = Seg_Field_Name(segment, i);
         if (field && S_has_data(schema, folder, segment, field)) {
             SegLexicon *lexicon = SegLex_new(schema, folder, segment, field);
-            VA_Store(self->lexicons, i, (Obj*)lexicon);
+            VA_Store(ivars->lexicons, i, (Obj*)lexicon);
         }
     }
 
@@ -174,26 +180,29 @@ DefLexReader_init(DefaultLexiconReader *self, Schema *schema, Folder *folder,
 
 void
 DefLexReader_close(DefaultLexiconReader *self) {
-    DECREF(self->lexicons);
-    self->lexicons = NULL;
+    DefaultLexiconReaderIVARS *const ivars = DefLexReader_IVARS(self);
+    DECREF(ivars->lexicons);
+    ivars->lexicons = NULL;
 }
 
 void
 DefLexReader_destroy(DefaultLexiconReader *self) {
-    DECREF(self->lexicons);
+    DefaultLexiconReaderIVARS *const ivars = DefLexReader_IVARS(self);
+    DECREF(ivars->lexicons);
     SUPER_DESTROY(self, DEFAULTLEXICONREADER);
 }
 
 Lexicon*
 DefLexReader_lexicon(DefaultLexiconReader *self, const CharBuf *field,
                      Obj *term) {
-    int32_t     field_num = Seg_Field_Num(self->segment, field);
-    SegLexicon *orig      = (SegLexicon*)VA_Fetch(self->lexicons, field_num);
+    DefaultLexiconReaderIVARS *const ivars = DefLexReader_IVARS(self);
+    int32_t     field_num = Seg_Field_Num(ivars->segment, field);
+    SegLexicon *orig      = (SegLexicon*)VA_Fetch(ivars->lexicons, field_num);
     SegLexicon *lexicon   = NULL;
 
     if (orig) { // i.e. has data
         lexicon
-            = SegLex_new(self->schema, self->folder, self->segment, field);
+            = SegLex_new(ivars->schema, ivars->folder, ivars->segment, field);
         SegLex_Seek(lexicon, term);
     }
 
@@ -202,10 +211,11 @@ DefLexReader_lexicon(DefaultLexiconReader *self, const CharBuf *field,
 
 static TermInfo*
 S_find_tinfo(DefaultLexiconReader *self, const CharBuf *field, Obj *target) {
+    DefaultLexiconReaderIVARS *const ivars = DefLexReader_IVARS(self);
     if (field != NULL && target != NULL) {
-        int32_t field_num = Seg_Field_Num(self->segment, field);
+        int32_t field_num = Seg_Field_Num(ivars->segment, field);
         SegLexicon *lexicon
-            = (SegLexicon*)VA_Fetch(self->lexicons, field_num);
+            = (SegLexicon*)VA_Fetch(ivars->lexicons, field_num);
 
         if (lexicon) {
             // Iterate until the result is ge the term.

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/LexiconWriter.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/LexiconWriter.c b/core/Lucy/Index/LexiconWriter.c
index 9a65fa3..115771e 100644
--- a/core/Lucy/Index/LexiconWriter.c
+++ b/core/Lucy/Index/LexiconWriter.c
@@ -46,79 +46,85 @@ LexWriter_init(LexiconWriter *self, Schema *schema, Snapshot *snapshot,
     Architecture *arch = Schema_Get_Architecture(schema);
 
     DataWriter_init((DataWriter*)self, schema, snapshot, segment, polyreader);
+    LexiconWriterIVARS *const ivars = LexWriter_IVARS(self);
 
     // Assign.
-    self->index_interval = Arch_Index_Interval(arch);
-    self->skip_interval  = Arch_Skip_Interval(arch);
+    ivars->index_interval = Arch_Index_Interval(arch);
+    ivars->skip_interval  = Arch_Skip_Interval(arch);
 
     // Init.
-    self->ix_out             = NULL;
-    self->ixix_out           = NULL;
-    self->dat_out            = NULL;
-    self->count              = 0;
-    self->ix_count           = 0;
-    self->dat_file           = CB_new(30);
-    self->ix_file            = CB_new(30);
-    self->ixix_file          = CB_new(30);
-    self->counts             = Hash_new(0);
-    self->ix_counts          = Hash_new(0);
-    self->temp_mode          = false;
-    self->term_stepper       = NULL;
-    self->tinfo_stepper      = (TermStepper*)MatchTInfoStepper_new(schema);
+    ivars->ix_out             = NULL;
+    ivars->ixix_out           = NULL;
+    ivars->dat_out            = NULL;
+    ivars->count              = 0;
+    ivars->ix_count           = 0;
+    ivars->dat_file           = CB_new(30);
+    ivars->ix_file            = CB_new(30);
+    ivars->ixix_file          = CB_new(30);
+    ivars->counts             = Hash_new(0);
+    ivars->ix_counts          = Hash_new(0);
+    ivars->temp_mode          = false;
+    ivars->term_stepper       = NULL;
+    ivars->tinfo_stepper      = (TermStepper*)MatchTInfoStepper_new(schema);
 
     return self;
 }
 
 void
 LexWriter_destroy(LexiconWriter *self) {
-    DECREF(self->term_stepper);
-    DECREF(self->tinfo_stepper);
-    DECREF(self->dat_file);
-    DECREF(self->ix_file);
-    DECREF(self->ixix_file);
-    DECREF(self->dat_out);
-    DECREF(self->ix_out);
-    DECREF(self->ixix_out);
-    DECREF(self->counts);
-    DECREF(self->ix_counts);
+    LexiconWriterIVARS *const ivars = LexWriter_IVARS(self);
+    DECREF(ivars->term_stepper);
+    DECREF(ivars->tinfo_stepper);
+    DECREF(ivars->dat_file);
+    DECREF(ivars->ix_file);
+    DECREF(ivars->ixix_file);
+    DECREF(ivars->dat_out);
+    DECREF(ivars->ix_out);
+    DECREF(ivars->ixix_out);
+    DECREF(ivars->counts);
+    DECREF(ivars->ix_counts);
     SUPER_DESTROY(self, LEXICONWRITER);
 }
 
 static void
 S_add_last_term_to_ix(LexiconWriter *self) {
+    LexiconWriterIVARS *const ivars = LexWriter_IVARS(self);
+
     // Write file pointer to index record.
-    OutStream_Write_I64(self->ixix_out, OutStream_Tell(self->ix_out));
+    OutStream_Write_I64(ivars->ixix_out, OutStream_Tell(ivars->ix_out));
 
     // Write term and file pointer to main record.  Track count of terms added
     // to ix.
-    TermStepper_Write_Key_Frame(self->term_stepper,
-                                self->ix_out, TermStepper_Get_Value(self->term_stepper));
-    TermStepper_Write_Key_Frame(self->tinfo_stepper,
-                                self->ix_out, TermStepper_Get_Value(self->tinfo_stepper));
-    OutStream_Write_C64(self->ix_out, OutStream_Tell(self->dat_out));
-    self->ix_count++;
+    TermStepper_Write_Key_Frame(ivars->term_stepper,
+                                ivars->ix_out, TermStepper_Get_Value(ivars->term_stepper));
+    TermStepper_Write_Key_Frame(ivars->tinfo_stepper,
+                                ivars->ix_out, TermStepper_Get_Value(ivars->tinfo_stepper));
+    OutStream_Write_C64(ivars->ix_out, OutStream_Tell(ivars->dat_out));
+    ivars->ix_count++;
 }
 
 void
 LexWriter_add_term(LexiconWriter* self, CharBuf* term_text, TermInfo* tinfo) {
-    OutStream *dat_out = self->dat_out;
+    LexiconWriterIVARS *const ivars = LexWriter_IVARS(self);
+    OutStream *dat_out = ivars->dat_out;
 
-    if ((self->count % self->index_interval == 0)
-        && !self->temp_mode
+    if ((ivars->count % ivars->index_interval == 0)
+        && !ivars->temp_mode
        ) {
         // Write a subset of entries to lexicon.ix.
         S_add_last_term_to_ix(self);
     }
 
-    TermStepper_Write_Delta(self->term_stepper, dat_out, (Obj*)term_text);
-    TermStepper_Write_Delta(self->tinfo_stepper, dat_out, (Obj*)tinfo);
+    TermStepper_Write_Delta(ivars->term_stepper, dat_out, (Obj*)term_text);
+    TermStepper_Write_Delta(ivars->tinfo_stepper, dat_out, (Obj*)tinfo);
 
     // Track number of terms.
-    self->count++;
+    ivars->count++;
 }
 
 void
 LexWriter_start_field(LexiconWriter *self, int32_t field_num) {
+    LexiconWriterIVARS *const ivars = LexWriter_IVARS(self);
     Segment   *const segment  = LexWriter_Get_Segment(self);
     Folder    *const folder   = LexWriter_Get_Folder(self);
     Schema    *const schema   = LexWriter_Get_Schema(self);
@@ -127,104 +133,110 @@ LexWriter_start_field(LexiconWriter *self, int32_t field_num) {
     FieldType *const type     = Schema_Fetch_Type(schema, field);
 
     // Open outstreams.
-    CB_setf(self->dat_file,  "%o/lexicon-%i32.dat",  seg_name, field_num);
-    CB_setf(self->ix_file,   "%o/lexicon-%i32.ix",   seg_name, field_num);
-    CB_setf(self->ixix_file, "%o/lexicon-%i32.ixix", seg_name, field_num);
-    self->dat_out = Folder_Open_Out(folder, self->dat_file);
-    if (!self->dat_out) { RETHROW(INCREF(Err_get_error())); }
-    self->ix_out = Folder_Open_Out(folder, self->ix_file);
-    if (!self->ix_out) { RETHROW(INCREF(Err_get_error())); }
-    self->ixix_out = Folder_Open_Out(folder, self->ixix_file);
-    if (!self->ixix_out) { RETHROW(INCREF(Err_get_error())); }
+    CB_setf(ivars->dat_file,  "%o/lexicon-%i32.dat",  seg_name, field_num);
+    CB_setf(ivars->ix_file,   "%o/lexicon-%i32.ix",   seg_name, field_num);
+    CB_setf(ivars->ixix_file, "%o/lexicon-%i32.ixix", seg_name, field_num);
+    ivars->dat_out = Folder_Open_Out(folder, ivars->dat_file);
+    if (!ivars->dat_out) { RETHROW(INCREF(Err_get_error())); }
+    ivars->ix_out = Folder_Open_Out(folder, ivars->ix_file);
+    if (!ivars->ix_out) { RETHROW(INCREF(Err_get_error())); }
+    ivars->ixix_out = Folder_Open_Out(folder, ivars->ixix_file);
+    if (!ivars->ixix_out) { RETHROW(INCREF(Err_get_error())); }
 
     // Initialize count and ix_count, term stepper and term info stepper.
-    self->count    = 0;
-    self->ix_count = 0;
-    self->term_stepper = FType_Make_Term_Stepper(type);
-    TermStepper_Reset(self->tinfo_stepper);
+    ivars->count    = 0;
+    ivars->ix_count = 0;
+    ivars->term_stepper = FType_Make_Term_Stepper(type);
+    TermStepper_Reset(ivars->tinfo_stepper);
 }
 
 void
 LexWriter_finish_field(LexiconWriter *self, int32_t field_num) {
-    CharBuf *field = Seg_Field_Name(self->segment, field_num);
+    LexiconWriterIVARS *const ivars = LexWriter_IVARS(self);
+    CharBuf *field = Seg_Field_Name(ivars->segment, field_num);
 
     // Store count of terms for this field as metadata.
-    Hash_Store(self->counts, (Obj*)field,
-               (Obj*)CB_newf("%i32", self->count));
-    Hash_Store(self->ix_counts, (Obj*)field,
-               (Obj*)CB_newf("%i32", self->ix_count));
+    Hash_Store(ivars->counts, (Obj*)field,
+               (Obj*)CB_newf("%i32", ivars->count));
+    Hash_Store(ivars->ix_counts, (Obj*)field,
+               (Obj*)CB_newf("%i32", ivars->ix_count));
 
     // Close streams.
-    OutStream_Close(self->dat_out);
-    OutStream_Close(self->ix_out);
-    OutStream_Close(self->ixix_out);
-    DECREF(self->dat_out);
-    DECREF(self->ix_out);
-    DECREF(self->ixix_out);
-    self->dat_out  = NULL;
-    self->ix_out   = NULL;
-    self->ixix_out = NULL;
+    OutStream_Close(ivars->dat_out);
+    OutStream_Close(ivars->ix_out);
+    OutStream_Close(ivars->ixix_out);
+    DECREF(ivars->dat_out);
+    DECREF(ivars->ix_out);
+    DECREF(ivars->ixix_out);
+    ivars->dat_out  = NULL;
+    ivars->ix_out   = NULL;
+    ivars->ixix_out = NULL;
 
     // Close term stepper.
-    DECREF(self->term_stepper);
-    self->term_stepper = NULL;
+    DECREF(ivars->term_stepper);
+    ivars->term_stepper = NULL;
 }
 
 void
 LexWriter_enter_temp_mode(LexiconWriter *self, const CharBuf *field,
                           OutStream *temp_outstream) {
+    LexiconWriterIVARS *const ivars = LexWriter_IVARS(self);
     Schema    *schema = LexWriter_Get_Schema(self);
     FieldType *type   = Schema_Fetch_Type(schema, field);
 
     // Assign outstream.
-    if (self->dat_out != NULL) {
-        THROW(ERR, "Can't enter temp mode (filename: %o) ", self->dat_file);
+    if (ivars->dat_out != NULL) {
+        THROW(ERR, "Can't enter temp mode (filename: %o) ", ivars->dat_file);
     }
-    self->dat_out = (OutStream*)INCREF(temp_outstream);
+    ivars->dat_out = (OutStream*)INCREF(temp_outstream);
 
     // Initialize count and ix_count, term stepper and term info stepper.
-    self->count    = 0;
-    self->ix_count = 0;
-    self->term_stepper = FType_Make_Term_Stepper(type);
-    TermStepper_Reset(self->tinfo_stepper);
+    ivars->count    = 0;
+    ivars->ix_count = 0;
+    ivars->term_stepper = FType_Make_Term_Stepper(type);
+    TermStepper_Reset(ivars->tinfo_stepper);
 
     // Remember that we're in temp mode.
-    self->temp_mode = true;
+    ivars->temp_mode = true;
 }
 
 void
 LexWriter_leave_temp_mode(LexiconWriter *self) {
-    DECREF(self->term_stepper);
-    self->term_stepper = NULL;
-    DECREF(self->dat_out);
-    self->dat_out   = NULL;
-    self->temp_mode = false;
+    LexiconWriterIVARS *const ivars = LexWriter_IVARS(self);
+    DECREF(ivars->term_stepper);
+    ivars->term_stepper = NULL;
+    DECREF(ivars->dat_out);
+    ivars->dat_out   = NULL;
+    ivars->temp_mode = false;
 }
 
 void
 LexWriter_finish(LexiconWriter *self) {
+    LexiconWriterIVARS *const ivars = LexWriter_IVARS(self);
+
     // Ensure that streams were closed (by calling Finish_Field or
     // Leave_Temp_Mode).
-    if (self->dat_out != NULL) {
-        THROW(ERR, "File '%o' never closed", self->dat_file);
+    if (ivars->dat_out != NULL) {
+        THROW(ERR, "File '%o' never closed", ivars->dat_file);
     }
-    else if (self->ix_out != NULL) {
-        THROW(ERR, "File '%o' never closed", self->ix_file);
+    else if (ivars->ix_out != NULL) {
+        THROW(ERR, "File '%o' never closed", ivars->ix_file);
     }
-    else if (self->ix_out != NULL) {
-        THROW(ERR, "File '%o' never closed", self->ix_file);
+    else if (ivars->ix_out != NULL) {
+        THROW(ERR, "File '%o' never closed", ivars->ix_file);
     }
 
     // Store metadata.
-    Seg_Store_Metadata_Str(self->segment, "lexicon", 7,
+    Seg_Store_Metadata_Str(ivars->segment, "lexicon", 7,
                            (Obj*)LexWriter_Metadata(self));
 }
 
 Hash*
 LexWriter_metadata(LexiconWriter *self) {
+    LexiconWriterIVARS *const ivars = LexWriter_IVARS(self);
     Hash *const metadata  = DataWriter_metadata((DataWriter*)self);
-    Hash *const counts    = (Hash*)INCREF(self->counts);
-    Hash *const ix_counts = (Hash*)INCREF(self->ix_counts);
+    Hash *const counts    = (Hash*)INCREF(ivars->counts);
+    Hash *const ix_counts = (Hash*)INCREF(ivars->ix_counts);
 
     // Placeholders.
     if (Hash_Get_Size(counts) == 0) {

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/PolyLexicon.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/PolyLexicon.c b/core/Lucy/Index/PolyLexicon.c
index 52553a2..713fda2 100644
--- a/core/Lucy/Index/PolyLexicon.c
+++ b/core/Lucy/Index/PolyLexicon.c
@@ -41,8 +41,9 @@ PolyLex_init(PolyLexicon *self, const CharBuf *field, VArray *sub_readers) {
 
     // Init.
     Lex_init((Lexicon*)self, field);
-    self->term            = NULL;
-    self->lex_q           = SegLexQ_new(num_sub_readers);
+    PolyLexiconIVARS *const ivars = PolyLex_IVARS(self);
+    ivars->term            = NULL;
+    ivars->lex_q           = SegLexQ_new(num_sub_readers);
 
     // Derive.
     for (uint32_t i = 0; i < num_sub_readers; i++) {
@@ -54,7 +55,7 @@ PolyLex_init(PolyLexicon *self, const CharBuf *field, VArray *sub_readers) {
             }
         }
     }
-    self->seg_lexicons  = seg_lexicons;
+    ivars->seg_lexicons  = seg_lexicons;
 
     PolyLex_Reset(self);
 
@@ -63,9 +64,10 @@ PolyLex_init(PolyLexicon *self, const CharBuf *field, VArray *sub_readers) {
 
 void
 PolyLex_destroy(PolyLexicon *self) {
-    DECREF(self->seg_lexicons);
-    DECREF(self->lex_q);
-    DECREF(self->term);
+    PolyLexiconIVARS *const ivars = PolyLex_IVARS(self);
+    DECREF(ivars->seg_lexicons);
+    DECREF(ivars->lex_q);
+    DECREF(ivars->term);
     SUPER_DESTROY(self, POLYLEXICON);
 }
 
@@ -91,9 +93,10 @@ S_refresh_lex_q(SegLexQueue *lex_q, VArray *seg_lexicons, Obj *target) {
 
 void
 PolyLex_reset(PolyLexicon *self) {
-    VArray *seg_lexicons = self->seg_lexicons;
+    PolyLexiconIVARS *const ivars = PolyLex_IVARS(self);
+    VArray *seg_lexicons = ivars->seg_lexicons;
     uint32_t num_segs = VA_Get_Size(seg_lexicons);
-    SegLexQueue *lex_q = self->lex_q;
+    SegLexQueue *lex_q = ivars->lex_q;
 
     // Empty out the queue.
     while (1) {
@@ -108,30 +111,31 @@ PolyLex_reset(PolyLexicon *self) {
             = (SegLexicon*)VA_Fetch(seg_lexicons, i);
         SegLex_Reset(seg_lexicon);
         if (SegLex_Next(seg_lexicon)) {
-            SegLexQ_Insert(self->lex_q, INCREF(seg_lexicon));
+            SegLexQ_Insert(ivars->lex_q, INCREF(seg_lexicon));
         }
     }
 
-    if (self->term != NULL) {
-        DECREF(self->term);
-        self->term = NULL;
+    if (ivars->term != NULL) {
+        DECREF(ivars->term);
+        ivars->term = NULL;
     }
 }
 
 bool
 PolyLex_next(PolyLexicon *self) {
-    SegLexQueue *lex_q = self->lex_q;
+    PolyLexiconIVARS *const ivars = PolyLex_IVARS(self);
+    SegLexQueue *lex_q = ivars->lex_q;
     SegLexicon *top_seg_lexicon = (SegLexicon*)SegLexQ_Peek(lex_q);
 
     // Churn through queue items with equal terms.
     while (top_seg_lexicon != NULL) {
         Obj *const candidate = SegLex_Get_Term(top_seg_lexicon);
-        if ((candidate && !self->term)
-            || Obj_Compare_To(self->term, candidate) != 0
+        if ((candidate && !ivars->term)
+            || Obj_Compare_To(ivars->term, candidate) != 0
            ) {
             // Succeed if the next item in the queue has a different term.
-            DECREF(self->term);
-            self->term = Obj_Clone(candidate);
+            DECREF(ivars->term);
+            ivars->term = Obj_Clone(candidate);
             return true;
         }
         else {
@@ -145,15 +149,16 @@ PolyLex_next(PolyLexicon *self) {
     }
 
     // If queue is empty, iterator is finished.
-    DECREF(self->term);
-    self->term = NULL;
+    DECREF(ivars->term);
+    ivars->term = NULL;
     return false;
 }
 
 void
 PolyLex_seek(PolyLexicon *self, Obj *target) {
-    VArray *seg_lexicons = self->seg_lexicons;
-    SegLexQueue *lex_q = self->lex_q;
+    PolyLexiconIVARS *const ivars = PolyLex_IVARS(self);
+    VArray *seg_lexicons = ivars->seg_lexicons;
+    SegLexQueue *lex_q = ivars->lex_q;
 
     if (target == NULL) {
         PolyLex_Reset(self);
@@ -163,17 +168,17 @@ PolyLex_seek(PolyLexicon *self, Obj *target) {
     // Refresh the queue, set vars.
     S_refresh_lex_q(lex_q, seg_lexicons, target);
     SegLexicon *least = (SegLexicon*)SegLexQ_Peek(lex_q);
-    DECREF(self->term);
-    self->term = NULL;
+    DECREF(ivars->term);
+    ivars->term = NULL;
     if (least) {
         Obj *least_term = SegLex_Get_Term(least);
-        self->term = least_term ? Obj_Clone(least_term) : NULL;
+        ivars->term = least_term ? Obj_Clone(least_term) : NULL;
     }
 
     // Scan up to the real target.
     do {
-        if (self->term) {
-            const int32_t comparison = Obj_Compare_To(self->term, target);
+        if (ivars->term) {
+            const int32_t comparison = Obj_Compare_To(ivars->term, target);
             if (comparison >= 0) { break; }
         }
     } while (PolyLex_Next(self));
@@ -181,12 +186,13 @@ PolyLex_seek(PolyLexicon *self, Obj *target) {
 
 Obj*
 PolyLex_get_term(PolyLexicon *self) {
-    return self->term;
+    return PolyLex_IVARS(self)->term;
 }
 
 uint32_t
 PolyLex_get_num_seg_lexicons(PolyLexicon *self) {
-    return VA_Get_Size(self->seg_lexicons);
+    PolyLexiconIVARS *const ivars = PolyLex_IVARS(self);
+    return VA_Get_Size(ivars->seg_lexicons);
 }
 
 SegLexQueue*

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/PolyReader.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/PolyReader.c b/core/Lucy/Index/PolyReader.c
index ba64e16..92f198b 100644
--- a/core/Lucy/Index/PolyReader.c
+++ b/core/Lucy/Index/PolyReader.c
@@ -100,23 +100,24 @@ S_first_non_null(VArray *array) {
 
 static void
 S_init_sub_readers(PolyReader *self, VArray *sub_readers) {
+    PolyReaderIVARS *const ivars = PolyReader_IVARS(self);
     uint32_t  num_sub_readers = VA_Get_Size(sub_readers);
     int32_t *starts = (int32_t*)MALLOCATE(num_sub_readers * sizeof(int32_t));
     Hash  *data_readers = Hash_new(0);
 
-    DECREF(self->sub_readers);
-    DECREF(self->offsets);
-    self->sub_readers       = (VArray*)INCREF(sub_readers);
+    DECREF(ivars->sub_readers);
+    DECREF(ivars->offsets);
+    ivars->sub_readers       = (VArray*)INCREF(sub_readers);
 
     // Accumulate doc_max, subreader start offsets, and DataReaders.
-    self->doc_max = 0;
+    ivars->doc_max = 0;
     for (uint32_t i = 0; i < num_sub_readers; i++) {
         SegReader *seg_reader = (SegReader*)VA_Fetch(sub_readers, i);
         Hash *components = SegReader_Get_Components(seg_reader);
         CharBuf *api;
         DataReader *component;
-        starts[i] = self->doc_max;
-        self->doc_max += SegReader_Doc_Max(seg_reader);
+        starts[i] = ivars->doc_max;
+        ivars->doc_max += SegReader_Doc_Max(seg_reader);
         Hash_Iterate(components);
         while (Hash_Next(components, (Obj**)&api, (Obj**)&component)) {
             VArray *readers = (VArray*)Hash_Fetch(data_readers, (Obj*)api);
@@ -127,7 +128,7 @@ S_init_sub_readers(PolyReader *self, VArray *sub_readers) {
             VA_Store(readers, i, INCREF(component));
         }
     }
-    self->offsets = I32Arr_new_steal(starts, num_sub_readers);
+    ivars->offsets = I32Arr_new_steal(starts, num_sub_readers);
 
     CharBuf *api;
     VArray  *readers;
@@ -136,26 +137,27 @@ S_init_sub_readers(PolyReader *self, VArray *sub_readers) {
         DataReader *datareader
             = (DataReader*)CERTIFY(S_first_non_null(readers), DATAREADER);
         DataReader *aggregator
-            = DataReader_Aggregator(datareader, readers, self->offsets);
+            = DataReader_Aggregator(datareader, readers, ivars->offsets);
         if (aggregator) {
             CERTIFY(aggregator, DATAREADER);
-            Hash_Store(self->components, (Obj*)api, (Obj*)aggregator);
+            Hash_Store(ivars->components, (Obj*)api, (Obj*)aggregator);
         }
     }
     DECREF(data_readers);
 
     DeletionsReader *del_reader
         = (DeletionsReader*)Hash_Fetch(
-              self->components, (Obj*)VTable_Get_Name(DELETIONSREADER));
-    self->del_count = del_reader ? DelReader_Del_Count(del_reader) : 0;
+              ivars->components, (Obj*)VTable_Get_Name(DELETIONSREADER));
+    ivars->del_count = del_reader ? DelReader_Del_Count(del_reader) : 0;
 }
 
 PolyReader*
 PolyReader_init(PolyReader *self, Schema *schema, Folder *folder,
                 Snapshot *snapshot, IndexManager *manager,
                 VArray *sub_readers) {
-    self->doc_max    = 0;
-    self->del_count  = 0;
+    PolyReaderIVARS *const ivars = PolyReader_IVARS(self);
+    ivars->doc_max    = 0;
+    ivars->del_count  = 0;
 
     if (sub_readers) {
         uint32_t num_segs = VA_Get_Size(sub_readers);
@@ -173,8 +175,8 @@ PolyReader_init(PolyReader *self, Schema *schema, Folder *folder,
     else {
         IxReader_init((IndexReader*)self, schema, folder, snapshot,
                       NULL, -1, manager);
-        self->sub_readers = VA_new(0);
-        self->offsets = I32Arr_new_steal(NULL, 0);
+        ivars->sub_readers = VA_new(0);
+        ivars->offsets = I32Arr_new_steal(NULL, 0);
     }
 
     return self;
@@ -182,10 +184,11 @@ PolyReader_init(PolyReader *self, Schema *schema, Folder *folder,
 
 void
 PolyReader_close(PolyReader *self) {
+    PolyReaderIVARS *const ivars = PolyReader_IVARS(self);
     PolyReader_Close_t super_close
         = SUPER_METHOD_PTR(POLYREADER, Lucy_PolyReader_Close);
-    for (uint32_t i = 0, max = VA_Get_Size(self->sub_readers); i < max; i++) {
-        SegReader *seg_reader = (SegReader*)VA_Fetch(self->sub_readers, i);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->sub_readers); i < max; i++) {
+        SegReader *seg_reader = (SegReader*)VA_Fetch(ivars->sub_readers, i);
         SegReader_Close(seg_reader);
     }
     super_close(self);
@@ -193,8 +196,9 @@ PolyReader_close(PolyReader *self) {
 
 void
 PolyReader_destroy(PolyReader *self) {
-    DECREF(self->sub_readers);
-    DECREF(self->offsets);
+    PolyReaderIVARS *const ivars = PolyReader_IVARS(self);
+    DECREF(ivars->sub_readers);
+    DECREF(ivars->offsets);
     SUPER_DESTROY(self, POLYREADER);
 }
 
@@ -218,7 +222,8 @@ S_try_open_elements(void *context) {
     struct try_open_elements_context *args
         = (struct try_open_elements_context*)context;
     PolyReader *self              = args->self;
-    VArray     *files             = Snapshot_List(self->snapshot);
+    PolyReaderIVARS *const ivars  = PolyReader_IVARS(self);
+    VArray     *files             = Snapshot_List(ivars->snapshot);
     Folder     *folder            = PolyReader_Get_Folder(self);
     uint32_t    num_segs          = 0;
     uint64_t    latest_schema_gen = 0;
@@ -251,8 +256,8 @@ S_try_open_elements(void *context) {
     else {
         Hash *dump = (Hash*)Json_slurp_json(folder, schema_file);
         if (dump) { // read file successfully
-            DECREF(self->schema);
-            self->schema = (Schema*)CERTIFY(
+            DECREF(ivars->schema);
+            ivars->schema = (Schema*)CERTIFY(
                                VTable_Load_Obj(SCHEMA, (Obj*)dump), SCHEMA);
             DECREF(dump);
             DECREF(schema_file);
@@ -329,6 +334,7 @@ int32_t  PolyReader_debug1_num_passes     = 0;
 PolyReader*
 PolyReader_do_open(PolyReader *self, Obj *index, Snapshot *snapshot,
                    IndexManager *manager) {
+    PolyReaderIVARS *const ivars = PolyReader_IVARS(self);
     Folder   *folder   = S_derive_folder(index);
     uint64_t  last_gen = 0;
 
@@ -391,7 +397,7 @@ PolyReader_do_open(PolyReader *self, Obj *index, Snapshot *snapshot,
         // If that's not the case, we must read the file we just picked.
         if (!snapshot) {
             struct try_read_snapshot_context context;
-            context.snapshot = self->snapshot;
+            context.snapshot = ivars->snapshot;
             context.folder   = folder;
             context.path     = target_snap_file;
             Err *error = Err_trap(S_try_read_snapshot, &context);
@@ -463,11 +469,12 @@ S_derive_folder(Obj *index) {
 
 static bool 
 S_obtain_deletion_lock(PolyReader *self) {
-    self->deletion_lock = IxManager_Make_Deletion_Lock(self->manager);
-    Lock_Clear_Stale(self->deletion_lock);
-    if (!Lock_Obtain(self->deletion_lock)) {
-        DECREF(self->deletion_lock);
-        self->deletion_lock = NULL;
+    PolyReaderIVARS *const ivars = PolyReader_IVARS(self);
+    ivars->deletion_lock = IxManager_Make_Deletion_Lock(ivars->manager);
+    Lock_Clear_Stale(ivars->deletion_lock);
+    if (!Lock_Obtain(ivars->deletion_lock)) {
+        DECREF(ivars->deletion_lock);
+        ivars->deletion_lock = NULL;
         return false;
     }
     return true;
@@ -475,13 +482,14 @@ S_obtain_deletion_lock(PolyReader *self) {
 
 static bool
 S_obtain_read_lock(PolyReader *self, const CharBuf *snapshot_file_name) {
-    self->read_lock = IxManager_Make_Snapshot_Read_Lock(self->manager,
-                                                        snapshot_file_name);
-
-    Lock_Clear_Stale(self->read_lock);
-    if (!Lock_Obtain(self->read_lock)) {
-        DECREF(self->read_lock);
-        self->read_lock = NULL;
+    PolyReaderIVARS *const ivars = PolyReader_IVARS(self);
+    ivars->read_lock = IxManager_Make_Snapshot_Read_Lock(ivars->manager,
+                                                         snapshot_file_name);
+
+    Lock_Clear_Stale(ivars->read_lock);
+    if (!Lock_Obtain(ivars->read_lock)) {
+        DECREF(ivars->read_lock);
+        ivars->read_lock = NULL;
         return false;
     }
     return true;
@@ -489,50 +497,55 @@ S_obtain_read_lock(PolyReader *self, const CharBuf *snapshot_file_name) {
 
 static void
 S_release_read_lock(PolyReader *self) {
-    if (self->read_lock) {
-        Lock_Release(self->read_lock);
-        DECREF(self->read_lock);
-        self->read_lock = NULL;
+    PolyReaderIVARS *const ivars = PolyReader_IVARS(self);
+    if (ivars->read_lock) {
+        Lock_Release(ivars->read_lock);
+        DECREF(ivars->read_lock);
+        ivars->read_lock = NULL;
     }
 }
 
 static void
 S_release_deletion_lock(PolyReader *self) {
-    if (self->deletion_lock) {
-        Lock_Release(self->deletion_lock);
-        DECREF(self->deletion_lock);
-        self->deletion_lock = NULL;
+    PolyReaderIVARS *const ivars = PolyReader_IVARS(self);
+    if (ivars->deletion_lock) {
+        Lock_Release(ivars->deletion_lock);
+        DECREF(ivars->deletion_lock);
+        ivars->deletion_lock = NULL;
     }
 }
 
 int32_t
 PolyReader_doc_max(PolyReader *self) {
-    return self->doc_max;
+    return PolyReader_IVARS(self)->doc_max;
 }
 
 int32_t
 PolyReader_doc_count(PolyReader *self) {
-    return self->doc_max - self->del_count;
+    PolyReaderIVARS *const ivars = PolyReader_IVARS(self);
+    return ivars->doc_max - ivars->del_count;
 }
 
 int32_t
 PolyReader_del_count(PolyReader *self) {
-    return self->del_count;
+    return PolyReader_IVARS(self)->del_count;
 }
 
 I32Array*
 PolyReader_offsets(PolyReader *self) {
-    return (I32Array*)INCREF(self->offsets);
+    PolyReaderIVARS *const ivars = PolyReader_IVARS(self);
+    return (I32Array*)INCREF(ivars->offsets);
 }
 
 VArray*
 PolyReader_seg_readers(PolyReader *self) {
-    return (VArray*)VA_Shallow_Copy(self->sub_readers);
+    PolyReaderIVARS *const ivars = PolyReader_IVARS(self);
+    return (VArray*)VA_Shallow_Copy(ivars->sub_readers);
 }
 
 VArray*
 PolyReader_get_seg_readers(PolyReader *self) {
-    return self->sub_readers;
+    return PolyReader_IVARS(self)->sub_readers;
 }
 
 uint32_t

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/Posting.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/Posting.c b/core/Lucy/Index/Posting.c
index 36cb1e9..98ca0f8 100644
--- a/core/Lucy/Index/Posting.c
+++ b/core/Lucy/Index/Posting.c
@@ -30,18 +30,19 @@
 
 Posting*
 Post_init(Posting *self) {
-    self->doc_id = 0;
+    PostingIVARS *const ivars = Post_IVARS(self);
+    ivars->doc_id = 0;
     return self;
 }
 
 void
 Post_set_doc_id(Posting *self, int32_t doc_id) {
-    self->doc_id = doc_id;
+    Post_IVARS(self)->doc_id = doc_id;
 }
 
 int32_t
 Post_get_doc_id(Posting *self) {
-    return self->doc_id;
+    return Post_IVARS(self)->doc_id;
 }
 
 PostingWriter*
@@ -49,7 +50,8 @@ PostWriter_init(PostingWriter *self, Schema *schema, Snapshot *snapshot,
                 Segment *segment, PolyReader *polyreader, int32_t field_num) {
     DataWriter_init((DataWriter*)self, schema, snapshot, segment,
                     polyreader);
-    self->field_num = field_num;
+    PostingWriterIVARS *const ivars = PostWriter_IVARS(self);
+    ivars->field_num = field_num;
     return self;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/PostingListReader.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/PostingListReader.c b/core/Lucy/Index/PostingListReader.c
index c2d3a49..5cb018e 100644
--- a/core/Lucy/Index/PostingListReader.c
+++ b/core/Lucy/Index/PostingListReader.c
@@ -64,10 +64,11 @@ DefPListReader_init(DefaultPostingListReader *self, Schema *schema,
                     int32_t seg_tick, LexiconReader *lex_reader) {
     PListReader_init((PostingListReader*)self, schema, folder, snapshot,
                      segments, seg_tick);
+    DefaultPostingListReaderIVARS *const ivars = DefPListReader_IVARS(self);
     Segment *segment = DefPListReader_Get_Segment(self);
 
     // Derive.
-    self->lex_reader = (LexiconReader*)INCREF(lex_reader);
+    ivars->lex_reader = (LexiconReader*)INCREF(lex_reader);
 
     // Check format.
     Hash *my_meta = (Hash*)Seg_Fetch_Metadata_Str(segment, "postings", 8);
@@ -91,23 +92,26 @@ DefPListReader_init(DefaultPostingListReader *self, Schema *schema,
 
 void
 DefPListReader_close(DefaultPostingListReader *self) {
-    if (self->lex_reader) {
-        LexReader_Close(self->lex_reader);
-        DECREF(self->lex_reader);
-        self->lex_reader = NULL;
+    DefaultPostingListReaderIVARS *const ivars = DefPListReader_IVARS(self);
+    if (ivars->lex_reader) {
+        LexReader_Close(ivars->lex_reader);
+        DECREF(ivars->lex_reader);
+        ivars->lex_reader = NULL;
     }
 }
 
 void
 DefPListReader_destroy(DefaultPostingListReader *self) {
-    DECREF(self->lex_reader);
+    DefaultPostingListReaderIVARS *const ivars = DefPListReader_IVARS(self);
+    DECREF(ivars->lex_reader);
     SUPER_DESTROY(self, DEFAULTPOSTINGLISTREADER);
 }
 
 SegPostingList*
 DefPListReader_posting_list(DefaultPostingListReader *self,
                             const CharBuf *field, Obj *target) {
-    FieldType *type = Schema_Fetch_Type(self->schema, field);
+    DefaultPostingListReaderIVARS *const ivars = DefPListReader_IVARS(self);
+    FieldType *type = Schema_Fetch_Type(ivars->schema, field);
 
     // Only return an object if we've got an indexed field.
     if (type != NULL && FType_Indexed(type)) {
@@ -122,6 +126,6 @@ DefPListReader_posting_list(DefaultPostingListReader *self,
 
 LexiconReader*
 DefPListReader_get_lex_reader(DefaultPostingListReader *self) {
-    return self->lex_reader;
+    return DefPListReader_IVARS(self)->lex_reader;
 }
 


[lucy-commits] [33/34] git commit: refs/heads/master - Move BBSortEx out of TestLucy back under Lucy.

Posted by ma...@apache.org.
Move BBSortEx out of TestLucy back under Lucy.

BBSortEx is a test-only class, but it uses member vars defined in
SortEx.  That's a problem once we cut off access to member vars defined
in another parcel, so move it back under Lucy for the time being.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/abf9363a
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/abf9363a
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/abf9363a

Branch: refs/heads/master
Commit: abf9363aa9d340716e559f94342d6316e85c3e4e
Parents: 0fc7b13
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Fri Jul 12 19:14:18 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 16:08:44 2013 -0700

----------------------------------------------------------------------
 core/Lucy/Test/Util/BBSortEx.c           | 176 --------------------------
 core/Lucy/Test/Util/BBSortEx.cfh         |  58 ---------
 core/Lucy/Util/BBSortEx.c                | 176 ++++++++++++++++++++++++++
 core/Lucy/Util/BBSortEx.cfh              |  58 +++++++++
 perl/buildlib/Lucy/Build/Binding/Misc.pm |  60 ---------
 perl/buildlib/Lucy/Build/Binding/Util.pm |  60 +++++++++
 perl/lib/Lucy/Test/Util/BBSortEx.pm      |  25 ----
 perl/lib/Lucy/Util/BBSortEx.pm           |  25 ++++
 perl/t/015-sort_external.t               |  22 ++--
 perl/t/028-sortexrun.t                   |   2 +-
 10 files changed, 331 insertions(+), 331 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/abf9363a/core/Lucy/Test/Util/BBSortEx.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Test/Util/BBSortEx.c b/core/Lucy/Test/Util/BBSortEx.c
deleted file mode 100644
index 0e17b42..0000000
--- a/core/Lucy/Test/Util/BBSortEx.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define C_TESTLUCY_BBSORTEX
-#define TESTLUCY_USE_SHORT_NAMES
-#include "Lucy/Util/ToolSet.h"
-
-#include "Lucy/Test/Util/BBSortEx.h"
-
-#include "Lucy/Index/Segment.h"
-#include "Lucy/Store/InStream.h"
-#include "Lucy/Store/Folder.h"
-#include "Lucy/Store/OutStream.h"
-
-BBSortEx*
-BBSortEx_new(uint32_t mem_threshold, VArray *external) {
-    BBSortEx *self = (BBSortEx*)VTable_Make_Obj(BBSORTEX);
-    return BBSortEx_init(self, mem_threshold, external);
-}
-
-BBSortEx*
-BBSortEx_init(BBSortEx *self, uint32_t mem_threshold, VArray *external) {
-    SortEx_init((SortExternal*)self, sizeof(Obj*));
-    BBSortExIVARS *const ivars = BBSortEx_IVARS(self);
-    ivars->external_tick = 0;
-    ivars->external = (VArray*)INCREF(external);
-    ivars->mem_consumed = 0;
-    BBSortEx_Set_Mem_Thresh(self, mem_threshold);
-    return self;
-}
-
-void
-BBSortEx_destroy(BBSortEx *self) {
-    BBSortExIVARS *const ivars = BBSortEx_IVARS(self);
-    DECREF(ivars->external);
-    SUPER_DESTROY(self, BBSORTEX);
-}
-
-void
-BBSortEx_clear_cache(BBSortEx *self) {
-    BBSortExIVARS *const ivars = BBSortEx_IVARS(self);
-    Obj **const cache = (Obj**)ivars->cache;
-    for (uint32_t i = ivars->cache_tick, max = ivars->cache_max; i < max; i++) {
-        DECREF(cache[i]);
-    }
-    ivars->mem_consumed = 0;
-    BBSortEx_Clear_Cache_t super_clear_cache
-        = SUPER_METHOD_PTR(BBSORTEX, TestLucy_BBSortEx_Clear_Cache);
-    super_clear_cache(self);
-}
-
-void
-BBSortEx_feed(BBSortEx *self, void *data) {
-    BBSortExIVARS *const ivars = BBSortEx_IVARS(self);
-    BBSortEx_Feed_t super_feed
-        = SUPER_METHOD_PTR(BBSORTEX, TestLucy_BBSortEx_Feed);
-    super_feed(self, data);
-
-    // Flush() if necessary.
-    ByteBuf *bytebuf = (ByteBuf*)CERTIFY(*(ByteBuf**)data, BYTEBUF);
-    ivars->mem_consumed += BB_Get_Size(bytebuf);
-    if (ivars->mem_consumed >= ivars->mem_thresh) {
-        BBSortEx_Flush(self);
-    }
-}
-
-void
-BBSortEx_flush(BBSortEx *self) {
-    BBSortExIVARS *const ivars = BBSortEx_IVARS(self);
-    uint32_t     cache_count = ivars->cache_max - ivars->cache_tick;
-    Obj        **cache = (Obj**)ivars->cache;
-    VArray      *elems;
-
-    if (!cache_count) { return; }
-    else              { elems = VA_new(cache_count); }
-
-    // Sort, then create a new run.
-    BBSortEx_Sort_Cache(self);
-    for (uint32_t i = ivars->cache_tick; i < ivars->cache_max; i++) {
-        VA_Push(elems, cache[i]);
-    }
-    BBSortEx *run = BBSortEx_new(0, elems);
-    DECREF(elems);
-    BBSortEx_Add_Run(self, (SortExternal*)run);
-
-    // Blank the cache vars.
-    ivars->cache_tick += cache_count;
-    BBSortEx_Clear_Cache(self);
-}
-
-uint32_t
-BBSortEx_refill(BBSortEx *self) {
-    BBSortExIVARS *const ivars = BBSortEx_IVARS(self);
-
-    // Make sure cache is empty, then set cache tick vars.
-    if (ivars->cache_max - ivars->cache_tick > 0) {
-        THROW(ERR, "Refill called but cache contains %u32 items",
-              ivars->cache_max - ivars->cache_tick);
-    }
-    ivars->cache_tick = 0;
-    ivars->cache_max  = 0;
-
-    // Read in elements.
-    while (1) {
-        ByteBuf *elem = NULL;
-
-        if (ivars->mem_consumed >= ivars->mem_thresh) {
-            ivars->mem_consumed = 0;
-            break;
-        }
-        else if (ivars->external_tick >= VA_Get_Size(ivars->external)) {
-            break;
-        }
-        else {
-            elem = (ByteBuf*)VA_Fetch(ivars->external, ivars->external_tick);
-            ivars->external_tick++;
-            // Should be + sizeof(ByteBuf), but that's ok.
-            ivars->mem_consumed += BB_Get_Size(elem);
-        }
-
-        if (ivars->cache_max == ivars->cache_cap) {
-            BBSortEx_Grow_Cache(self,
-                                Memory_oversize(ivars->cache_max + 1, ivars->width));
-        }
-        Obj **cache = (Obj**)ivars->cache;
-        cache[ivars->cache_max++] = INCREF(elem);
-    }
-
-    return ivars->cache_max;
-}
-
-void
-BBSortEx_flip(BBSortEx *self) {
-    BBSortExIVARS *const ivars = BBSortEx_IVARS(self);
-    uint32_t run_mem_thresh = 65536;
-
-    BBSortEx_Flush(self);
-
-    // Recalculate the approximate mem allowed for each run.
-    uint32_t num_runs = VA_Get_Size(ivars->runs);
-    if (num_runs) {
-        run_mem_thresh = (ivars->mem_thresh / 2) / num_runs;
-        if (run_mem_thresh < 65536) {
-            run_mem_thresh = 65536;
-        }
-    }
-
-    for (uint32_t i = 0; i < num_runs; i++) {
-        BBSortEx *run = (BBSortEx*)VA_Fetch(ivars->runs, i);
-        BBSortEx_Set_Mem_Thresh(run, run_mem_thresh);
-    }
-
-    // OK to fetch now.
-    ivars->flipped = true;
-}
-
-int
-BBSortEx_compare(BBSortEx *self, void *va, void *vb) {
-    UNUSED_VAR(self);
-    return BB_compare((ByteBuf**)va, (ByteBuf**)vb);
-}
-
-

http://git-wip-us.apache.org/repos/asf/lucy/blob/abf9363a/core/Lucy/Test/Util/BBSortEx.cfh
----------------------------------------------------------------------
diff --git a/core/Lucy/Test/Util/BBSortEx.cfh b/core/Lucy/Test/Util/BBSortEx.cfh
deleted file mode 100644
index 1978085..0000000
--- a/core/Lucy/Test/Util/BBSortEx.cfh
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-parcel TestLucy;
-
-/** SortExternal for ByteBufs.
- */
-
-class Lucy::Test::Util::BBSortEx
-    inherits Lucy::Util::SortExternal {
-
-    VArray   *external;
-    uint32_t  external_tick;
-    uint32_t  mem_consumed;
-
-    inert BBSortEx*
-    new(uint32_t mem_thresh = 0x1000000, VArray *external = NULL);
-
-    inert BBSortEx*
-    init(BBSortEx *self, uint32_t mem_thresh = 0x1000000,
-        VArray *external = NULL);
-
-    void
-    Feed(BBSortEx *self, void *data);
-
-    void
-    Flush(BBSortEx *self);
-
-    uint32_t
-    Refill(BBSortEx *self);
-
-    void
-    Clear_Cache(BBSortEx *self);
-
-    void
-    Flip(BBSortEx *self);
-
-    int
-    Compare(BBSortEx *self, void *va, void *vb);
-
-    public void
-    Destroy(BBSortEx *self);
-}
-
-

http://git-wip-us.apache.org/repos/asf/lucy/blob/abf9363a/core/Lucy/Util/BBSortEx.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Util/BBSortEx.c b/core/Lucy/Util/BBSortEx.c
new file mode 100644
index 0000000..d42ca55
--- /dev/null
+++ b/core/Lucy/Util/BBSortEx.c
@@ -0,0 +1,176 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define C_LUCY_BBSORTEX
+#define LUCY_USE_SHORT_NAMES
+#include "Lucy/Util/ToolSet.h"
+
+#include "Lucy/Util/BBSortEx.h"
+
+#include "Lucy/Index/Segment.h"
+#include "Lucy/Store/InStream.h"
+#include "Lucy/Store/Folder.h"
+#include "Lucy/Store/OutStream.h"
+
+BBSortEx*
+BBSortEx_new(uint32_t mem_threshold, VArray *external) {
+    BBSortEx *self = (BBSortEx*)VTable_Make_Obj(BBSORTEX);
+    return BBSortEx_init(self, mem_threshold, external);
+}
+
+BBSortEx*
+BBSortEx_init(BBSortEx *self, uint32_t mem_threshold, VArray *external) {
+    SortEx_init((SortExternal*)self, sizeof(Obj*));
+    BBSortExIVARS *const ivars = BBSortEx_IVARS(self);
+    ivars->external_tick = 0;
+    ivars->external = (VArray*)INCREF(external);
+    ivars->mem_consumed = 0;
+    BBSortEx_Set_Mem_Thresh(self, mem_threshold);
+    return self;
+}
+
+void
+BBSortEx_destroy(BBSortEx *self) {
+    BBSortExIVARS *const ivars = BBSortEx_IVARS(self);
+    DECREF(ivars->external);
+    SUPER_DESTROY(self, BBSORTEX);
+}
+
+void
+BBSortEx_clear_cache(BBSortEx *self) {
+    BBSortExIVARS *const ivars = BBSortEx_IVARS(self);
+    Obj **const cache = (Obj**)ivars->cache;
+    for (uint32_t i = ivars->cache_tick, max = ivars->cache_max; i < max; i++) {
+        DECREF(cache[i]);
+    }
+    ivars->mem_consumed = 0;
+    BBSortEx_Clear_Cache_t super_clear_cache
+        = SUPER_METHOD_PTR(BBSORTEX, Lucy_BBSortEx_Clear_Cache);
+    super_clear_cache(self);
+}
+
+void
+BBSortEx_feed(BBSortEx *self, void *data) {
+    BBSortExIVARS *const ivars = BBSortEx_IVARS(self);
+    BBSortEx_Feed_t super_feed
+        = SUPER_METHOD_PTR(BBSORTEX, Lucy_BBSortEx_Feed);
+    super_feed(self, data);
+
+    // Flush() if necessary.
+    ByteBuf *bytebuf = (ByteBuf*)CERTIFY(*(ByteBuf**)data, BYTEBUF);
+    ivars->mem_consumed += BB_Get_Size(bytebuf);
+    if (ivars->mem_consumed >= ivars->mem_thresh) {
+        BBSortEx_Flush(self);
+    }
+}
+
+void
+BBSortEx_flush(BBSortEx *self) {
+    BBSortExIVARS *const ivars = BBSortEx_IVARS(self);
+    uint32_t     cache_count = ivars->cache_max - ivars->cache_tick;
+    Obj        **cache = (Obj**)ivars->cache;
+    VArray      *elems;
+
+    if (!cache_count) { return; }
+    else              { elems = VA_new(cache_count); }
+
+    // Sort, then create a new run.
+    BBSortEx_Sort_Cache(self);
+    for (uint32_t i = ivars->cache_tick; i < ivars->cache_max; i++) {
+        VA_Push(elems, cache[i]);
+    }
+    BBSortEx *run = BBSortEx_new(0, elems);
+    DECREF(elems);
+    BBSortEx_Add_Run(self, (SortExternal*)run);
+
+    // Blank the cache vars.
+    ivars->cache_tick += cache_count;
+    BBSortEx_Clear_Cache(self);
+}
+
+uint32_t
+BBSortEx_refill(BBSortEx *self) {
+    BBSortExIVARS *const ivars = BBSortEx_IVARS(self);
+
+    // Make sure cache is empty, then set cache tick vars.
+    if (ivars->cache_max - ivars->cache_tick > 0) {
+        THROW(ERR, "Refill called but cache contains %u32 items",
+              ivars->cache_max - ivars->cache_tick);
+    }
+    ivars->cache_tick = 0;
+    ivars->cache_max  = 0;
+
+    // Read in elements.
+    while (1) {
+        ByteBuf *elem = NULL;
+
+        if (ivars->mem_consumed >= ivars->mem_thresh) {
+            ivars->mem_consumed = 0;
+            break;
+        }
+        else if (ivars->external_tick >= VA_Get_Size(ivars->external)) {
+            break;
+        }
+        else {
+            elem = (ByteBuf*)VA_Fetch(ivars->external, ivars->external_tick);
+            ivars->external_tick++;
+            // Should be + sizeof(ByteBuf), but that's ok.
+            ivars->mem_consumed += BB_Get_Size(elem);
+        }
+
+        if (ivars->cache_max == ivars->cache_cap) {
+            BBSortEx_Grow_Cache(self,
+                                Memory_oversize(ivars->cache_max + 1, ivars->width));
+        }
+        Obj **cache = (Obj**)ivars->cache;
+        cache[ivars->cache_max++] = INCREF(elem);
+    }
+
+    return ivars->cache_max;
+}
+
+void
+BBSortEx_flip(BBSortEx *self) {
+    BBSortExIVARS *const ivars = BBSortEx_IVARS(self);
+    uint32_t run_mem_thresh = 65536;
+
+    BBSortEx_Flush(self);
+
+    // Recalculate the approximate mem allowed for each run.
+    uint32_t num_runs = VA_Get_Size(ivars->runs);
+    if (num_runs) {
+        run_mem_thresh = (ivars->mem_thresh / 2) / num_runs;
+        if (run_mem_thresh < 65536) {
+            run_mem_thresh = 65536;
+        }
+    }
+
+    for (uint32_t i = 0; i < num_runs; i++) {
+        BBSortEx *run = (BBSortEx*)VA_Fetch(ivars->runs, i);
+        BBSortEx_Set_Mem_Thresh(run, run_mem_thresh);
+    }
+
+    // OK to fetch now.
+    ivars->flipped = true;
+}
+
+int
+BBSortEx_compare(BBSortEx *self, void *va, void *vb) {
+    UNUSED_VAR(self);
+    return BB_compare((ByteBuf**)va, (ByteBuf**)vb);
+}
+
+

http://git-wip-us.apache.org/repos/asf/lucy/blob/abf9363a/core/Lucy/Util/BBSortEx.cfh
----------------------------------------------------------------------
diff --git a/core/Lucy/Util/BBSortEx.cfh b/core/Lucy/Util/BBSortEx.cfh
new file mode 100644
index 0000000..41f72ea
--- /dev/null
+++ b/core/Lucy/Util/BBSortEx.cfh
@@ -0,0 +1,58 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+parcel Lucy;
+
+/** SortExternal for ByteBufs.
+ */
+
+class Lucy::Util::BBSortEx
+    inherits Lucy::Util::SortExternal {
+
+    VArray   *external;
+    uint32_t  external_tick;
+    uint32_t  mem_consumed;
+
+    inert BBSortEx*
+    new(uint32_t mem_thresh = 0x1000000, VArray *external = NULL);
+
+    inert BBSortEx*
+    init(BBSortEx *self, uint32_t mem_thresh = 0x1000000,
+        VArray *external = NULL);
+
+    void
+    Feed(BBSortEx *self, void *data);
+
+    void
+    Flush(BBSortEx *self);
+
+    uint32_t
+    Refill(BBSortEx *self);
+
+    void
+    Clear_Cache(BBSortEx *self);
+
+    void
+    Flip(BBSortEx *self);
+
+    int
+    Compare(BBSortEx *self, void *va, void *vb);
+
+    public void
+    Destroy(BBSortEx *self);
+}
+
+

http://git-wip-us.apache.org/repos/asf/lucy/blob/abf9363a/perl/buildlib/Lucy/Build/Binding/Misc.pm
----------------------------------------------------------------------
diff --git a/perl/buildlib/Lucy/Build/Binding/Misc.pm b/perl/buildlib/Lucy/Build/Binding/Misc.pm
index 3a779c0..19036d9 100644
--- a/perl/buildlib/Lucy/Build/Binding/Misc.pm
+++ b/perl/buildlib/Lucy/Build/Binding/Misc.pm
@@ -25,7 +25,6 @@ sub bind_all {
     $class->bind_lucy;
     $class->bind_test;
     $class->bind_testschema;
-    $class->bind_bbsortex;
 }
 
 sub inherit_metadata {
@@ -216,64 +215,5 @@ sub bind_testschema {
     Clownfish::CFC::Binding::Perl::Class->register($binding);
 }
 
-sub bind_bbsortex {
-    my @hand_rolled = qw(
-        Fetch
-        Peek
-        Feed
-    );
-    my $xs_code = <<'END_XS_CODE';
-MODULE = Lucy    PACKAGE = Lucy::Test::Util::BBSortEx
-
-SV*
-fetch(self)
-    testlucy_BBSortEx *self;
-CODE:
-{
-    void *address = TestLucy_BBSortEx_Fetch(self);
-    if (address) {
-        RETVAL = XSBind_cfish_to_perl(*(cfish_Obj**)address);
-        CFISH_DECREF(*(cfish_Obj**)address);
-    }
-    else {
-        RETVAL = newSV(0);
-    }
-}
-OUTPUT: RETVAL
-
-SV*
-peek(self)
-    testlucy_BBSortEx *self;
-CODE:
-{
-    void *address = TestLucy_BBSortEx_Peek(self);
-    if (address) {
-        RETVAL = XSBind_cfish_to_perl(*(cfish_Obj**)address);
-    }
-    else {
-        RETVAL = newSV(0);
-    }
-}
-OUTPUT: RETVAL
-
-void
-feed(self, bb)
-    testlucy_BBSortEx *self;
-    cfish_ByteBuf *bb;
-CODE:
-    CFISH_INCREF(bb);
-    TestLucy_BBSortEx_Feed(self, &bb);
-
-END_XS_CODE
-
-    my $binding = Clownfish::CFC::Binding::Perl::Class->new(
-        parcel     => "TestLucy",
-        class_name => "Lucy::Test::Util::BBSortEx",
-    );
-    $binding->append_xs($xs_code);
-
-    Clownfish::CFC::Binding::Perl::Class->register($binding);
-}
-
 1;
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/abf9363a/perl/buildlib/Lucy/Build/Binding/Util.pm
----------------------------------------------------------------------
diff --git a/perl/buildlib/Lucy/Build/Binding/Util.pm b/perl/buildlib/Lucy/Build/Binding/Util.pm
index df3ee31..a64c58b 100644
--- a/perl/buildlib/Lucy/Build/Binding/Util.pm
+++ b/perl/buildlib/Lucy/Build/Binding/Util.pm
@@ -21,6 +21,7 @@ $VERSION = eval $VERSION;
 
 sub bind_all {
     my $class = shift;
+    $class->bind_bbsortex;
     $class->bind_debug;
     $class->bind_freezer;
     $class->bind_indexfilenames;
@@ -30,6 +31,65 @@ sub bind_all {
     $class->bind_stepper;
 }
 
+sub bind_bbsortex {
+    my @hand_rolled = qw(
+        Fetch
+        Peek
+        Feed
+    );
+    my $xs_code = <<'END_XS_CODE';
+MODULE = Lucy    PACKAGE = Lucy::Util::BBSortEx
+
+SV*
+fetch(self)
+    lucy_BBSortEx *self;
+CODE:
+{
+    void *address = Lucy_BBSortEx_Fetch(self);
+    if (address) {
+        RETVAL = XSBind_cfish_to_perl(*(cfish_Obj**)address);
+        CFISH_DECREF(*(cfish_Obj**)address);
+    }
+    else {
+        RETVAL = newSV(0);
+    }
+}
+OUTPUT: RETVAL
+
+SV*
+peek(self)
+    lucy_BBSortEx *self;
+CODE:
+{
+    void *address = Lucy_BBSortEx_Peek(self);
+    if (address) {
+        RETVAL = XSBind_cfish_to_perl(*(cfish_Obj**)address);
+    }
+    else {
+        RETVAL = newSV(0);
+    }
+}
+OUTPUT: RETVAL
+
+void
+feed(self, bb)
+    lucy_BBSortEx *self;
+    cfish_ByteBuf *bb;
+CODE:
+    CFISH_INCREF(bb);
+    Lucy_BBSortEx_Feed(self, &bb);
+
+END_XS_CODE
+
+    my $binding = Clownfish::CFC::Binding::Perl::Class->new(
+        parcel     => "Lucy",
+        class_name => "Lucy::Util::BBSortEx",
+    );
+    $binding->append_xs($xs_code);
+
+    Clownfish::CFC::Binding::Perl::Class->register($binding);
+}
+
 sub bind_debug {
     my $xs_code = <<'END_XS_CODE';
 MODULE = Lucy   PACKAGE = Lucy::Util::Debug

http://git-wip-us.apache.org/repos/asf/lucy/blob/abf9363a/perl/lib/Lucy/Test/Util/BBSortEx.pm
----------------------------------------------------------------------
diff --git a/perl/lib/Lucy/Test/Util/BBSortEx.pm b/perl/lib/Lucy/Test/Util/BBSortEx.pm
deleted file mode 100644
index 5c968f7..0000000
--- a/perl/lib/Lucy/Test/Util/BBSortEx.pm
+++ /dev/null
@@ -1,25 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-package Lucy::Test::Util::BBSortEx;
-use Lucy;
-our $VERSION = '0.003000';
-$VERSION = eval $VERSION;
-
-1;
-
-__END__
-
-

http://git-wip-us.apache.org/repos/asf/lucy/blob/abf9363a/perl/lib/Lucy/Util/BBSortEx.pm
----------------------------------------------------------------------
diff --git a/perl/lib/Lucy/Util/BBSortEx.pm b/perl/lib/Lucy/Util/BBSortEx.pm
new file mode 100644
index 0000000..cbba688
--- /dev/null
+++ b/perl/lib/Lucy/Util/BBSortEx.pm
@@ -0,0 +1,25 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+package Lucy::Util::BBSortEx;
+use Lucy;
+our $VERSION = '0.003000';
+$VERSION = eval $VERSION;
+
+1;
+
+__END__
+
+

http://git-wip-us.apache.org/repos/asf/lucy/blob/abf9363a/perl/t/015-sort_external.t
----------------------------------------------------------------------
diff --git a/perl/t/015-sort_external.t b/perl/t/015-sort_external.t
index 4d8bdad..134e7c7 100644
--- a/perl/t/015-sort_external.t
+++ b/perl/t/015-sort_external.t
@@ -23,7 +23,7 @@ use bytes qw();
 
 my ( $sortex, $cache, @orig, @sort_output );
 
-$sortex = Lucy::Test::Util::BBSortEx->new( mem_thresh => 4 );
+$sortex = Lucy::Util::BBSortEx->new( mem_thresh => 4 );
 $sortex->feed( new_bytebuf('c') );
 is( $sortex->cache_count, 1, "feed elem into cache" );
 
@@ -42,7 +42,7 @@ is( $sortex->cache_count, 0,
 #is( $sortex->get_num_runs, 1, "run added" );
 
 my @bytebufs = map { new_bytebuf($_) } qw( x y z );
-my $run = Lucy::Test::Util::BBSortEx->new( external => \@bytebufs );
+my $run = Lucy::Util::BBSortEx->new( external => \@bytebufs );
 $sortex->add_run($run);
 $sortex->flip;
 @orig = qw( a b c d x y z );
@@ -53,7 +53,7 @@ is_deeply( \@sort_output, \@orig, "Add_Run" );
 @orig        = ();
 @sort_output = ();
 
-$sortex = Lucy::Test::Util::BBSortEx->new( mem_thresh => 4 );
+$sortex = Lucy::Util::BBSortEx->new( mem_thresh => 4 );
 $sortex->feed( new_bytebuf('c') );
 $sortex->clear_cache;
 is( $sortex->cache_count, 0, "Clear_Cache" );
@@ -72,7 +72,7 @@ is_deeply( \@sort_output, \@orig,
 @orig        = ();
 @sort_output = ();
 
-$sortex = Lucy::Test::Util::BBSortEx->new;
+$sortex = Lucy::Util::BBSortEx->new;
 @orig   = ( 'a' .. 'z' );
 $sortex->feed( new_bytebuf($_) ) for shuffle(@orig);
 $sortex->flip;
@@ -83,7 +83,7 @@ is_deeply( \@sort_output, \@orig, "sort letters" );
 @orig        = ();
 @sort_output = ();
 
-$sortex = Lucy::Test::Util::BBSortEx->new;
+$sortex = Lucy::Util::BBSortEx->new;
 @orig   = qw( a a a b c d x x x x x x y y );
 $sortex->feed( new_bytebuf($_) ) for shuffle(@orig);
 $sortex->flip;
@@ -94,7 +94,7 @@ is_deeply( \@sort_output, \@orig, "sort repeated letters" );
 @orig        = ();
 @sort_output = ();
 
-$sortex = Lucy::Test::Util::BBSortEx->new;
+$sortex = Lucy::Util::BBSortEx->new;
 @orig = ( '', '', 'a' .. 'z' );
 $sortex->feed( new_bytebuf($_) ) for shuffle(@orig);
 $sortex->flip;
@@ -105,7 +105,7 @@ is_deeply( \@sort_output, \@orig, "sort letters and empty strings" );
 @orig        = ();
 @sort_output = ();
 
-$sortex = Lucy::Test::Util::BBSortEx->new( mem_thresh => 30 );
+$sortex = Lucy::Util::BBSortEx->new( mem_thresh => 30 );
 @orig = 'a' .. 'z';
 $sortex->feed( new_bytebuf($_) ) for shuffle(@orig);
 $sortex->flip;
@@ -116,7 +116,7 @@ is_deeply( \@sort_output, \@orig, "... with an absurdly low mem_thresh" );
 @orig        = ();
 @sort_output = ();
 
-$sortex = Lucy::Test::Util::BBSortEx->new( mem_thresh => 1 );
+$sortex = Lucy::Util::BBSortEx->new( mem_thresh => 1 );
 @orig = 'a' .. 'z';
 $sortex->feed( new_bytebuf($_) ) for shuffle(@orig);
 $sortex->flip;
@@ -127,13 +127,13 @@ is_deeply( \@sort_output, \@orig, "... with an even lower mem_thresh" );
 @orig        = ();
 @sort_output = ();
 
-$sortex = Lucy::Test::Util::BBSortEx->new;
+$sortex = Lucy::Util::BBSortEx->new;
 $sortex->flip;
 @sort_output = $sortex->fetch;
 is_deeply( \@sort_output, [undef], "Sorting nothing returns undef" );
 @sort_output = ();
 
-$sortex = Lucy::Test::Util::BBSortEx->new( mem_thresh => 5_000 );
+$sortex = Lucy::Util::BBSortEx->new( mem_thresh => 5_000 );
 @orig = map { pack( 'N', $_ ) } ( 0 .. 11_000 );
 $sortex->feed( new_bytebuf($_) ) for shuffle(@orig);
 $sortex->flip;
@@ -143,7 +143,7 @@ while ( defined( my $item = $sortex->fetch ) ) {
 is_deeply( \@sort_output, \@orig, "Sorting packed integers..." );
 @sort_output = ();
 
-$sortex = Lucy::Test::Util::BBSortEx->new( mem_thresh => 15_000 );
+$sortex = Lucy::Util::BBSortEx->new( mem_thresh => 15_000 );
 @orig = ();
 for my $iter ( 0 .. 1_000 ) {
     my $string = '';

http://git-wip-us.apache.org/repos/asf/lucy/blob/abf9363a/perl/t/028-sortexrun.t
----------------------------------------------------------------------
diff --git a/perl/t/028-sortexrun.t b/perl/t/028-sortexrun.t
index 64b9ef7..a9a075b 100644
--- a/perl/t/028-sortexrun.t
+++ b/perl/t/028-sortexrun.t
@@ -24,7 +24,7 @@ use Clownfish qw( to_perl );
 
 my $letters = Clownfish::VArray->new( capacity => 26 );
 $letters->push( Clownfish::ByteBuf->new($_) ) for 'a' .. 'z';
-my $run = Lucy::Test::Util::BBSortEx->new( external => $letters );
+my $run = Lucy::Util::BBSortEx->new( external => $letters );
 $run->set_mem_thresh(5);
 
 my $num_in_cache = $run->refill;


[lucy-commits] [22/34] git commit: refs/heads/master - Migrate Lucy's posting classes to IVARS.

Posted by ma...@apache.org.
Migrate Lucy's posting classes to IVARS.

Change all of Lucy's posting classes to access instance vars via an IVARS
struct rather than via `self`.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/14e863fb
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/14e863fb
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/14e863fb

Branch: refs/heads/master
Commit: 14e863fb64d05f441e086074a620f94a1d9cd5ae
Parents: 965fdb2
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Sun Jun 30 20:34:50 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 16:08:43 2013 -0700

----------------------------------------------------------------------
 core/Lucy/Index/Posting/MatchPosting.c | 127 ++++++++++++++++------------
 core/Lucy/Index/Posting/RawPosting.c   |  48 ++++++-----
 core/Lucy/Index/Posting/RichPosting.c  |  69 ++++++++-------
 core/Lucy/Index/Posting/ScorePosting.c |  98 ++++++++++++---------
 4 files changed, 199 insertions(+), 143 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/14e863fb/core/Lucy/Index/Posting/MatchPosting.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/Posting/MatchPosting.c b/core/Lucy/Index/Posting/MatchPosting.c
index 3ff887f..bdb9f97 100644
--- a/core/Lucy/Index/Posting/MatchPosting.c
+++ b/core/Lucy/Index/Posting/MatchPosting.c
@@ -43,8 +43,8 @@
 #include "Lucy/Store/OutStream.h"
 #include "Lucy/Util/MemoryPool.h"
 
-#define MAX_RAW_POSTING_LEN(_text_len) \
-    (              sizeof(RawPosting) \
+#define MAX_RAW_POSTING_LEN(_raw_post_size, _text_len) \
+    (              _raw_post_size \
                    + _text_len + 1            /* term text content */ \
     )
 
@@ -56,38 +56,41 @@ MatchPost_new(Similarity *sim) {
 
 MatchPosting*
 MatchPost_init(MatchPosting *self, Similarity *sim) {
-    self->sim = (Similarity*)INCREF(sim);
+    MatchPostingIVARS *const ivars = MatchPost_IVARS(self);
+    ivars->sim = (Similarity*)INCREF(sim);
     return (MatchPosting*)Post_init((Posting*)self);
 }
 
 void
 MatchPost_destroy(MatchPosting *self) {
-    DECREF(self->sim);
+    MatchPostingIVARS *const ivars = MatchPost_IVARS(self);
+    DECREF(ivars->sim);
     SUPER_DESTROY(self, MATCHPOSTING);
 }
 
 int32_t
 MatchPost_get_freq(MatchPosting *self) {
-    return self->freq;
+    return MatchPost_IVARS(self)->freq;
 }
 
 void
 MatchPost_reset(MatchPosting *self) {
-    self->doc_id = 0;
+    MatchPost_IVARS(self)->doc_id = 0;
 }
 
 void
 MatchPost_read_record(MatchPosting *self, InStream *instream) {
+    MatchPostingIVARS *const ivars = MatchPost_IVARS(self);
     const uint32_t doc_code = InStream_Read_C32(instream);
     const uint32_t doc_delta = doc_code >> 1;
 
     // Apply delta doc and retrieve freq.
-    self->doc_id   += doc_delta;
+    ivars->doc_id   += doc_delta;
     if (doc_code & 1) {
-        self->freq = 1;
+        ivars->freq = 1;
     }
     else {
-        self->freq = InStream_Read_C32(instream);
+        ivars->freq = InStream_Read_C32(instream);
     }
 }
 
@@ -102,7 +105,8 @@ MatchPost_read_raw(MatchPosting *self, InStream *instream, int32_t last_doc_id,
     const uint32_t freq      = (doc_code & 1)
                                ? 1
                                : InStream_Read_C32(instream);
-    size_t raw_post_bytes    = MAX_RAW_POSTING_LEN(text_size);
+    const size_t base_size    = VTable_Get_Obj_Alloc_Size(RAWPOSTING);
+    size_t raw_post_bytes    = MAX_RAW_POSTING_LEN(base_size, text_size);
     void *const allocation   = MemPool_Grab(mem_pool, raw_post_bytes);
     UNUSED_VAR(self);
 
@@ -115,6 +119,7 @@ MatchPost_add_inversion_to_pool(MatchPosting *self, PostingPool *post_pool,
                                 int32_t doc_id, float doc_boost,
                                 float length_norm) {
     MemoryPool  *mem_pool = PostPool_Get_Mem_Pool(post_pool);
+    const size_t base_size = VTable_Get_Obj_Alloc_Size(RAWPOSTING);
     Token      **tokens;
     uint32_t     freq;
 
@@ -125,11 +130,12 @@ MatchPost_add_inversion_to_pool(MatchPosting *self, PostingPool *post_pool,
 
     Inversion_Reset(inversion);
     while ((tokens = Inversion_Next_Cluster(inversion, &freq)) != NULL) {
-        Token   *token          = *tokens;
-        uint32_t raw_post_bytes = MAX_RAW_POSTING_LEN(token->len);
+        TokenIVARS *const token_ivars = Token_IVARS(*tokens);
+        uint32_t raw_post_bytes
+            = MAX_RAW_POSTING_LEN(base_size, token_ivars->len);
         RawPosting *raw_posting
             = RawPost_new(MemPool_Grab(mem_pool, raw_post_bytes), doc_id,
-                          freq, token->text, token->len);
+                          freq, token_ivars->text, token_ivars->len);
         PostPool_Feed(post_pool, &raw_posting);
     }
 }
@@ -156,7 +162,7 @@ MatchPostMatcher_init(MatchPostingMatcher *self, Similarity *sim,
 
 float
 MatchPostMatcher_score(MatchPostingMatcher* self) {
-    return self->weight;
+    return MatchPostMatcher_IVARS(self)->weight;
 }
 
 /***************************************************************************/
@@ -179,46 +185,55 @@ MatchPostWriter_init(MatchPostingWriter *self, Schema *schema,
         = CB_newf("%o/postings-%i32.dat", Seg_Get_Name(segment), field_num);
     PostWriter_init((PostingWriter*)self, schema, snapshot, segment,
                     polyreader, field_num);
-    self->outstream = Folder_Open_Out(folder, filename);
-    if (!self->outstream) { RETHROW(INCREF(Err_get_error())); }
+    MatchPostingWriterIVARS *const ivars = MatchPostWriter_IVARS(self);
+    ivars->outstream = Folder_Open_Out(folder, filename);
+    if (!ivars->outstream) { RETHROW(INCREF(Err_get_error())); }
     DECREF(filename);
     return self;
 }
 
 void
 MatchPostWriter_destroy(MatchPostingWriter *self) {
-    DECREF(self->outstream);
+    MatchPostingWriterIVARS *const ivars = MatchPostWriter_IVARS(self);
+    DECREF(ivars->outstream);
     SUPER_DESTROY(self, MATCHPOSTINGWRITER);
 }
 
 void
 MatchPostWriter_write_posting(MatchPostingWriter *self, RawPosting *posting) {
-    OutStream *const outstream   = self->outstream;
-    const int32_t    doc_id      = posting->doc_id;
-    const uint32_t   delta_doc   = doc_id - self->last_doc_id;
-    char  *const     aux_content = posting->blob + posting->content_len;
-    if (posting->freq == 1) {
+    MatchPostingWriterIVARS *const ivars = MatchPostWriter_IVARS(self);
+    RawPostingIVARS *const posting_ivars = RawPost_IVARS(posting);
+    OutStream *const outstream   = ivars->outstream;
+    const int32_t    doc_id      = posting_ivars->doc_id;
+    const uint32_t   delta_doc   = doc_id - ivars->last_doc_id;
+    char  *const     aux_content = posting_ivars->blob
+                                   + posting_ivars->content_len;
+    if (posting_ivars->freq == 1) {
         const uint32_t doc_code = (delta_doc << 1) | 1;
         OutStream_Write_C32(outstream, doc_code);
     }
     else {
         const uint32_t doc_code = delta_doc << 1;
         OutStream_Write_C32(outstream, doc_code);
-        OutStream_Write_C32(outstream, posting->freq);
+        OutStream_Write_C32(outstream, posting_ivars->freq);
     }
-    OutStream_Write_Bytes(outstream, aux_content, posting->aux_len);
-    self->last_doc_id = doc_id;
+    OutStream_Write_Bytes(outstream, aux_content, posting_ivars->aux_len);
+    ivars->last_doc_id = doc_id;
 }
 
 void
 MatchPostWriter_start_term(MatchPostingWriter *self, TermInfo *tinfo) {
-    self->last_doc_id   = 0;
-    tinfo->post_filepos = OutStream_Tell(self->outstream);
+    MatchPostingWriterIVARS *const ivars = MatchPostWriter_IVARS(self);
+    TermInfoIVARS *const tinfo_ivars = TInfo_IVARS(tinfo);
+    ivars->last_doc_id   = 0;
+    tinfo_ivars->post_filepos = OutStream_Tell(ivars->outstream);
 }
 
 void
 MatchPostWriter_update_skip_info(MatchPostingWriter *self, TermInfo *tinfo) {
-    tinfo->post_filepos = OutStream_Tell(self->outstream);
+    MatchPostingWriterIVARS *const ivars = MatchPostWriter_IVARS(self);
+    TermInfoIVARS *const tinfo_ivars = TInfo_IVARS(tinfo);
+    tinfo_ivars->post_filepos = OutStream_Tell(ivars->outstream);
 }
 
 /***************************************************************************/
@@ -234,43 +249,49 @@ MatchTermInfoStepper*
 MatchTInfoStepper_init(MatchTermInfoStepper *self, Schema *schema) {
     Architecture *arch = Schema_Get_Architecture(schema);
     TermStepper_init((TermStepper*)self);
-    self->skip_interval = Arch_Skip_Interval(arch);
-    self->value = (Obj*)TInfo_new(0);
+    MatchTermInfoStepperIVARS *const ivars = MatchTInfoStepper_IVARS(self);
+    ivars->skip_interval = Arch_Skip_Interval(arch);
+    ivars->value = (Obj*)TInfo_new(0);
     return self;
 }
 
 void
 MatchTInfoStepper_reset(MatchTermInfoStepper *self) {
-    TInfo_Reset((TermInfo*)self->value);
+    MatchTermInfoStepperIVARS *const ivars = MatchTInfoStepper_IVARS(self);
+    TInfo_Reset((TermInfo*)ivars->value);
 }
 
 void
 MatchTInfoStepper_write_key_frame(MatchTermInfoStepper *self,
                                   OutStream *outstream, Obj *value) {
+    MatchTermInfoStepperIVARS *const ivars = MatchTInfoStepper_IVARS(self);
     TermInfo *tinfo    = (TermInfo*)CERTIFY(value, TERMINFO);
     int32_t   doc_freq = TInfo_Get_Doc_Freq(tinfo);
+    TermInfoIVARS *const tinfo_ivars = TInfo_IVARS((TermInfo*)value);
 
     // Write doc_freq.
     OutStream_Write_C32(outstream, doc_freq);
 
     // Write postings file pointer.
-    OutStream_Write_C64(outstream, tinfo->post_filepos);
+    OutStream_Write_C64(outstream, tinfo_ivars->post_filepos);
 
     // Write skip file pointer (maybe).
-    if (doc_freq >= self->skip_interval) {
-        OutStream_Write_C64(outstream, tinfo->skip_filepos);
+    if (doc_freq >= ivars->skip_interval) {
+        OutStream_Write_C64(outstream, tinfo_ivars->skip_filepos);
     }
 
-    TInfo_Mimic((TermInfo*)self->value, (Obj*)tinfo);
+    TInfo_Mimic((TermInfo*)ivars->value, (Obj*)tinfo);
 }
 
 void
 MatchTInfoStepper_write_delta(MatchTermInfoStepper *self,
                               OutStream *outstream, Obj *value) {
+    MatchTermInfoStepperIVARS *const ivars = MatchTInfoStepper_IVARS(self);
     TermInfo *tinfo      = (TermInfo*)CERTIFY(value, TERMINFO);
-    TermInfo *last_tinfo = (TermInfo*)self->value;
+    TermInfo *last_tinfo = (TermInfo*)ivars->value;
     int32_t   doc_freq   = TInfo_Get_Doc_Freq(tinfo);
-    int64_t   post_delta = tinfo->post_filepos - last_tinfo->post_filepos;
+    int64_t   post_delta = TInfo_IVARS(tinfo)->post_filepos
+                           - TInfo_IVARS(last_tinfo)->post_filepos;
 
     // Write doc_freq.
     OutStream_Write_C32(outstream, doc_freq);
@@ -279,49 +300,51 @@ MatchTInfoStepper_write_delta(MatchTermInfoStepper *self,
     OutStream_Write_C64(outstream, post_delta);
 
     // Write skip file pointer (maybe).
-    if (doc_freq >= self->skip_interval) {
-        OutStream_Write_C64(outstream, tinfo->skip_filepos);
+    if (doc_freq >= ivars->skip_interval) {
+        OutStream_Write_C64(outstream, TInfo_IVARS(tinfo)->skip_filepos);
     }
 
-    TInfo_Mimic((TermInfo*)self->value, (Obj*)tinfo);
+    TInfo_Mimic((TermInfo*)ivars->value, (Obj*)tinfo);
 }
 
 void
 MatchTInfoStepper_read_key_frame(MatchTermInfoStepper *self,
                                  InStream *instream) {
-    TermInfo *const tinfo = (TermInfo*)self->value;
+    MatchTermInfoStepperIVARS *const ivars = MatchTInfoStepper_IVARS(self);
+    TermInfoIVARS *const tinfo_ivars = TInfo_IVARS((TermInfo*)ivars->value);
 
     // Read doc freq.
-    tinfo->doc_freq = InStream_Read_C32(instream);
+    tinfo_ivars->doc_freq = InStream_Read_C32(instream);
 
     // Read postings file pointer.
-    tinfo->post_filepos = InStream_Read_C64(instream);
+    tinfo_ivars->post_filepos = InStream_Read_C64(instream);
 
     // Maybe read skip pointer.
-    if (tinfo->doc_freq >= self->skip_interval) {
-        tinfo->skip_filepos = InStream_Read_C64(instream);
+    if (tinfo_ivars->doc_freq >= ivars->skip_interval) {
+        tinfo_ivars->skip_filepos = InStream_Read_C64(instream);
     }
     else {
-        tinfo->skip_filepos = 0;
+        tinfo_ivars->skip_filepos = 0;
     }
 }
 
 void
 MatchTInfoStepper_read_delta(MatchTermInfoStepper *self, InStream *instream) {
-    TermInfo *const tinfo = (TermInfo*)self->value;
+    MatchTermInfoStepperIVARS *const ivars = MatchTInfoStepper_IVARS(self);
+    TermInfoIVARS *const tinfo_ivars = TInfo_IVARS((TermInfo*)ivars->value);
 
     // Read doc freq.
-    tinfo->doc_freq = InStream_Read_C32(instream);
+    tinfo_ivars->doc_freq = InStream_Read_C32(instream);
 
     // Adjust postings file pointer.
-    tinfo->post_filepos += InStream_Read_C64(instream);
+    tinfo_ivars->post_filepos += InStream_Read_C64(instream);
 
     // Maybe read skip pointer.
-    if (tinfo->doc_freq >= self->skip_interval) {
-        tinfo->skip_filepos = InStream_Read_C64(instream);
+    if (tinfo_ivars->doc_freq >= ivars->skip_interval) {
+        tinfo_ivars->skip_filepos = InStream_Read_C64(instream);
     }
     else {
-        tinfo->skip_filepos = 0;
+        tinfo_ivars->skip_filepos = 0;
     }
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/14e863fb/core/Lucy/Index/Posting/RawPosting.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/Posting/RawPosting.c b/core/Lucy/Index/Posting/RawPosting.c
index eb87fb2..1fb73be 100644
--- a/core/Lucy/Index/Posting/RawPosting.c
+++ b/core/Lucy/Index/Posting/RawPosting.c
@@ -35,11 +35,12 @@ RawPost_new(void *pre_allocated_memory, int32_t doc_id, uint32_t freq,
             char *term_text, size_t term_text_len) {
     RawPosting *self
         = (RawPosting*)VTable_Init_Obj(RAWPOSTING, pre_allocated_memory);
-    self->doc_id      = doc_id;
-    self->freq        = freq;
-    self->content_len = term_text_len;
-    self->aux_len     = 0;
-    memcpy(&self->blob, term_text, term_text_len);
+    RawPostingIVARS *const ivars = RawPost_IVARS(self);
+    ivars->doc_id      = doc_id;
+    ivars->freq        = freq;
+    ivars->content_len = term_text_len;
+    ivars->aux_len     = 0;
+    memcpy(&ivars->blob, term_text, term_text_len);
 
     return self;
 }
@@ -85,45 +86,54 @@ RawPostWriter_init(RawPostingWriter *self, Schema *schema,
     const int32_t invalid_field_num = 0;
     PostWriter_init((PostingWriter*)self, schema, snapshot, segment,
                     polyreader, invalid_field_num);
-    self->outstream = (OutStream*)INCREF(outstream);
-    self->last_doc_id = 0;
+    RawPostingWriterIVARS *const ivars = RawPostWriter_IVARS(self);
+    ivars->outstream = (OutStream*)INCREF(outstream);
+    ivars->last_doc_id = 0;
     return self;
 }
 
 void
 RawPostWriter_start_term(RawPostingWriter *self, TermInfo *tinfo) {
-    self->last_doc_id   = 0;
-    tinfo->post_filepos = OutStream_Tell(self->outstream);
+    RawPostingWriterIVARS *const ivars = RawPostWriter_IVARS(self);
+    ivars->last_doc_id   = 0;
+    TermInfoIVARS *const tinfo_ivars = TInfo_IVARS(tinfo);
+    tinfo_ivars->post_filepos = OutStream_Tell(ivars->outstream);
 }
 
 void
 RawPostWriter_update_skip_info(RawPostingWriter *self, TermInfo *tinfo) {
-    tinfo->post_filepos = OutStream_Tell(self->outstream);
+    RawPostingWriterIVARS *const ivars = RawPostWriter_IVARS(self);
+    TermInfoIVARS *const tinfo_ivars = TInfo_IVARS(tinfo);
+    tinfo_ivars->post_filepos = OutStream_Tell(ivars->outstream);
 }
 
 void
 RawPostWriter_destroy(RawPostingWriter *self) {
-    DECREF(self->outstream);
+    RawPostingWriterIVARS *const ivars = RawPostWriter_IVARS(self);
+    DECREF(ivars->outstream);
     SUPER_DESTROY(self, RAWPOSTINGWRITER);
 }
 
 void
 RawPostWriter_write_posting(RawPostingWriter *self, RawPosting *posting) {
-    OutStream *const outstream   = self->outstream;
-    const int32_t    doc_id      = posting->doc_id;
-    const uint32_t   delta_doc   = doc_id - self->last_doc_id;
-    char  *const     aux_content = posting->blob + posting->content_len;
-    if (posting->freq == 1) {
+    RawPostingWriterIVARS *const ivars = RawPostWriter_IVARS(self);
+    RawPostingIVARS *const posting_ivars = RawPost_IVARS(posting);
+    OutStream *const outstream   = ivars->outstream;
+    const int32_t    doc_id      = posting_ivars->doc_id;
+    const uint32_t   delta_doc   = doc_id - ivars->last_doc_id;
+    char  *const     aux_content = posting_ivars->blob
+                                   + posting_ivars->content_len;
+    if (posting_ivars->freq == 1) {
         const uint32_t doc_code = (delta_doc << 1) | 1;
         OutStream_Write_C32(outstream, doc_code);
     }
     else {
         const uint32_t doc_code = delta_doc << 1;
         OutStream_Write_C32(outstream, doc_code);
-        OutStream_Write_C32(outstream, posting->freq);
+        OutStream_Write_C32(outstream, posting_ivars->freq);
     }
-    OutStream_Write_Bytes(outstream, aux_content, posting->aux_len);
-    self->last_doc_id = doc_id;
+    OutStream_Write_Bytes(outstream, aux_content, posting_ivars->aux_len);
+    ivars->last_doc_id = doc_id;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/14e863fb/core/Lucy/Index/Posting/RichPosting.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/Posting/RichPosting.c b/core/Lucy/Index/Posting/RichPosting.c
index 30b4f39..9715765 100644
--- a/core/Lucy/Index/Posting/RichPosting.c
+++ b/core/Lucy/Index/Posting/RichPosting.c
@@ -33,8 +33,8 @@
 #include "Lucy/Util/MemoryPool.h"
 
 #define FREQ_MAX_LEN     C32_MAX_BYTES
-#define MAX_RAW_POSTING_LEN(_text_len, _freq) \
-    (              sizeof(RawPosting) \
+#define MAX_RAW_POSTING_LEN(_raw_posting_size, _text_len, _freq) \
+    (              _raw_posting_size \
                    + _text_len                /* term text content */ \
                    + FREQ_MAX_LEN             /* freq c32 */ \
                    + (C32_MAX_BYTES * _freq)  /* positions deltas */ \
@@ -50,46 +50,49 @@ RichPost_new(Similarity *sim) {
 RichPosting*
 RichPost_init(RichPosting *self, Similarity *sim) {
     ScorePost_init((ScorePosting*)self, sim);
-    self->prox_boosts     = NULL;
+    RichPostingIVARS *const ivars = RichPost_IVARS(self);
+    ivars->prox_boosts     = NULL;
     return self;
 }
 
 void
 RichPost_destroy(RichPosting *self) {
-    FREEMEM(self->prox_boosts);
+    RichPostingIVARS *const ivars = RichPost_IVARS(self);
+    FREEMEM(ivars->prox_boosts);
     SUPER_DESTROY(self, RICHPOSTING);
 }
 
 void
 RichPost_read_record(RichPosting *self, InStream *instream) {
-    float *const norm_decoder = self->norm_decoder;
+    RichPostingIVARS *const ivars = RichPost_IVARS(self);
+    float *const norm_decoder = ivars->norm_decoder;
     uint32_t  num_prox = 0;
     uint32_t  position = 0;
     float     aggregate_weight = 0.0;
 
     // Decode delta doc.
     uint32_t doc_code = InStream_Read_C32(instream);
-    self->doc_id += doc_code >> 1;
+    ivars->doc_id += doc_code >> 1;
 
     // If the stored num was odd, the freq is 1.
     if (doc_code & 1) {
-        self->freq = 1;
+        ivars->freq = 1;
     }
     // Otherwise, freq was stored as a C32.
     else {
-        self->freq = InStream_Read_C32(instream);
+        ivars->freq = InStream_Read_C32(instream);
     }
 
     // Read positions, aggregate per-position boost byte into weight.
-    num_prox = self->freq;
-    if (num_prox > self->prox_cap) {
-        self->prox
-            = (uint32_t*)REALLOCATE(self->prox, num_prox * sizeof(uint32_t));
-        self->prox_boosts
-            = (float*)REALLOCATE(self->prox_boosts, num_prox * sizeof(float));
+    num_prox = ivars->freq;
+    if (num_prox > ivars->prox_cap) {
+        ivars->prox
+            = (uint32_t*)REALLOCATE(ivars->prox, num_prox * sizeof(uint32_t));
+        ivars->prox_boosts
+            = (float*)REALLOCATE(ivars->prox_boosts, num_prox * sizeof(float));
     }
-    uint32_t *positions    = self->prox;
-    float    *prox_boosts  = self->prox_boosts;
+    uint32_t *positions    = ivars->prox;
+    float    *prox_boosts  = ivars->prox_boosts;
 
     while (num_prox--) {
         position += InStream_Read_C32(instream);
@@ -98,7 +101,7 @@ RichPost_read_record(RichPosting *self, InStream *instream) {
         aggregate_weight += *prox_boosts;
         prox_boosts++;
     }
-    self->weight = aggregate_weight / self->freq;
+    ivars->weight = aggregate_weight / ivars->freq;
 }
 
 void
@@ -106,38 +109,42 @@ RichPost_add_inversion_to_pool(RichPosting *self, PostingPool *post_pool,
                                Inversion *inversion, FieldType *type,
                                int32_t doc_id, float doc_boost,
                                float length_norm) {
+    RichPostingIVARS *const ivars = RichPost_IVARS(self);
     MemoryPool *mem_pool = PostPool_Get_Mem_Pool(post_pool);
-    Similarity *sim = self->sim;
+    Similarity *sim = ivars->sim;
     float       field_boost = doc_boost * FType_Get_Boost(type) * length_norm;
+    const size_t base_size = VTable_Get_Obj_Alloc_Size(RAWPOSTING);
     Token     **tokens;
     uint32_t    freq;
 
     Inversion_Reset(inversion);
     while ((tokens = Inversion_Next_Cluster(inversion, &freq)) != NULL) {
-        Token   *token          = *tokens;
-        uint32_t raw_post_bytes = MAX_RAW_POSTING_LEN(token->len, freq);
+        TokenIVARS *const token_ivars = Token_IVARS(*tokens);
+        uint32_t raw_post_bytes
+            = MAX_RAW_POSTING_LEN(base_size, token_ivars->len, freq);
         RawPosting *raw_posting
             = RawPost_new(MemPool_Grab(mem_pool, raw_post_bytes), doc_id,
-                          freq, token->text, token->len);
-        char *const start = raw_posting->blob + token->len;
+                          freq, token_ivars->text, token_ivars->len);
+        RawPostingIVARS *const raw_post_ivars = RawPost_IVARS(raw_posting);
+        char *const start = raw_post_ivars->blob + token_ivars->len;
         char *dest = start;
         uint32_t last_prox = 0;
 
         // Positions and boosts.
         for (uint32_t i = 0; i < freq; i++) {
-            Token *const t = tokens[i];
-            const uint32_t prox_delta = t->pos - last_prox;
-            const float boost = field_boost * t->boost;
+            TokenIVARS *const t_ivars = Token_IVARS(tokens[i]);
+            const uint32_t prox_delta = t_ivars->pos - last_prox;
+            const float boost = field_boost * t_ivars->boost;
 
             NumUtil_encode_c32(prox_delta, &dest);
-            last_prox = t->pos;
+            last_prox = t_ivars->pos;
 
             *((uint8_t*)dest) = Sim_Encode_Norm(sim, boost);
             dest++;
         }
 
         // Resize raw posting memory allocation.
-        raw_posting->aux_len = dest - start;
+        raw_post_ivars->aux_len = dest - start;
         raw_post_bytes = dest - (char*)raw_posting;
         MemPool_Resize(mem_pool, raw_posting, raw_post_bytes);
         PostPool_Feed(post_pool, &raw_posting);
@@ -155,12 +162,14 @@ RichPost_read_raw(RichPosting *self, InStream *instream, int32_t last_doc_id,
     const uint32_t freq           = (doc_code & 1)
                                     ? 1
                                     : InStream_Read_C32(instream);
-    size_t raw_post_bytes         = MAX_RAW_POSTING_LEN(text_size, freq);
+    const size_t base_size        = VTable_Get_Obj_Alloc_Size(RAWPOSTING);
+    size_t raw_post_bytes         = MAX_RAW_POSTING_LEN(base_size, text_size, freq);
     void *const allocation        = MemPool_Grab(mem_pool, raw_post_bytes);
     RawPosting *const raw_posting
         = RawPost_new(allocation, doc_id, freq, text_buf, text_size);
+        RawPostingIVARS *const raw_post_ivars = RawPost_IVARS(raw_posting);
     uint32_t num_prox = freq;
-    char *const start = raw_posting->blob + text_size;
+    char *const start = raw_post_ivars->blob + text_size;
     char *      dest  = start;
     UNUSED_VAR(self);
 
@@ -172,7 +181,7 @@ RichPost_read_raw(RichPosting *self, InStream *instream, int32_t last_doc_id,
     }
 
     // Resize raw posting memory allocation.
-    raw_posting->aux_len = dest - start;
+    raw_post_ivars->aux_len = dest - start;
     raw_post_bytes       = dest - (char*)raw_posting;
     MemPool_Resize(mem_pool, raw_posting, raw_post_bytes);
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/14e863fb/core/Lucy/Index/Posting/ScorePosting.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/Posting/ScorePosting.c b/core/Lucy/Index/Posting/ScorePosting.c
index 08dee59..f02de37 100644
--- a/core/Lucy/Index/Posting/ScorePosting.c
+++ b/core/Lucy/Index/Posting/ScorePosting.c
@@ -35,8 +35,8 @@
 
 #define FIELD_BOOST_LEN  1
 #define FREQ_MAX_LEN     C32_MAX_BYTES
-#define MAX_RAW_POSTING_LEN(_text_len, _freq) \
-    (              sizeof(RawPosting) \
+#define MAX_RAW_POSTING_LEN(_raw_post_size, _text_len, _freq) \
+    (              _raw_post_size \
                    + _text_len                /* term text content */ \
                    + FIELD_BOOST_LEN          /* field boost byte */ \
                    + FREQ_MAX_LEN             /* freq c32 */ \
@@ -52,23 +52,25 @@ ScorePost_new(Similarity *sim) {
 ScorePosting*
 ScorePost_init(ScorePosting *self, Similarity *sim) {
     MatchPost_init((MatchPosting*)self, sim);
-    self->norm_decoder = Sim_Get_Norm_Decoder(sim);
-    self->freq         = 0;
-    self->weight       = 0.0;
-    self->prox         = NULL;
-    self->prox_cap     = 0;
+    ScorePostingIVARS *const ivars = ScorePost_IVARS(self);
+    ivars->norm_decoder = Sim_Get_Norm_Decoder(sim);
+    ivars->freq         = 0;
+    ivars->weight       = 0.0;
+    ivars->prox         = NULL;
+    ivars->prox_cap     = 0;
     return self;
 }
 
 void
 ScorePost_destroy(ScorePosting *self) {
-    FREEMEM(self->prox);
+    ScorePostingIVARS *const ivars = ScorePost_IVARS(self);
+    FREEMEM(ivars->prox);
     SUPER_DESTROY(self, SCOREPOSTING);
 }
 
 uint32_t*
 ScorePost_get_prox(ScorePosting *self) {
-    return self->prox;
+    return ScorePost_IVARS(self)->prox;
 }
 
 void
@@ -76,21 +78,25 @@ ScorePost_add_inversion_to_pool(ScorePosting *self, PostingPool *post_pool,
                                 Inversion *inversion, FieldType *type,
                                 int32_t doc_id, float doc_boost,
                                 float length_norm) {
+    ScorePostingIVARS *const ivars = ScorePost_IVARS(self);
     MemoryPool     *mem_pool = PostPool_Get_Mem_Pool(post_pool);
-    Similarity     *sim = self->sim;
+    Similarity     *sim = ivars->sim;
     float           field_boost = doc_boost * FType_Get_Boost(type) * length_norm;
     const uint8_t   field_boost_byte  = Sim_Encode_Norm(sim, field_boost);
+    const size_t    base_size = VTable_Get_Obj_Alloc_Size(RAWPOSTING);
     Token         **tokens;
     uint32_t        freq;
 
     Inversion_Reset(inversion);
     while ((tokens = Inversion_Next_Cluster(inversion, &freq)) != NULL) {
-        Token   *token          = *tokens;
-        uint32_t raw_post_bytes = MAX_RAW_POSTING_LEN(token->len, freq);
+        TokenIVARS *const token_ivars = Token_IVARS(*tokens);
+        uint32_t raw_post_bytes
+            = MAX_RAW_POSTING_LEN(base_size, token_ivars->len, freq);
         RawPosting *raw_posting
             = RawPost_new(MemPool_Grab(mem_pool, raw_post_bytes), doc_id,
-                          freq, token->text, token->len);
-        char *const start  = raw_posting->blob + token->len;
+                          freq, token_ivars->text, token_ivars->len);
+        RawPostingIVARS *const raw_post_ivars = RawPost_IVARS(raw_posting);
+        char *const start  = raw_post_ivars->blob + token_ivars->len;
         char *dest         = start;
         uint32_t last_prox = 0;
 
@@ -100,14 +106,14 @@ ScorePost_add_inversion_to_pool(ScorePosting *self, PostingPool *post_pool,
 
         // Positions.
         for (uint32_t i = 0; i < freq; i++) {
-            Token *const t = tokens[i];
-            const uint32_t prox_delta = t->pos - last_prox;
+            TokenIVARS *const t_ivars = Token_IVARS(tokens[i]);
+            const uint32_t prox_delta = t_ivars->pos - last_prox;
             NumUtil_encode_c32(prox_delta, &dest);
-            last_prox = t->pos;
+            last_prox = t_ivars->pos;
         }
 
         // Resize raw posting memory allocation.
-        raw_posting->aux_len = dest - start;
+        raw_post_ivars->aux_len = dest - start;
         raw_post_bytes = dest - (char*)raw_posting;
         MemPool_Resize(mem_pool, raw_posting, raw_post_bytes);
         PostPool_Feed(post_pool, &raw_posting);
@@ -116,13 +122,15 @@ ScorePost_add_inversion_to_pool(ScorePosting *self, PostingPool *post_pool,
 
 void
 ScorePost_reset(ScorePosting *self) {
-    self->doc_id = 0;
-    self->freq   = 0;
-    self->weight = 0.0;
+    ScorePostingIVARS *const ivars = ScorePost_IVARS(self);
+    ivars->doc_id = 0;
+    ivars->freq   = 0;
+    ivars->weight = 0.0;
 }
 
 void
 ScorePost_read_record(ScorePosting *self, InStream *instream) {
+    ScorePostingIVARS *const ivars = ScorePost_IVARS(self);
     uint32_t  position = 0;
     const size_t max_start_bytes = (C32_MAX_BYTES * 2) + 1;
     char *buf = InStream_Buf(instream, max_start_bytes);
@@ -130,26 +138,26 @@ ScorePost_read_record(ScorePosting *self, InStream *instream) {
     const uint32_t doc_delta = doc_code >> 1;
 
     // Apply delta doc and retrieve freq.
-    self->doc_id   += doc_delta;
+    ivars->doc_id   += doc_delta;
     if (doc_code & 1) {
-        self->freq = 1;
+        ivars->freq = 1;
     }
     else {
-        self->freq = NumUtil_decode_c32(&buf);
+        ivars->freq = NumUtil_decode_c32(&buf);
     }
 
     // Decode boost/norm byte.
-    self->weight = self->norm_decoder[*(uint8_t*)buf];
+    ivars->weight = ivars->norm_decoder[*(uint8_t*)buf];
     buf++;
 
     // Read positions.
-    uint32_t num_prox = self->freq;
-    if (num_prox > self->prox_cap) {
-        self->prox = (uint32_t*)REALLOCATE(
-                         self->prox, num_prox * sizeof(uint32_t));
-        self->prox_cap = num_prox;
+    uint32_t num_prox = ivars->freq;
+    if (num_prox > ivars->prox_cap) {
+        ivars->prox = (uint32_t*)REALLOCATE(
+                         ivars->prox, num_prox * sizeof(uint32_t));
+        ivars->prox_cap = num_prox;
     }
-    uint32_t *positions = self->prox;
+    uint32_t *positions = ivars->prox;
 
     InStream_Advance_Buf(instream, buf);
     buf = InStream_Buf(instream, num_prox * C32_MAX_BYTES);
@@ -173,12 +181,14 @@ ScorePost_read_raw(ScorePosting *self, InStream *instream,
     const uint32_t freq           = (doc_code & 1)
                                     ? 1
                                     : InStream_Read_C32(instream);
-    size_t raw_post_bytes         = MAX_RAW_POSTING_LEN(text_size, freq);
+    const size_t base_size        = VTable_Get_Obj_Alloc_Size(RAWPOSTING);
+    size_t raw_post_bytes         = MAX_RAW_POSTING_LEN(base_size, text_size, freq);
     void *const allocation        = MemPool_Grab(mem_pool, raw_post_bytes);
     RawPosting *const raw_posting
         = RawPost_new(allocation, doc_id, freq, text_buf, text_size);
+    RawPostingIVARS *const raw_post_ivars = RawPost_IVARS(raw_posting);
     uint32_t num_prox = freq;
-    char *const start = raw_posting->blob + text_size;
+    char *const start = raw_post_ivars->blob + text_size;
     char *dest        = start;
     UNUSED_VAR(self);
 
@@ -192,7 +202,7 @@ ScorePost_read_raw(ScorePosting *self, InStream *instream,
     }
 
     // Resize raw posting memory allocation.
-    raw_posting->aux_len = dest - start;
+    raw_post_ivars->aux_len = dest - start;
     raw_post_bytes       = dest - (char*)raw_posting;
     MemPool_Resize(mem_pool, raw_posting, raw_post_bytes);
 
@@ -215,11 +225,12 @@ ScorePostMatcher_init(ScorePostingMatcher *self, Similarity *sim,
                       PostingList *plist, Compiler *compiler) {
     // Init.
     TermMatcher_init((TermMatcher*)self, sim, plist, compiler);
+    ScorePostingMatcherIVARS *const ivars = ScorePostMatcher_IVARS(self);
 
     // Fill score cache.
-    self->score_cache = (float*)MALLOCATE(TERMMATCHER_SCORE_CACHE_SIZE * sizeof(float));
+    ivars->score_cache = (float*)MALLOCATE(TERMMATCHER_SCORE_CACHE_SIZE * sizeof(float));
     for (uint32_t i = 0; i < TERMMATCHER_SCORE_CACHE_SIZE; i++) {
-        self->score_cache[i] = Sim_TF(sim, (float)i) * self->weight;
+        ivars->score_cache[i] = Sim_TF(sim, (float)i) * ivars->weight;
     }
 
     return self;
@@ -227,23 +238,26 @@ ScorePostMatcher_init(ScorePostingMatcher *self, Similarity *sim,
 
 float
 ScorePostMatcher_score(ScorePostingMatcher* self) {
-    ScorePosting *const posting = (ScorePosting*)self->posting;
-    const uint32_t freq = posting->freq;
+    ScorePostingMatcherIVARS *const ivars = ScorePostMatcher_IVARS(self);
+    ScorePostingIVARS *const posting_ivars
+        = ScorePost_IVARS((ScorePosting*)ivars->posting);
+    const uint32_t freq = posting_ivars->freq;
 
     // Calculate initial score based on frequency of term.
     float score = (freq < TERMMATCHER_SCORE_CACHE_SIZE)
-                  ? self->score_cache[freq] // cache hit
-                  : Sim_TF(self->sim, (float)freq) * self->weight;
+                  ? ivars->score_cache[freq] // cache hit
+                  : Sim_TF(ivars->sim, (float)freq) * ivars->weight;
 
     // Factor in field-length normalization and doc/field/prox boost.
-    score *= posting->weight;
+    score *= posting_ivars->weight;
 
     return score;
 }
 
 void
 ScorePostMatcher_destroy(ScorePostingMatcher *self) {
-    FREEMEM(self->score_cache);
+    ScorePostingMatcherIVARS *const ivars = ScorePostMatcher_IVARS(self);
+    FREEMEM(ivars->score_cache);
     SUPER_DESTROY(self, SCOREPOSTINGMATCHER);
 }
 


[lucy-commits] [06/34] git commit: refs/heads/master - Migrate Lucy's object classes to IVARS.

Posted by ma...@apache.org.
Migrate Lucy's object classes to IVARS.

Change BitVector and I32Array to access instance vars via an IVARS
struct rather than via `self`.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/474e8b4f
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/474e8b4f
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/474e8b4f

Branch: refs/heads/master
Commit: 474e8b4f132e215c39e833a29e96f59b67929bb3
Parents: 9bff835
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Fri Jun 28 13:29:40 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 15:50:07 2013 -0700

----------------------------------------------------------------------
 core/Lucy/Object/BitVector.c | 172 +++++++++++++++++++++-----------------
 core/Lucy/Object/I32Array.c  |  24 +++---
 2 files changed, 111 insertions(+), 85 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/474e8b4f/core/Lucy/Object/BitVector.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Object/BitVector.c b/core/Lucy/Object/BitVector.c
index 7366a4c..c6940b3 100644
--- a/core/Lucy/Object/BitVector.c
+++ b/core/Lucy/Object/BitVector.c
@@ -56,29 +56,33 @@ BitVec_new(uint32_t capacity) {
 
 BitVector*
 BitVec_init(BitVector *self, uint32_t capacity) {
+    BitVectorIVARS *const ivars = BitVec_IVARS(self);
     const uint32_t byte_size = (uint32_t)ceil(capacity / 8.0);
 
     // Derive.
-    self->bits = capacity
+    ivars->bits = capacity
                  ? (uint8_t*)CALLOCATE(byte_size, sizeof(uint8_t))
                  : NULL;
 
     // Assign.
-    self->cap = byte_size * 8;
+    ivars->cap = byte_size * 8;
 
     return self;
 }
 
 void
 BitVec_destroy(BitVector* self) {
-    FREEMEM(self->bits);
+    BitVectorIVARS *const ivars = BitVec_IVARS(self);
+    FREEMEM(ivars->bits);
     SUPER_DESTROY(self, BITVECTOR);
 }
 
 BitVector*
 BitVec_clone(BitVector *self) {
-    BitVector *twin = BitVec_new(self->cap);
-    uint32_t   byte_size = (uint32_t)ceil(self->cap / 8.0);
+    BitVectorIVARS *const ivars = BitVec_IVARS(self);
+    BitVector *other = BitVec_new(ivars->cap);
+    uint32_t   byte_size = (uint32_t)ceil(ivars->cap / 8.0);
+    BitVectorIVARS *const ovars = BitVec_IVARS(other);
 
     // Forbid inheritance.
     if (BitVec_Get_VTable(self) != BITVECTOR) {
@@ -86,78 +90,85 @@ BitVec_clone(BitVector *self) {
               BitVec_Get_Class_Name(self));
     }
 
-    memcpy(twin->bits, self->bits, byte_size * sizeof(uint8_t));
+    memcpy(ovars->bits, ivars->bits, byte_size * sizeof(uint8_t));
 
-    return twin;
+    return other;
 }
 
 uint8_t*
 BitVec_get_raw_bits(BitVector *self) {
-    return self->bits;
+    return BitVec_IVARS(self)->bits;
 }
 
 uint32_t
 BitVec_get_capacity(BitVector *self) {
-    return self->cap;
+    return BitVec_IVARS(self)->cap;
 }
 
 void
 BitVec_mimic(BitVector *self, Obj *other) {
-    BitVector *twin = (BitVector*)CERTIFY(other, BITVECTOR);
-    const uint32_t my_byte_size = (uint32_t)ceil(self->cap / 8.0);
-    const uint32_t twin_byte_size = (uint32_t)ceil(twin->cap / 8.0);
-    if (my_byte_size > twin_byte_size) {
-        uint32_t space = my_byte_size - twin_byte_size;
-        memset(self->bits + twin_byte_size, 0, space);
+    CERTIFY(other, BITVECTOR);
+    BitVectorIVARS *const ivars = BitVec_IVARS(self);
+    BitVectorIVARS *const ovars = BitVec_IVARS((BitVector*)other);
+    const uint32_t my_byte_size = (uint32_t)ceil(ivars->cap / 8.0);
+    const uint32_t other_byte_size = (uint32_t)ceil(ovars->cap / 8.0);
+    if (my_byte_size > other_byte_size) {
+        uint32_t space = my_byte_size - other_byte_size;
+        memset(ivars->bits + other_byte_size, 0, space);
     }
-    else if (my_byte_size < twin_byte_size) {
-        BitVec_Grow(self, twin->cap - 1);
+    else if (my_byte_size < other_byte_size) {
+        BitVec_Grow(self, ovars->cap - 1);
     }
-    memcpy(self->bits, twin->bits, twin_byte_size);
+    memcpy(ivars->bits, ovars->bits, other_byte_size);
 }
 
 void
 BitVec_grow(BitVector *self, uint32_t capacity) {
-    if (capacity > self->cap) {
-        const size_t old_byte_cap  = (size_t)ceil(self->cap / 8.0);
+    BitVectorIVARS *const ivars = BitVec_IVARS(self);
+    if (capacity > ivars->cap) {
+        const size_t old_byte_cap  = (size_t)ceil(ivars->cap / 8.0);
         const size_t new_byte_cap  = (size_t)ceil((capacity + 1) / 8.0);
         const size_t num_new_bytes = new_byte_cap - old_byte_cap;
 
-        self->bits = (uint8_t*)REALLOCATE(self->bits, new_byte_cap);
-        memset(self->bits + old_byte_cap, 0, num_new_bytes);
-        self->cap = new_byte_cap * 8;
+        ivars->bits = (uint8_t*)REALLOCATE(ivars->bits, new_byte_cap);
+        memset(ivars->bits + old_byte_cap, 0, num_new_bytes);
+        ivars->cap = new_byte_cap * 8;
     }
 }
 
 void
 BitVec_set(BitVector *self, uint32_t tick) {
-    if (tick >= self->cap) {
+    BitVectorIVARS *const ivars = BitVec_IVARS(self);
+    if (tick >= ivars->cap) {
         uint32_t new_cap = (uint32_t)Memory_oversize(tick + 1, 0);
         BitVec_Grow(self, new_cap);
     }
-    NumUtil_u1set(self->bits, tick);
+    NumUtil_u1set(ivars->bits, tick);
 }
 
 void
 BitVec_clear(BitVector *self, uint32_t tick) {
-    if (tick >= self->cap) {
+    BitVectorIVARS *const ivars = BitVec_IVARS(self);
+    if (tick >= ivars->cap) {
         return;
     }
-    NumUtil_u1clear(self->bits, tick);
+    NumUtil_u1clear(ivars->bits, tick);
 }
 
 void
 BitVec_clear_all(BitVector *self) {
-    const size_t byte_size = (size_t)ceil(self->cap / 8.0);
-    memset(self->bits, 0, byte_size);
+    BitVectorIVARS *const ivars = BitVec_IVARS(self);
+    const size_t byte_size = (size_t)ceil(ivars->cap / 8.0);
+    memset(ivars->bits, 0, byte_size);
 }
 
 bool
 BitVec_get(BitVector *self, uint32_t tick) {
-    if (tick >= self->cap) {
+    BitVectorIVARS *const ivars = BitVec_IVARS(self);
+    if (tick >= ivars->cap) {
         return false;
     }
-    return NumUtil_u1get(self->bits, tick);
+    return NumUtil_u1get(ivars->bits, tick);
 }
 
 static int32_t
@@ -171,31 +182,32 @@ S_first_bit_in_nonzero_byte(uint8_t num) {
 
 int32_t
 BitVec_next_hit(BitVector *self, uint32_t tick) {
-    size_t byte_size = (size_t)ceil(self->cap / 8.0);
-    uint8_t *const limit = self->bits + byte_size;
-    uint8_t *ptr = self->bits + (tick >> 3);
+    BitVectorIVARS *const ivars = BitVec_IVARS(self);
+    size_t byte_size = (size_t)ceil(ivars->cap / 8.0);
+    uint8_t *const limit = ivars->bits + byte_size;
+    uint8_t *ptr = ivars->bits + (tick >> 3);
 
     if (ptr >= limit) {
         return -1;
     }
     else if (*ptr != 0) {
         // Special case the first byte.
-        const int32_t base = (ptr - self->bits) * 8;
+        const int32_t base = (ptr - ivars->bits) * 8;
         const int32_t min_sub_tick = tick & 0x7;
         unsigned int byte = *ptr >> min_sub_tick;
         if (byte) {
             const int32_t candidate 
                 = base + min_sub_tick + S_first_bit_in_nonzero_byte(byte);
-            return candidate < (int32_t)self->cap ? candidate : -1;
+            return candidate < (int32_t)ivars->cap ? candidate : -1;
         }
     }
 
     for (ptr++ ; ptr < limit; ptr++) {
         if (*ptr != 0) {
             // There's a non-zero bit in this byte.
-            const int32_t base = (ptr - self->bits) * 8;
+            const int32_t base = (ptr - ivars->bits) * 8;
             const int32_t candidate = base + S_first_bit_in_nonzero_byte(*ptr);
-            return candidate < (int32_t)self->cap ? candidate : -1;
+            return candidate < (int32_t)ivars->cap ? candidate : -1;
         }
     }
 
@@ -204,11 +216,13 @@ BitVec_next_hit(BitVector *self, uint32_t tick) {
 
 void
 BitVec_and(BitVector *self, const BitVector *other) {
-    uint8_t *bits_a = self->bits;
-    uint8_t *bits_b = other->bits;
-    const uint32_t min_cap = self->cap < other->cap
-                             ? self->cap
-                             : other->cap;
+    BitVectorIVARS *const ivars = BitVec_IVARS(self);
+    const BitVectorIVARS *const ovars = BitVec_IVARS((BitVector*)other);
+    uint8_t *bits_a = ivars->bits;
+    uint8_t *bits_b = ovars->bits;
+    const uint32_t min_cap = ivars->cap < ovars->cap
+                             ? ivars->cap
+                             : ovars->cap;
     const size_t byte_size = (size_t)ceil(min_cap / 8.0);
     uint8_t *const limit = bits_a + byte_size;
 
@@ -219,8 +233,8 @@ BitVec_and(BitVector *self, const BitVector *other) {
     }
 
     // Set all remaining to zero.
-    if (self->cap > min_cap) {
-        const size_t self_byte_size = (size_t)ceil(self->cap / 8.0);
+    if (ivars->cap > min_cap) {
+        const size_t self_byte_size = (size_t)ceil(ivars->cap / 8.0);
         memset(bits_a, 0, self_byte_size - byte_size);
     }
 }
@@ -237,27 +251,29 @@ BitVec_xor(BitVector *self, const BitVector *other) {
 
 static void
 S_do_or_or_xor(BitVector *self, const BitVector *other, int operation) {
+    BitVectorIVARS *const ivars = BitVec_IVARS(self);
+    const BitVectorIVARS *const ovars = BitVec_IVARS((BitVector*)other);
     uint8_t *bits_a, *bits_b;
     uint32_t max_cap, min_cap;
     uint8_t *limit;
     double byte_size;
 
     // Sort out what the minimum and maximum caps are.
-    if (self->cap < other->cap) {
-        max_cap = other->cap;
-        min_cap = self->cap;
+    if (ivars->cap < ovars->cap) {
+        max_cap = ovars->cap;
+        min_cap = ivars->cap;
     }
     else {
-        max_cap = self->cap;
-        min_cap = other->cap;
+        max_cap = ivars->cap;
+        min_cap = ovars->cap;
     }
 
     // Grow self if smaller than other, then calc pointers.
-    if (max_cap > self->cap) { BitVec_Grow(self, max_cap); }
-    bits_a        = self->bits;
-    bits_b        = other->bits;
+    if (max_cap > ivars->cap) { BitVec_Grow(self, max_cap); }
+    bits_a        = ivars->bits;
+    bits_b        = ovars->bits;
     byte_size     = ceil(min_cap / 8.0);
-    limit         = self->bits + (size_t)byte_size;
+    limit         = ivars->bits + (size_t)byte_size;
 
     // Perform union of common bits.
     if (operation == DO_OR) {
@@ -277,8 +293,8 @@ S_do_or_or_xor(BitVector *self, const BitVector *other, int operation) {
     }
 
     // Copy remaining bits if other is bigger than self.
-    if (other->cap > min_cap) {
-        const double other_byte_size = ceil(other->cap / 8.0);
+    if (ovars->cap > min_cap) {
+        const double other_byte_size = ceil(ovars->cap / 8.0);
         const size_t bytes_to_copy = (size_t)(other_byte_size - byte_size);
         memcpy(bits_a, bits_b, bytes_to_copy);
     }
@@ -286,11 +302,13 @@ S_do_or_or_xor(BitVector *self, const BitVector *other, int operation) {
 
 void
 BitVec_and_not(BitVector *self, const BitVector *other) {
-    uint8_t *bits_a = self->bits;
-    uint8_t *bits_b = other->bits;
-    const uint32_t min_cap = self->cap < other->cap
-                             ? self->cap
-                             : other->cap;
+    BitVectorIVARS *const ivars = BitVec_IVARS(self);
+    const BitVectorIVARS *const ovars = BitVec_IVARS((BitVector*)other);
+    uint8_t *bits_a = ivars->bits;
+    uint8_t *bits_b = ovars->bits;
+    const uint32_t min_cap = ivars->cap < ovars->cap
+                             ? ivars->cap
+                             : ovars->cap;
     const size_t byte_size = (size_t)ceil(min_cap / 8.0);
     uint8_t *const limit = bits_a + byte_size;
 
@@ -303,47 +321,49 @@ BitVec_and_not(BitVector *self, const BitVector *other) {
 
 void
 BitVec_flip(BitVector *self, uint32_t tick) {
-    if (tick >= self->cap) {
+    BitVectorIVARS *const ivars = BitVec_IVARS(self);
+    if (tick >= ivars->cap) {
         uint32_t new_cap = (uint32_t)Memory_oversize(tick + 1, 0);
         BitVec_Grow(self, new_cap);
     }
-    NumUtil_u1flip(self->bits, tick);
+    NumUtil_u1flip(ivars->bits, tick);
 }
 
 void
 BitVec_flip_block(BitVector *self, uint32_t offset, uint32_t length) {
+    BitVectorIVARS *const ivars = BitVec_IVARS(self);
     uint32_t first = offset;
     uint32_t last  = offset + length - 1;
 
     // Bail if there's nothing to flip.
     if (!length) { return; }
 
-    if (last >= self->cap) { BitVec_Grow(self, last + 1); }
+    if (last >= ivars->cap) { BitVec_Grow(self, last + 1); }
 
     // Flip partial bytes.
     while (last % 8 != 0 && last > first) {
-        NumUtil_u1flip(self->bits, last);
+        NumUtil_u1flip(ivars->bits, last);
         last--;
     }
     while (first % 8 != 0 && first < last) {
-        NumUtil_u1flip(self->bits, first);
+        NumUtil_u1flip(ivars->bits, first);
         first++;
     }
 
     // Are first and last equal?
     if (first == last) {
         // There's only one bit left to flip.
-        NumUtil_u1flip(self->bits, last);
+        NumUtil_u1flip(ivars->bits, last);
     }
     // They must be multiples of 8, then.
     else {
         const uint32_t start_tick = first >> 3;
         const uint32_t limit_tick = last  >> 3;
-        uint8_t *bits  = self->bits + start_tick;
-        uint8_t *limit = self->bits + limit_tick;
+        uint8_t *bits  = ivars->bits + start_tick;
+        uint8_t *limit = ivars->bits + limit_tick;
 
         // Last actually belongs to the following byte (e.g. 8, in byte 2).
-        NumUtil_u1flip(self->bits, last);
+        NumUtil_u1flip(ivars->bits, last);
 
         // Flip whole bytes.
         for (; bits < limit; bits++) {
@@ -354,9 +374,10 @@ BitVec_flip_block(BitVector *self, uint32_t offset, uint32_t length) {
 
 uint32_t
 BitVec_count(BitVector *self) {
+    BitVectorIVARS *const ivars = BitVec_IVARS(self);
     uint32_t count = 0;
-    const size_t byte_size = (size_t)ceil(self->cap / 8.0);
-    uint8_t *ptr = self->bits;
+    const size_t byte_size = (size_t)ceil(ivars->cap / 8.0);
+    uint8_t *ptr = ivars->bits;
     uint8_t *const limit = ptr + byte_size;
 
     for (; ptr < limit; ptr++) {
@@ -368,12 +389,13 @@ BitVec_count(BitVector *self) {
 
 I32Array*
 BitVec_to_array(BitVector *self) {
+    BitVectorIVARS *const ivars = BitVec_IVARS(self);
     uint32_t        count     = BitVec_Count(self);
     uint32_t        num_left  = count;
-    const uint32_t  capacity  = self->cap;
+    const uint32_t  capacity  = ivars->cap;
     uint32_t *const array     = (uint32_t*)CALLOCATE(count, sizeof(uint32_t));
-    const size_t    byte_size = (size_t)ceil(self->cap / 8.0);
-    uint8_t *const  bits      = self->bits;
+    const size_t    byte_size = (size_t)ceil(ivars->cap / 8.0);
+    uint8_t *const  bits      = ivars->bits;
     uint8_t *const  limit     = bits + byte_size;
     uint32_t        num       = 0;
     uint32_t        i         = 0;

http://git-wip-us.apache.org/repos/asf/lucy/blob/474e8b4f/core/Lucy/Object/I32Array.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Object/I32Array.c b/core/Lucy/Object/I32Array.c
index 57609a1..84ed55e 100644
--- a/core/Lucy/Object/I32Array.c
+++ b/core/Lucy/Object/I32Array.c
@@ -42,36 +42,40 @@ I32Arr_new_steal(int32_t *ints, uint32_t size) {
 
 I32Array*
 I32Arr_init(I32Array *self, int32_t *ints, uint32_t size) {
-    self->ints = ints;
-    self->size = size;
+    I32ArrayIVARS *const ivars = I32Arr_IVARS(self);
+    ivars->ints = ints;
+    ivars->size = size;
     return self;
 }
 
 void
 I32Arr_destroy(I32Array *self) {
-    FREEMEM(self->ints);
+    I32ArrayIVARS *const ivars = I32Arr_IVARS(self);
+    FREEMEM(ivars->ints);
     SUPER_DESTROY(self, I32ARRAY);
 }
 
 void
 I32Arr_set(I32Array *self, uint32_t tick, int32_t value) {
-    if (tick >= self->size) {
-        THROW(ERR, "Out of bounds: %u32 >= %u32", tick, self->size);
+    I32ArrayIVARS *const ivars = I32Arr_IVARS(self);
+    if (tick >= ivars->size) {
+        THROW(ERR, "Out of bounds: %u32 >= %u32", tick, ivars->size);
     }
-    self->ints[tick] = value;
+    ivars->ints[tick] = value;
 }
 
 int32_t
 I32Arr_get(I32Array *self, uint32_t tick) {
-    if (tick >= self->size) {
-        THROW(ERR, "Out of bounds: %u32 >= %u32", tick, self->size);
+    I32ArrayIVARS *const ivars = I32Arr_IVARS(self);
+    if (tick >= ivars->size) {
+        THROW(ERR, "Out of bounds: %u32 >= %u32", tick, ivars->size);
     }
-    return self->ints[tick];
+    return ivars->ints[tick];
 }
 
 uint32_t
 I32Arr_get_size(I32Array *self) {
-    return self->size;
+    return I32Arr_IVARS(self)->size;
 }
 
 


[lucy-commits] [34/34] git commit: refs/heads/master - Access IVARS struct using global offset.

Posted by ma...@apache.org.
Access IVARS struct using global offset.

Instead of performing a simple cast to convert the object struct pointer
to an IVARS struct pointer, add a global offset variable.  For now, the
offset is always 0.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/6450cc02
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/6450cc02
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/6450cc02

Branch: refs/heads/master
Commit: 6450cc02bb9bb72f95d682ee2d22ba443b4e07cc
Parents: a266a93
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Thu Jul 11 17:29:50 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 16:08:44 2013 -0700

----------------------------------------------------------------------
 clownfish/compiler/src/CFCBindClass.c | 53 ++++++++++++++++++++----------
 1 file changed, 35 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/6450cc02/clownfish/compiler/src/CFCBindClass.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCBindClass.c b/clownfish/compiler/src/CFCBindClass.c
index e63b9d4..a431d26 100644
--- a/clownfish/compiler/src/CFCBindClass.c
+++ b/clownfish/compiler/src/CFCBindClass.c
@@ -152,28 +152,37 @@ S_to_c_header_inert(CFCBindClass *self) {
 }
 
 static char*
-S_ivars_hack(CFCBindClass *self) {
-    const char *full_struct = CFCClass_full_struct_sym(self->client);
-    const char *full_ivars  = CFCClass_full_ivars_struct(self->client);
-    const char *short_ivars = CFCClass_short_ivars_struct(self->client);
-    const char *prefix      = CFCClass_get_prefix(self->client);
-    const char *PREFIX      = CFCClass_get_PREFIX(self->client);
-    const char *class_cnick = CFCClass_get_cnick(self->client);
+S_ivars_func(CFCBindClass *self) {
+    CFCClass *client = self->client;
+    const char *full_type    = CFCClass_full_struct_sym(client);
+    const char *full_func    = CFCClass_full_ivars_func(client);
+    const char *short_func   = CFCClass_short_ivars_func(client);
+    const char *full_struct  = CFCClass_full_ivars_struct(client);
+    const char *short_struct = CFCClass_short_ivars_struct(client);
+    const char *full_offset  = CFCClass_full_ivars_offset(client);
+    const char *PREFIX       = CFCClass_get_PREFIX(client);
     char pattern[] =
+        "extern size_t %s;\n"
         "typedef struct %s %s;\n"
         "static CHY_INLINE %s*\n"
-        "%s%s_IVARS(%s *self) {\n"
-        "   return (%s*)self;\n"
+        "%s(%s *self) {\n"
+        "   char *ptr = (char*)self + %s;\n"
+        "   return (%s*)ptr;\n"
         "}\n"
         "#ifdef %sUSE_SHORT_NAMES\n"
         "  #define %s %s\n"
-        "  #define %s_IVARS %s%s_IVARS\n"
+        "  #define %s %s\n"
         "#endif\n";
-    char *content
-        = CFCUtil_sprintf(pattern, full_ivars, full_ivars, full_ivars, prefix,
-                          class_cnick, full_struct, full_ivars, PREFIX,
-                          short_ivars, full_ivars, class_cnick, prefix,
-                          class_cnick);
+    char *content = CFCUtil_sprintf(pattern,
+                                    full_offset,
+                                    full_struct, full_struct,
+                                    full_struct,
+                                    full_func, full_type,
+                                    full_offset,
+                                    full_struct,
+                                    PREFIX,
+                                    short_struct, full_struct,
+                                    short_func, full_func);
     return content;
 }
 
@@ -183,7 +192,7 @@ S_to_c_header_dynamic(CFCBindClass *self) {
     const char *vt_var          = CFCClass_full_vtable_var(self->client);
     const char *prefix          = CFCClass_get_prefix(self->client);
     const char *PREFIX          = CFCClass_get_PREFIX(self->client);
-    char *ivars                 = S_ivars_hack(self);
+    char *ivars                 = S_ivars_func(self);
     char *struct_def            = S_struct_definition(self);
     char *parent_include        = S_parent_include(self);
     char *sub_declarations      = S_sub_declarations(self);
@@ -265,6 +274,8 @@ CFCBindClass_to_c_data(CFCBindClass *self) {
         return CFCUtil_strdup(CFCClass_get_autocode(client));
     }
 
+    const char *ivars_offset = CFCClass_full_ivars_offset(client);
+
     const char *autocode  = CFCClass_get_autocode(client);
     const char *vt_var    = CFCClass_full_vtable_var(client);
 
@@ -321,6 +332,12 @@ CFCBindClass_to_c_data(CFCBindClass *self) {
     }
 
     const char pattern[] =
+        "/* Offset from the top of the object at which the IVARS struct\n"
+        " * can be found.\n"
+        " */\n"
+        "\n"
+        "size_t %s;\n"
+        "\n"
         "/* Offsets for method pointers, measured in bytes, from the top\n"
         " * of this class's vtable.\n"
         " */\n"
@@ -348,8 +365,8 @@ CFCBindClass_to_c_data(CFCBindClass *self) {
         "\n"
         "%s\n"
         "\n";
-    char *code = CFCUtil_sprintf(pattern, offsets, method_defs, ms_var, vt_var,
-                                 autocode);
+    char *code = CFCUtil_sprintf(pattern, ivars_offset, offsets, method_defs,
+                                 ms_var, vt_var, autocode);
 
     FREEMEM(fresh_methods);
     FREEMEM(offsets);


[lucy-commits] [07/34] git commit: refs/heads/master - Migrate Lucy's highlight classes to IVARS.

Posted by ma...@apache.org.
Migrate Lucy's highlight classes to IVARS.

Change all Lucy's highlight classes to access instance vars
via an IVARS struct rather than via `self`.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/458824ce
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/458824ce
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/458824ce

Branch: refs/heads/master
Commit: 458824ce4f5335dd6cfbd3c76a6d46f64a7755f5
Parents: 6827b4f
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Fri Jun 28 11:00:32 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 15:50:07 2013 -0700

----------------------------------------------------------------------
 core/Lucy/Highlight/HeatMap.c     |  17 +++--
 core/Lucy/Highlight/Highlighter.c | 123 ++++++++++++++++++---------------
 2 files changed, 76 insertions(+), 64 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/458824ce/core/Lucy/Highlight/HeatMap.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Highlight/HeatMap.c b/core/Lucy/Highlight/HeatMap.c
index 0d976e9..114bbbe 100644
--- a/core/Lucy/Highlight/HeatMap.c
+++ b/core/Lucy/Highlight/HeatMap.c
@@ -29,17 +29,18 @@ HeatMap_new(VArray *spans, uint32_t window) {
 
 HeatMap*
 HeatMap_init(HeatMap *self, VArray *spans, uint32_t window) {
+    HeatMapIVARS *const ivars = HeatMap_IVARS(self);
     VArray *spans_copy = VA_Shallow_Copy(spans);
     VArray *spans_plus_boosts;
 
-    self->spans  = NULL;
-    self->window = window;
+    ivars->spans  = NULL;
+    ivars->window = window;
 
     VA_Sort(spans_copy, NULL, NULL);
     spans_plus_boosts = HeatMap_Generate_Proximity_Boosts(self, spans_copy);
     VA_Push_VArray(spans_plus_boosts, spans_copy);
     VA_Sort(spans_plus_boosts, NULL, NULL);
-    self->spans = HeatMap_Flatten_Spans(self, spans_plus_boosts);
+    ivars->spans = HeatMap_Flatten_Spans(self, spans_plus_boosts);
 
     DECREF(spans_plus_boosts);
     DECREF(spans_copy);
@@ -49,7 +50,8 @@ HeatMap_init(HeatMap *self, VArray *spans, uint32_t window) {
 
 void
 HeatMap_destroy(HeatMap *self) {
-    DECREF(self->spans);
+    HeatMapIVARS *const ivars = HeatMap_IVARS(self);
+    DECREF(ivars->spans);
     SUPER_DESTROY(self, HEATMAP);
 }
 
@@ -155,6 +157,7 @@ HeatMap_flatten_spans(HeatMap *self, VArray *spans) {
 
 float
 HeatMap_calc_proximity_boost(HeatMap *self, Span *span1, Span *span2) {
+    HeatMapIVARS *const ivars = HeatMap_IVARS(self);
     int32_t comparison = Span_Compare_To(span1, (Obj*)span2);
     Span *lower = comparison <= 0 ? span1 : span2;
     Span *upper = comparison >= 0 ? span1 : span2;
@@ -164,11 +167,11 @@ HeatMap_calc_proximity_boost(HeatMap *self, Span *span1, Span *span2) {
     // If spans overlap, set distance to 0.
     if (distance < 0) { distance = 0; }
 
-    if (distance > (int32_t)self->window) {
+    if (distance > (int32_t)ivars->window) {
         return 0.0f;
     }
     else {
-        float factor = (self->window - distance) / (float)self->window;
+        float factor = (ivars->window - distance) / (float)ivars->window;
         // Damp boost with greater distance.
         factor *= factor;
         return factor * (Span_Get_Weight(lower) + Span_Get_Weight(upper));
@@ -208,7 +211,7 @@ HeatMap_generate_proximity_boosts(HeatMap *self, VArray *spans) {
 
 VArray*
 HeatMap_get_spans(HeatMap *self) {
-    return self->spans;
+    return HeatMap_IVARS(self)->spans;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/458824ce/core/Lucy/Highlight/Highlighter.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Highlight/Highlighter.c b/core/Lucy/Highlight/Highlighter.c
index 85afe29..1e43b21 100644
--- a/core/Lucy/Highlight/Highlighter.c
+++ b/core/Lucy/Highlight/Highlighter.c
@@ -53,97 +53,103 @@ Highlighter_new(Searcher *searcher, Obj *query, const CharBuf *field,
 Highlighter*
 Highlighter_init(Highlighter *self, Searcher *searcher, Obj *query,
                  const CharBuf *field, uint32_t excerpt_length) {
-    self->query          = Searcher_Glean_Query(searcher, query);
-    self->searcher       = (Searcher*)INCREF(searcher);
-    self->field          = CB_Clone(field);
-    self->excerpt_length = excerpt_length;
-    self->slop           = excerpt_length / 3;
-    self->window_width   = excerpt_length + (self->slop * 2);
-    self->pre_tag        = CB_new_from_trusted_utf8("<strong>", 8);
-    self->post_tag       = CB_new_from_trusted_utf8("</strong>", 9);
-    if (Query_Is_A(self->query, COMPILER)) {
-        self->compiler = (Compiler*)INCREF(self->query);
+    HighlighterIVARS *const ivars = Highlighter_IVARS(self);
+    ivars->query          = Searcher_Glean_Query(searcher, query);
+    ivars->searcher       = (Searcher*)INCREF(searcher);
+    ivars->field          = CB_Clone(field);
+    ivars->excerpt_length = excerpt_length;
+    ivars->slop           = excerpt_length / 3;
+    ivars->window_width   = excerpt_length + (ivars->slop * 2);
+    ivars->pre_tag        = CB_new_from_trusted_utf8("<strong>", 8);
+    ivars->post_tag       = CB_new_from_trusted_utf8("</strong>", 9);
+    if (Query_Is_A(ivars->query, COMPILER)) {
+        ivars->compiler = (Compiler*)INCREF(ivars->query);
     }
     else {
-        self->compiler = Query_Make_Compiler(self->query, searcher,
-                                             Query_Get_Boost(self->query),
-                                             false);
+        ivars->compiler = Query_Make_Compiler(ivars->query, searcher,
+                                              Query_Get_Boost(ivars->query),
+                                              false);
     }
     return self;
 }
 
 void
 Highlighter_destroy(Highlighter *self) {
-    DECREF(self->searcher);
-    DECREF(self->query);
-    DECREF(self->compiler);
-    DECREF(self->field);
-    DECREF(self->pre_tag);
-    DECREF(self->post_tag);
+    HighlighterIVARS *const ivars = Highlighter_IVARS(self);
+    DECREF(ivars->searcher);
+    DECREF(ivars->query);
+    DECREF(ivars->compiler);
+    DECREF(ivars->field);
+    DECREF(ivars->pre_tag);
+    DECREF(ivars->post_tag);
     SUPER_DESTROY(self, HIGHLIGHTER);
 }
 
 CharBuf*
 Highlighter_highlight(Highlighter *self, const CharBuf *text) {
-    size_t   size   = CB_Get_Size(text)
-                      + CB_Get_Size(self->pre_tag)
-                      + CB_Get_Size(self->post_tag);
+    HighlighterIVARS *const ivars = Highlighter_IVARS(self);
+    size_t size = CB_Get_Size(text)
+                  + CB_Get_Size(ivars->pre_tag)
+                  + CB_Get_Size(ivars->post_tag);
     CharBuf *retval = CB_new(size);
-    CB_Cat(retval, self->pre_tag);
+    CB_Cat(retval, ivars->pre_tag);
     CB_Cat(retval, text);
-    CB_Cat(retval, self->post_tag);
+    CB_Cat(retval, ivars->post_tag);
     return retval;
 }
 
 void
 Highlighter_set_pre_tag(Highlighter *self, const CharBuf *pre_tag) {
-    CB_Mimic(self->pre_tag, (Obj*)pre_tag);
+    HighlighterIVARS *const ivars = Highlighter_IVARS(self);
+    CB_Mimic(ivars->pre_tag, (Obj*)pre_tag);
 }
 
 void
 Highlighter_set_post_tag(Highlighter *self, const CharBuf *post_tag) {
-    CB_Mimic(self->post_tag, (Obj*)post_tag);
+    HighlighterIVARS *const ivars = Highlighter_IVARS(self);
+    CB_Mimic(ivars->post_tag, (Obj*)post_tag);
 }
 
 CharBuf*
 Highlighter_get_pre_tag(Highlighter *self) {
-    return self->pre_tag;
+    return Highlighter_IVARS(self)->pre_tag;
 }
 
 CharBuf*
 Highlighter_get_post_tag(Highlighter *self) {
-    return self->post_tag;
+    return Highlighter_IVARS(self)->post_tag;
 }
 
 CharBuf*
 Highlighter_get_field(Highlighter *self) {
-    return self->field;
+    return Highlighter_IVARS(self)->field;
 }
 
 Query*
 Highlighter_get_query(Highlighter *self) {
-    return self->query;
+    return Highlighter_IVARS(self)->query;
 }
 
 Searcher*
 Highlighter_get_searcher(Highlighter *self) {
-    return self->searcher;
+    return Highlighter_IVARS(self)->searcher;
 }
 
 Compiler*
 Highlighter_get_compiler(Highlighter *self) {
-    return self->compiler;
+    return Highlighter_IVARS(self)->compiler;
 }
 
 uint32_t
 Highlighter_get_excerpt_length(Highlighter *self) {
-    return self->excerpt_length;
+    return Highlighter_IVARS(self)->excerpt_length;
 }
 
 CharBuf*
 Highlighter_create_excerpt(Highlighter *self, HitDoc *hit_doc) {
+    HighlighterIVARS *const ivars = Highlighter_IVARS(self);
     ZombieCharBuf *field_val
-        = (ZombieCharBuf*)HitDoc_Extract(hit_doc, self->field,
+        = (ZombieCharBuf*)HitDoc_Extract(hit_doc, ivars->field,
                                          (ViewCharBuf*)ZCB_BLANK());
 
     if (!field_val || !Obj_Is_A((Obj*)field_val, CHARBUF)) {
@@ -155,24 +161,24 @@ Highlighter_create_excerpt(Highlighter *self, HitDoc *hit_doc) {
     }
     else {
         ZombieCharBuf *fragment = ZCB_WRAP((CharBuf*)field_val);
-        CharBuf *raw_excerpt = CB_new(self->excerpt_length + 10);
-        CharBuf *highlighted = CB_new((self->excerpt_length * 3) / 2);
+        CharBuf *raw_excerpt = CB_new(ivars->excerpt_length + 10);
+        CharBuf *highlighted = CB_new((ivars->excerpt_length * 3) / 2);
         DocVector *doc_vec
-            = Searcher_Fetch_Doc_Vec(self->searcher,
+            = Searcher_Fetch_Doc_Vec(ivars->searcher,
                                      HitDoc_Get_Doc_ID(hit_doc));
         VArray *maybe_spans
-            = Compiler_Highlight_Spans(self->compiler, self->searcher,
-                                       doc_vec, self->field);
+            = Compiler_Highlight_Spans(ivars->compiler, ivars->searcher,
+                                       doc_vec, ivars->field);
         VArray *score_spans = maybe_spans ? maybe_spans : VA_new(0);
         VA_Sort(score_spans, NULL, NULL);
         HeatMap *heat_map
-            = HeatMap_new(score_spans, (self->excerpt_length * 2) / 3);
+            = HeatMap_new(score_spans, (ivars->excerpt_length * 2) / 3);
         int32_t top
             = Highlighter_Find_Best_Fragment(self, (CharBuf*)field_val,
                                              (ViewCharBuf*)fragment, heat_map);
         VArray *sentences
             = Highlighter_Find_Sentences(self, (CharBuf*)field_val, 0,
-                                         top + self->window_width);
+                                         top + ivars->window_width);
 
         top = Highlighter_Raw_Excerpt(self, (CharBuf*)field_val,
                                       (CharBuf*)fragment, raw_excerpt, top,
@@ -208,32 +214,34 @@ S_hottest(HeatMap *heat_map) {
 int32_t
 Highlighter_find_best_fragment(Highlighter *self, const CharBuf *field_val,
                                ViewCharBuf *fragment, HeatMap *heat_map) {
+    HighlighterIVARS *const ivars = Highlighter_IVARS(self);
+
     // Window is 1.66 * excerpt_length, with the loc in the middle.
     int32_t best_location = S_hottest(heat_map);
 
-    if (best_location < (int32_t)self->slop) {
+    if (best_location < (int32_t)ivars->slop) {
         // If the beginning of the string falls within the window centered
         // around the hottest point in the field, start the fragment at the
         // beginning.
         ViewCB_Assign(fragment, (CharBuf*)field_val);
         int32_t top = ViewCB_Trim_Top(fragment);
-        ViewCB_Truncate(fragment, self->window_width);
+        ViewCB_Truncate(fragment, ivars->window_width);
         return top;
     }
     else {
-        int32_t top = best_location - self->slop;
+        int32_t top = best_location - ivars->slop;
         ViewCB_Assign(fragment, (CharBuf*)field_val);
         ViewCB_Nip(fragment, top);
         top += ViewCB_Trim_Top(fragment);
-        int32_t chars_left = ViewCB_Truncate(fragment, self->excerpt_length);
-        int32_t overrun = self->excerpt_length - chars_left;
+        int32_t chars_left = ViewCB_Truncate(fragment, ivars->excerpt_length);
+        int32_t overrun = ivars->excerpt_length - chars_left;
 
         if (!overrun) {
             // We've found an acceptable window.
             ViewCB_Assign(fragment, (CharBuf*)field_val);
             ViewCB_Nip(fragment, top);
             top += ViewCB_Trim_Top(fragment);
-            ViewCB_Truncate(fragment, self->window_width);
+            ViewCB_Truncate(fragment, ivars->window_width);
             return top;
         }
         else if (overrun > top) {
@@ -248,7 +256,7 @@ Highlighter_find_best_fragment(Highlighter *self, const CharBuf *field_val,
             ViewCB_Assign(fragment, (CharBuf*)field_val);
             ViewCB_Nip(fragment, top);
             top += ViewCB_Trim_Top(fragment);
-            ViewCB_Truncate(fragment, self->excerpt_length);
+            ViewCB_Truncate(fragment, ivars->excerpt_length);
             return top;
         }
     }
@@ -283,14 +291,15 @@ int32_t
 Highlighter_raw_excerpt(Highlighter *self, const CharBuf *field_val,
                         const CharBuf *fragment, CharBuf *raw_excerpt,
                         int32_t top, HeatMap *heat_map, VArray *sentences) {
+    HighlighterIVARS *const ivars = Highlighter_IVARS(self);
     bool     found_starting_edge = false;
     bool     found_ending_edge   = false;
     int32_t  start = top;
     int32_t  end   = 0;
     double   field_len = CB_Length(field_val);
-    uint32_t min_len = field_len < self->excerpt_length * 0.6666
+    uint32_t min_len = field_len < ivars->excerpt_length * 0.6666
                        ? (uint32_t)field_len
-                       : (uint32_t)(self->excerpt_length * 0.6666);
+                       : (uint32_t)(ivars->excerpt_length * 0.6666);
 
     // Try to find a starting sentence boundary.
     const uint32_t num_sentences = VA_Get_Size(sentences);
@@ -299,7 +308,7 @@ Highlighter_raw_excerpt(Highlighter *self, const CharBuf *field_val,
             Span *sentence = (Span*)VA_Fetch(sentences, i);
             int32_t candidate = Span_Get_Offset(sentence);;
 
-            if (candidate > top + (int32_t)self->window_width) {
+            if (candidate > top + (int32_t)ivars->window_width) {
                 break;
             }
             else if (candidate >= top) {
@@ -308,7 +317,7 @@ Highlighter_raw_excerpt(Highlighter *self, const CharBuf *field_val,
                 // fragment.
                 ZombieCharBuf *temp = ZCB_WRAP(fragment);
                 ZCB_Nip(temp, candidate - top);
-                uint32_t chars_left = ZCB_Truncate(temp, self->excerpt_length);
+                uint32_t chars_left = ZCB_Truncate(temp, ivars->excerpt_length);
                 if (chars_left >= min_len
                     && S_has_heat(heat_map, candidate, chars_left)
                    ) {
@@ -333,7 +342,7 @@ Highlighter_raw_excerpt(Highlighter *self, const CharBuf *field_val,
             if (last_edge <= start) {
                 break;
             }
-            else if (last_edge - start > (int32_t)self->excerpt_length) {
+            else if (last_edge - start > (int32_t)ivars->excerpt_length) {
                 continue;
             }
             else {
@@ -361,7 +370,7 @@ Highlighter_raw_excerpt(Highlighter *self, const CharBuf *field_val,
     }
     int32_t this_excerpt_len = found_ending_edge
                                ? end - start
-                               : (int32_t)self->excerpt_length;
+                               : (int32_t)ivars->excerpt_length;
     if (!this_excerpt_len) { return start; }
 
     if (found_starting_edge) {
@@ -403,7 +412,7 @@ Highlighter_raw_excerpt(Highlighter *self, const CharBuf *field_val,
                     // we don't know a solid end point yet.
                     break;
                 }
-                else if (this_excerpt_len <= (int32_t)self->excerpt_length) {
+                else if (this_excerpt_len <= (int32_t)ivars->excerpt_length) {
                     break;
                 }
             }
@@ -415,7 +424,7 @@ Highlighter_raw_excerpt(Highlighter *self, const CharBuf *field_val,
             temp             = orig_temp;
             start            = orig_start;
             this_excerpt_len = orig_len;
-            int32_t diff = this_excerpt_len - self->excerpt_length;
+            int32_t diff = this_excerpt_len - ivars->excerpt_length;
             if (diff > 0) {
                 ZCB_Nip(temp, diff);
                 start            += diff;
@@ -423,7 +432,7 @@ Highlighter_raw_excerpt(Highlighter *self, const CharBuf *field_val,
             }
         }
 
-        ZCB_Truncate(temp, self->excerpt_length - ELLIPSIS_LEN);
+        ZCB_Truncate(temp, ivars->excerpt_length - ELLIPSIS_LEN);
         CB_Cat_Char(raw_excerpt, ELLIPSIS_CODE_POINT);
         CB_Cat_Char(raw_excerpt, ' ');
         CB_Cat(raw_excerpt, (CharBuf*)temp);


[lucy-commits] [26/34] git commit: refs/heads/master - Use Token accessors within HighlightWriter.

Posted by ma...@apache.org.
Use Token accessors within HighlightWriter.

Use accessors rather than direct struct access when reading Tokens
within HighlightWriter.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/6346d10b
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/6346d10b
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/6346d10b

Branch: refs/heads/master
Commit: 6346d10be88d44d038009bf64544c83587c60911
Parents: e894b7c
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Thu Jul 11 16:04:35 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 16:08:43 2013 -0700

----------------------------------------------------------------------
 core/Lucy/Index/HighlightWriter.c | 30 ++++++++++++++----------------
 1 file changed, 14 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/6346d10b/core/Lucy/Index/HighlightWriter.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/HighlightWriter.c b/core/Lucy/Index/HighlightWriter.c
index d1ce83a..60154df 100644
--- a/core/Lucy/Index/HighlightWriter.c
+++ b/core/Lucy/Index/HighlightWriter.c
@@ -16,7 +16,6 @@
 
 #define C_LUCY_HIGHLIGHTWRITER
 #define C_LUCY_DEFAULTHIGHLIGHTWRITER
-#define C_LUCY_TOKEN
 #include "Lucy/Util/ToolSet.h"
 
 #include <stdio.h>
@@ -155,16 +154,18 @@ HLWriter_tv_buf(HighlightWriter *self, Inversion *inversion) {
     Inversion_Reset(inversion);
     while ((tokens = Inversion_Next_Cluster(inversion, &freq)) != NULL) {
         Token *token = *tokens;
-        TokenIVARS *token_ivars = Token_IVARS(token);
-        int32_t overlap = StrHelp_overlap(last_text, token_ivars->text,
-                                          last_len, token_ivars->len);
+        char *const   token_text = Token_Get_Text(token);
+        const int32_t token_len  = Token_Get_Len(token);
+
+        int32_t overlap = StrHelp_overlap(last_text, token_text,
+                                          last_len, token_len);
         char *ptr;
         char *orig;
         size_t old_size = BB_Get_Size(tv_buf);
         size_t new_size = old_size
                           + C32_MAX_BYTES      // overlap
                           + C32_MAX_BYTES      // length of string diff
-                          + (token_ivars->len - overlap) // diff char data
+                          + (token_len - overlap)        // diff char data
                           + C32_MAX_BYTES                // num prox
                           + (C32_MAX_BYTES * freq * 3);  // pos data
 
@@ -178,25 +179,22 @@ HLWriter_tv_buf(HighlightWriter *self, Inversion *inversion) {
 
         // Append the string diff to the tv_buf.
         NumUtil_encode_c32(overlap, &ptr);
-        NumUtil_encode_c32((token_ivars->len - overlap), &ptr);
-        memcpy(ptr, (token_ivars->text + overlap),
-               (token_ivars->len - overlap));
-        ptr += token_ivars->len - overlap;
+        NumUtil_encode_c32((token_len - overlap), &ptr);
+        memcpy(ptr, (token_text + overlap), (token_len - overlap));
+        ptr += token_len - overlap;
 
         // Save text and text_len for comparison next loop.
-        last_text = token_ivars->text;
-        last_len  = token_ivars->len;
+        last_text = token_text;
+        last_len  = token_len;
 
         // Append the number of positions for this term.
         NumUtil_encode_c32(freq, &ptr);
 
         do {
-            token_ivars = Token_IVARS(token);
             // Add position, start_offset, and end_offset to tv_buf.
-            NumUtil_encode_c32(token_ivars->pos, &ptr);
-            NumUtil_encode_c32(token_ivars->start_offset, &ptr);
-            NumUtil_encode_c32(token_ivars->end_offset, &ptr);
-
+            NumUtil_encode_c32(Token_Get_Pos(token), &ptr);
+            NumUtil_encode_c32(Token_Get_Start_Offset(token), &ptr);
+            NumUtil_encode_c32(Token_Get_End_Offset(token), &ptr);
         } while (--freq && (token = *++tokens));
 
         // Set new byte length.


[lucy-commits] [23/34] git commit: refs/heads/master - Migrate Lucy unit tests to IVARS.

Posted by ma...@apache.org.
Migrate Lucy unit tests to IVARS.

Change all unit tests to access instance vars via an IVARS struct rather than
via `self`.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/3a3bf226
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/3a3bf226
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/3a3bf226

Branch: refs/heads/master
Commit: 3a3bf226b81d2e6c984c0e0137667949ef9e2c09
Parents: 5d0cc09
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Thu Jul 11 15:12:59 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 16:08:43 2013 -0700

----------------------------------------------------------------------
 core/Lucy/Test/Search/TestQueryParser.c       | 24 ++++----
 core/Lucy/Test/Search/TestQueryParserLogic.c  | 15 +++--
 core/Lucy/Test/Search/TestQueryParserSyntax.c | 32 +++++-----
 core/Lucy/Test/Search/TestSortSpec.c          |  9 +--
 core/Lucy/Test/Store/MockFileHandle.c         |  5 +-
 core/Lucy/Test/Store/TestFSFileHandle.c       | 15 ++---
 core/Lucy/Test/Store/TestIOChunks.c           |  9 +--
 core/Lucy/Test/Store/TestInStream.c           | 43 +++++++------
 core/Lucy/Test/Store/TestRAMFileHandle.c      |  9 +--
 core/Lucy/Test/TestSchema.c                   |  4 +-
 core/Lucy/Test/Util/BBSortEx.c                | 72 ++++++++++++----------
 core/Lucy/Test/Util/TestMemoryPool.c          | 10 +--
 12 files changed, 138 insertions(+), 109 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/3a3bf226/core/Lucy/Test/Search/TestQueryParser.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Test/Search/TestQueryParser.c b/core/Lucy/Test/Search/TestQueryParser.c
index eef20e3..8129c74 100644
--- a/core/Lucy/Test/Search/TestQueryParser.c
+++ b/core/Lucy/Test/Search/TestQueryParser.c
@@ -40,39 +40,41 @@ TestQP_new(const char *query_string, Query *tree, Query *expanded,
 TestQueryParser*
 TestQP_init(TestQueryParser *self, const char *query_string, Query *tree,
             Query *expanded, uint32_t num_hits) {
-    self->query_string = query_string ? TestUtils_get_cb(query_string) : NULL;
-    self->tree         = tree     ? tree     : NULL;
-    self->expanded     = expanded ? expanded : NULL;
-    self->num_hits     = num_hits;
+    TestQueryParserIVARS *const ivars = TestQP_IVARS(self);
+    ivars->query_string = query_string ? TestUtils_get_cb(query_string) : NULL;
+    ivars->tree         = tree     ? tree     : NULL;
+    ivars->expanded     = expanded ? expanded : NULL;
+    ivars->num_hits     = num_hits;
     return self;
 }
 
 void
 TestQP_destroy(TestQueryParser *self) {
-    DECREF(self->query_string);
-    DECREF(self->tree);
-    DECREF(self->expanded);
+    TestQueryParserIVARS *const ivars = TestQP_IVARS(self);
+    DECREF(ivars->query_string);
+    DECREF(ivars->tree);
+    DECREF(ivars->expanded);
     SUPER_DESTROY(self, TESTQUERYPARSER);
 }
 
 CharBuf*
 TestQP_get_query_string(TestQueryParser *self) {
-    return self->query_string;
+    return TestQP_IVARS(self)->query_string;
 }
 
 Query*
 TestQP_get_tree(TestQueryParser *self) {
-    return self->tree;
+    return TestQP_IVARS(self)->tree;
 }
 
 Query*
 TestQP_get_expanded(TestQueryParser *self) {
-    return self->expanded;
+    return TestQP_IVARS(self)->expanded;
 }
 
 uint32_t
 TestQP_get_num_hits(TestQueryParser *self) {
-    return self->num_hits;
+    return TestQP_IVARS(self)->num_hits;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/3a3bf226/core/Lucy/Test/Search/TestQueryParserLogic.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Test/Search/TestQueryParserLogic.c b/core/Lucy/Test/Search/TestQueryParserLogic.c
index 57049e5..22a86c1 100644
--- a/core/Lucy/Test/Search/TestQueryParserLogic.c
+++ b/core/Lucy/Test/Search/TestQueryParserLogic.c
@@ -899,7 +899,8 @@ TestQPLogic_run(TestQueryParserLogic *self, TestBatchRunner *runner) {
     // Run logical tests with default boolop of OR.
     for (i = 0; logical_test_funcs[i] != NULL; i++) {
         Lucy_TestQPLogic_Logical_Test_t test_func = logical_test_funcs[i];
-        TestQueryParser *test_case = test_func(BOOLOP_OR);
+        TestQueryParser *test_case_obj = test_func(BOOLOP_OR);
+        TestQueryParserIVARS *test_case = TestQP_IVARS(test_case_obj);
         Query *tree     = QParser_Tree(or_parser, test_case->query_string);
         Query *parsed   = QParser_Parse(or_parser, test_case->query_string);
         Hits  *hits     = IxSearcher_Hits(searcher, (Obj*)parsed, 0, 10, NULL);
@@ -911,13 +912,14 @@ TestQPLogic_run(TestQueryParserLogic *self, TestBatchRunner *runner) {
         DECREF(hits);
         DECREF(parsed);
         DECREF(tree);
-        DECREF(test_case);
+        DECREF(test_case_obj);
     }
 
     // Run logical tests with default boolop of AND.
     for (i = 0; logical_test_funcs[i] != NULL; i++) {
         Lucy_TestQPLogic_Logical_Test_t test_func = logical_test_funcs[i];
-        TestQueryParser *test_case = test_func(BOOLOP_AND);
+        TestQueryParser *test_case_obj = test_func(BOOLOP_AND);
+        TestQueryParserIVARS *test_case = TestQP_IVARS(test_case_obj);
         Query *tree     = QParser_Tree(and_parser, test_case->query_string);
         Query *parsed   = QParser_Parse(and_parser, test_case->query_string);
         Hits  *hits     = IxSearcher_Hits(searcher, (Obj*)parsed, 0, 10, NULL);
@@ -929,13 +931,14 @@ TestQPLogic_run(TestQueryParserLogic *self, TestBatchRunner *runner) {
         DECREF(hits);
         DECREF(parsed);
         DECREF(tree);
-        DECREF(test_case);
+        DECREF(test_case_obj);
     }
 
     // Run tests for QParser_Prune().
     for (i = 0; prune_test_funcs[i] != NULL; i++) {
         Lucy_TestQPLogic_Prune_Test_t test_func = prune_test_funcs[i];
-        TestQueryParser *test_case = test_func();
+        TestQueryParser *test_case_obj = test_func();
+        TestQueryParserIVARS *test_case = TestQP_IVARS(test_case_obj);
         CharBuf *qstring = test_case->tree
                            ? Query_To_String(test_case->tree)
                            : CB_new_from_trusted_utf8("(NULL)", 6);
@@ -956,7 +959,7 @@ TestQPLogic_run(TestQueryParserLogic *self, TestBatchRunner *runner) {
         DECREF(expanded);
         DECREF(pruned);
         DECREF(qstring);
-        DECREF(test_case);
+        DECREF(test_case_obj);
     }
 
     DECREF(and_parser);

http://git-wip-us.apache.org/repos/asf/lucy/blob/3a3bf226/core/Lucy/Test/Search/TestQueryParserSyntax.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Test/Search/TestQueryParserSyntax.c b/core/Lucy/Test/Search/TestQueryParserSyntax.c
index b0baf15..47dff21 100644
--- a/core/Lucy/Test/Search/TestQueryParserSyntax.c
+++ b/core/Lucy/Test/Search/TestQueryParserSyntax.c
@@ -398,17 +398,18 @@ test_query_parser_syntax(TestBatchRunner *runner) {
     for (uint32_t i = 0; leaf_test_funcs[i] != NULL; i++) {
         Lucy_TestQPSyntax_Test_t test_func = leaf_test_funcs[i];
         TestQueryParser *test_case = test_func();
-        Query *tree     = QParser_Tree(qparser, test_case->query_string);
-        Query *expanded = QParser_Expand_Leaf(qparser, test_case->tree);
-        Query *parsed   = QParser_Parse(qparser, test_case->query_string);
+        TestQueryParserIVARS *ivars = TestQP_IVARS(test_case);
+        Query *tree     = QParser_Tree(qparser, ivars->query_string);
+        Query *expanded = QParser_Expand_Leaf(qparser, ivars->tree);
+        Query *parsed   = QParser_Parse(qparser, ivars->query_string);
         Hits  *hits     = IxSearcher_Hits(searcher, (Obj*)parsed, 0, 10, NULL);
 
-        TEST_TRUE(runner, Query_Equals(tree, (Obj*)test_case->tree),
-                  "tree()    %s", (char*)CB_Get_Ptr8(test_case->query_string));
-        TEST_TRUE(runner, Query_Equals(expanded, (Obj*)test_case->expanded),
-                  "expand_leaf()    %s", (char*)CB_Get_Ptr8(test_case->query_string));
-        TEST_INT_EQ(runner, Hits_Total_Hits(hits), test_case->num_hits,
-                    "hits:    %s", (char*)CB_Get_Ptr8(test_case->query_string));
+        TEST_TRUE(runner, Query_Equals(tree, (Obj*)ivars->tree),
+                  "tree()    %s", (char*)CB_Get_Ptr8(ivars->query_string));
+        TEST_TRUE(runner, Query_Equals(expanded, (Obj*)ivars->expanded),
+                  "expand_leaf()    %s", (char*)CB_Get_Ptr8(ivars->query_string));
+        TEST_INT_EQ(runner, Hits_Total_Hits(hits), ivars->num_hits,
+                    "hits:    %s", (char*)CB_Get_Ptr8(ivars->query_string));
         DECREF(hits);
         DECREF(parsed);
         DECREF(expanded);
@@ -419,14 +420,15 @@ test_query_parser_syntax(TestBatchRunner *runner) {
     for (uint32_t i = 0; syntax_test_funcs[i] != NULL; i++) {
         Lucy_TestQPSyntax_Test_t test_func = syntax_test_funcs[i];
         TestQueryParser *test_case = test_func();
-        Query *tree   = QParser_Tree(qparser, test_case->query_string);
-        Query *parsed = QParser_Parse(qparser, test_case->query_string);
+        TestQueryParserIVARS *ivars = TestQP_IVARS(test_case);
+        Query *tree   = QParser_Tree(qparser, ivars->query_string);
+        Query *parsed = QParser_Parse(qparser, ivars->query_string);
         Hits  *hits   = IxSearcher_Hits(searcher, (Obj*)parsed, 0, 10, NULL);
 
-        TEST_TRUE(runner, Query_Equals(tree, (Obj*)test_case->tree),
-                  "tree()    %s", (char*)CB_Get_Ptr8(test_case->query_string));
-        TEST_INT_EQ(runner, Hits_Total_Hits(hits), test_case->num_hits,
-                    "hits:    %s", (char*)CB_Get_Ptr8(test_case->query_string));
+        TEST_TRUE(runner, Query_Equals(tree, (Obj*)ivars->tree),
+                  "tree()    %s", (char*)CB_Get_Ptr8(ivars->query_string));
+        TEST_INT_EQ(runner, Hits_Total_Hits(hits), ivars->num_hits,
+                    "hits:    %s", (char*)CB_Get_Ptr8(ivars->query_string));
         DECREF(hits);
         DECREF(parsed);
         DECREF(tree);

http://git-wip-us.apache.org/repos/asf/lucy/blob/3a3bf226/core/Lucy/Test/Search/TestSortSpec.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Test/Search/TestSortSpec.c b/core/Lucy/Test/Search/TestSortSpec.c
index 841e9ba..990ac9d 100644
--- a/core/Lucy/Test/Search/TestSortSpec.c
+++ b/core/Lucy/Test/Search/TestSortSpec.c
@@ -154,10 +154,11 @@ TestReverseType*
 TestReverseType_init2(TestReverseType *self, float boost, bool indexed,
                       bool stored, bool sortable) {
     FType_init((FieldType*)self);
-    self->boost      = boost;
-    self->indexed    = indexed;
-    self->stored     = stored;
-    self->sortable   = sortable;
+    TestReverseTypeIVARS *const ivars = TestReverseType_IVARS(self);
+    ivars->boost      = boost;
+    ivars->indexed    = indexed;
+    ivars->stored     = stored;
+    ivars->sortable   = sortable;
     return self;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/3a3bf226/core/Lucy/Test/Store/MockFileHandle.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Test/Store/MockFileHandle.c b/core/Lucy/Test/Store/MockFileHandle.c
index 3e3ba04..d4a203d 100644
--- a/core/Lucy/Test/Store/MockFileHandle.c
+++ b/core/Lucy/Test/Store/MockFileHandle.c
@@ -32,7 +32,8 @@ MockFileHandle*
 MockFileHandle_init(MockFileHandle *self, const CharBuf *path,
                     int64_t length) {
     FH_do_open((FileHandle*)self, path, 0);
-    self->len = length;
+    MockFileHandleIVARS *const ivars = MockFileHandle_IVARS(self);
+    ivars->len = length;
     return self;
 }
 
@@ -53,7 +54,7 @@ MockFileHandle_release_window(MockFileHandle *self, FileWindow *window) {
 
 int64_t
 MockFileHandle_length(MockFileHandle *self) {
-    return self->len;
+    return MockFileHandle_IVARS(self)->len;
 }
 
 bool

http://git-wip-us.apache.org/repos/asf/lucy/blob/3a3bf226/core/Lucy/Test/Store/TestFSFileHandle.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Test/Store/TestFSFileHandle.c b/core/Lucy/Test/Store/TestFSFileHandle.c
index d9ab78e..fe4f5fd 100644
--- a/core/Lucy/Test/Store/TestFSFileHandle.c
+++ b/core/Lucy/Test/Store/TestFSFileHandle.c
@@ -180,14 +180,14 @@ test_Close(TestBatchRunner *runner) {
     SKIP(runner, "LUCY-155");
     SKIP(runner, "LUCY-155");
 #else
-    int saved_fd = fh->fd;
-    fh->fd = -1;
+    int saved_fd = FSFH_IVARS(fh)->fd;
+    FSFH_IVARS(fh)->fd = -1;
     Err_set_error(NULL);
     bool result = FSFH_Close(fh);
     TEST_FALSE(runner, result, "Failed Close() returns false");
     TEST_TRUE(runner, Err_get_error() != NULL,
               "Failed Close() sets Err_error");
-    fh->fd = saved_fd;
+    FSFH_IVARS(fh)->fd = saved_fd;
 #endif /* _MSC_VER */
     DECREF(fh);
 
@@ -203,6 +203,7 @@ test_Window(TestBatchRunner *runner) {
     CharBuf *test_filename = (CharBuf*)ZCB_WRAP_STR("_fstest", 7);
     FSFileHandle *fh;
     FileWindow *window = FileWindow_new();
+    FileWindowIVARS *const window_ivars = FileWindow_IVARS(window);
     uint32_t i;
 
     remove((char*)CB_Get_Ptr8(test_filename));
@@ -233,14 +234,14 @@ test_Window(TestBatchRunner *runner) {
     TEST_TRUE(runner, FSFH_Window(fh, window, 1021, 2),
               "Window() returns true");
     TEST_TRUE(runner,
-              strncmp(window->buf - window->offset + 1021, "oo", 2) == 0,
+              strncmp(window_ivars->buf - window_ivars->offset + 1021, "oo", 2) == 0,
               "Window()");
 
     TEST_TRUE(runner, FSFH_Release_Window(fh, window),
               "Release_Window() returns true");
-    TEST_TRUE(runner, window->buf == NULL, "Release_Window() resets buf");
-    TEST_TRUE(runner, window->offset == 0, "Release_Window() resets offset");
-    TEST_TRUE(runner, window->len == 0, "Release_Window() resets len");
+    TEST_TRUE(runner, window_ivars->buf == NULL, "Release_Window() resets buf");
+    TEST_TRUE(runner, window_ivars->offset == 0, "Release_Window() resets offset");
+    TEST_TRUE(runner, window_ivars->len == 0, "Release_Window() resets len");
 
     DECREF(window);
     DECREF(fh);

http://git-wip-us.apache.org/repos/asf/lucy/blob/3a3bf226/core/Lucy/Test/Store/TestIOChunks.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Test/Store/TestIOChunks.c b/core/Lucy/Test/Store/TestIOChunks.c
index fe2fc61..7381b7e 100644
--- a/core/Lucy/Test/Store/TestIOChunks.c
+++ b/core/Lucy/Test/Store/TestIOChunks.c
@@ -86,24 +86,25 @@ test_Buf(TestBatchRunner *runner) {
     OutStream_Close(outstream);
 
     instream = InStream_open((Obj*)file);
+    InStreamIVARS *const ivars = InStream_IVARS(instream);
     buf = InStream_Buf(instream, 5);
-    TEST_INT_EQ(runner, instream->limit - buf, IO_STREAM_BUF_SIZE,
+    TEST_INT_EQ(runner, ivars->limit - buf, IO_STREAM_BUF_SIZE,
                 "Small request bumped up");
 
     buf += IO_STREAM_BUF_SIZE - 10; // 10 bytes left in buffer.
     InStream_Advance_Buf(instream, buf);
 
     buf = InStream_Buf(instream, 10);
-    TEST_INT_EQ(runner, instream->limit - buf, 10,
+    TEST_INT_EQ(runner, ivars->limit - buf, 10,
                 "Exact request doesn't trigger refill");
 
     buf = InStream_Buf(instream, 11);
-    TEST_INT_EQ(runner, instream->limit - buf, IO_STREAM_BUF_SIZE,
+    TEST_INT_EQ(runner, ivars->limit - buf, IO_STREAM_BUF_SIZE,
                 "Requesting over limit triggers refill");
 
     int64_t  expected = InStream_Length(instream) - InStream_Tell(instream);
     char    *buff     = InStream_Buf(instream, 100000);
-    int64_t  got      = PTR_TO_I64(instream->limit) - PTR_TO_I64(buff);
+    int64_t  got      = PTR_TO_I64(ivars->limit) - PTR_TO_I64(buff);
     TEST_TRUE(runner, got == expected,
               "Requests greater than file size get pared down");
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/3a3bf226/core/Lucy/Test/Store/TestInStream.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Test/Store/TestInStream.c b/core/Lucy/Test/Store/TestInStream.c
index a09df9f..cc5ef78 100644
--- a/core/Lucy/Test/Store/TestInStream.c
+++ b/core/Lucy/Test/Store/TestInStream.c
@@ -43,6 +43,7 @@ test_refill(TestBatchRunner *runner) {
     OutStream  *outstream = OutStream_open((Obj*)file);
     InStream   *instream;
     char        scratch[5];
+    InStreamIVARS *ivars;
 
     for (int32_t i = 0; i < 1023; i++) {
         OutStream_Write_U8(outstream, 'x');
@@ -52,36 +53,41 @@ test_refill(TestBatchRunner *runner) {
     OutStream_Close(outstream);
 
     instream = InStream_open((Obj*)file);
+    ivars = InStream_IVARS(instream);
     InStream_Refill(instream);
-    TEST_INT_EQ(runner, instream->limit - instream->buf, IO_STREAM_BUF_SIZE,
+    TEST_INT_EQ(runner, ivars->limit - ivars->buf, IO_STREAM_BUF_SIZE,
                 "Refill");
     TEST_INT_EQ(runner, (long)InStream_Tell(instream), 0,
                 "Correct file pos after standing-start Refill()");
     DECREF(instream);
 
     instream = InStream_open((Obj*)file);
+    ivars = InStream_IVARS(instream);
     InStream_Fill(instream, 30);
-    TEST_INT_EQ(runner, instream->limit - instream->buf, 30, "Fill()");
+    TEST_INT_EQ(runner, ivars->limit - ivars->buf, 30, "Fill()");
     TEST_INT_EQ(runner, (long)InStream_Tell(instream), 0,
                 "Correct file pos after standing-start Fill()");
     DECREF(instream);
 
     instream = InStream_open((Obj*)file);
+    ivars = InStream_IVARS(instream);
     InStream_Read_Bytes(instream, scratch, 5);
-    TEST_INT_EQ(runner, instream->limit - instream->buf,
+    TEST_INT_EQ(runner, ivars->limit - ivars->buf,
                 IO_STREAM_BUF_SIZE - 5, "small read triggers refill");
     DECREF(instream);
 
     instream = InStream_open((Obj*)file);
+    ivars = InStream_IVARS(instream);
     TEST_INT_EQ(runner, InStream_Read_U8(instream), 'x', "Read_U8");
     InStream_Seek(instream, 1023);
-    TEST_INT_EQ(runner, (long)instream->window->offset, 0,
+    TEST_INT_EQ(runner, (long)FileWindow_IVARS(ivars->window)->offset, 0,
                 "no unnecessary refill on Seek");
     TEST_INT_EQ(runner, (long)InStream_Tell(instream), 1023, "Seek/Tell");
     TEST_INT_EQ(runner, InStream_Read_U8(instream), 'y',
                 "correct data after in-buffer Seek()");
     TEST_INT_EQ(runner, InStream_Read_U8(instream), 'z', "automatic Refill");
-    TEST_TRUE(runner, (instream->window->offset != 0), "refilled");
+    TEST_TRUE(runner, (FileWindow_IVARS(ivars->window)->offset != 0),
+              "refilled");
 
     DECREF(instream);
     DECREF(outstream);
@@ -144,7 +150,7 @@ test_Close(TestBatchRunner *runner) {
     RAMFile  *file     = RAMFile_new(NULL, false);
     InStream *instream = InStream_open((Obj*)file);
     InStream_Close(instream);
-    TEST_TRUE(runner, instream->file_handle == NULL,
+    TEST_TRUE(runner, InStream_IVARS(instream)->file_handle == NULL,
               "Close decrements FileHandle's refcount");
     DECREF(instream);
     DECREF(file);
@@ -158,49 +164,50 @@ test_Seek_and_Tell(TestBatchRunner *runner) {
     int64_t     gb12     = gb1 * 12;
     FileHandle *fh       = (FileHandle*)MockFileHandle_new(NULL, gb12);
     InStream   *instream = InStream_open((Obj*)fh);
+    InStreamIVARS *const ivars = InStream_IVARS(instream);
 
     InStream_Buf(instream, 10000);
-    TEST_TRUE(runner, instream->limit == ((char*)NULL) + 10000,
+    TEST_TRUE(runner, ivars->limit == ((char*)NULL) + 10000,
               "InStream_Buf sets limit");
 
     InStream_Seek(instream, gb6);
     TEST_TRUE(runner, InStream_Tell(instream) == gb6,
               "Tell after seek forwards outside buffer");
-    TEST_TRUE(runner, instream->buf == NULL,
+    TEST_TRUE(runner, ivars->buf == NULL,
               "Seek forwards outside buffer sets buf to NULL");
-    TEST_TRUE(runner, instream->limit == NULL,
+    TEST_TRUE(runner, ivars->limit == NULL,
               "Seek forwards outside buffer sets limit to NULL");
-    TEST_TRUE(runner, instream->window->offset == gb6,
+    TEST_TRUE(runner, FileWindow_IVARS(ivars->window)->offset == gb6,
               "Seek forwards outside buffer tracks pos in window offset");
 
     InStream_Buf(instream, (size_t)gb1);
-    TEST_TRUE(runner, instream->limit == ((char*)NULL) + gb1,
+    TEST_TRUE(runner, ivars->limit == ((char*)NULL) + gb1,
               "InStream_Buf sets limit");
 
     InStream_Seek(instream, gb6 + 10);
     TEST_TRUE(runner, InStream_Tell(instream) == gb6 + 10,
               "Tell after seek forwards within buffer");
-    TEST_TRUE(runner, instream->buf == ((char*)NULL) + 10,
+    TEST_TRUE(runner, ivars->buf == ((char*)NULL) + 10,
               "Seek within buffer sets buf");
-    TEST_TRUE(runner, instream->limit == ((char*)NULL) + gb1,
+    TEST_TRUE(runner, ivars->limit == ((char*)NULL) + gb1,
               "Seek within buffer leaves limit alone");
 
     InStream_Seek(instream, gb6 + 1);
     TEST_TRUE(runner, InStream_Tell(instream) == gb6 + 1,
               "Tell after seek backwards within buffer");
-    TEST_TRUE(runner, instream->buf == ((char*)NULL) + 1,
+    TEST_TRUE(runner, ivars->buf == ((char*)NULL) + 1,
               "Seek backwards within buffer sets buf");
-    TEST_TRUE(runner, instream->limit == ((char*)NULL) + gb1,
+    TEST_TRUE(runner, ivars->limit == ((char*)NULL) + gb1,
               "Seek backwards within buffer leaves limit alone");
 
     InStream_Seek(instream, gb3);
     TEST_TRUE(runner, InStream_Tell(instream) == gb3,
               "Tell after seek backwards outside buffer");
-    TEST_TRUE(runner, instream->buf == NULL,
+    TEST_TRUE(runner, ivars->buf == NULL,
               "Seek backwards outside buffer sets buf to NULL");
-    TEST_TRUE(runner, instream->limit == NULL,
+    TEST_TRUE(runner, ivars->limit == NULL,
               "Seek backwards outside buffer sets limit to NULL");
-    TEST_TRUE(runner, instream->window->offset == gb3,
+    TEST_TRUE(runner, FileWindow_IVARS(ivars->window)->offset == gb3,
               "Seek backwards outside buffer tracks pos in window offset");
 
     DECREF(instream);

http://git-wip-us.apache.org/repos/asf/lucy/blob/3a3bf226/core/Lucy/Test/Store/TestRAMFileHandle.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Test/Store/TestRAMFileHandle.c b/core/Lucy/Test/Store/TestRAMFileHandle.c
index 4a4bfb5..47b0d9b 100644
--- a/core/Lucy/Test/Store/TestRAMFileHandle.c
+++ b/core/Lucy/Test/Store/TestRAMFileHandle.c
@@ -126,6 +126,7 @@ test_Window(TestBatchRunner *runner) {
     RAMFile *file = RAMFile_new(NULL, false);
     RAMFileHandle *fh = RAMFH_open(NULL, FH_WRITE_ONLY, file);
     FileWindow *window = FileWindow_new();
+    FileWindowIVARS *const window_ivars = FileWindow_IVARS(window);
 
     for (uint32_t i = 0; i < 1024; i++) {
         RAMFH_Write(fh, "foo ", 4);
@@ -150,13 +151,13 @@ test_Window(TestBatchRunner *runner) {
 
     TEST_TRUE(runner, RAMFH_Window(fh, window, 1021, 2),
               "Window() returns true");
-    TEST_TRUE(runner, strncmp(window->buf, "oo", 2) == 0, "Window()");
+    TEST_TRUE(runner, strncmp(window_ivars->buf, "oo", 2) == 0, "Window()");
 
     TEST_TRUE(runner, RAMFH_Release_Window(fh, window),
               "Release_Window() returns true");
-    TEST_TRUE(runner, window->buf == NULL, "Release_Window() resets buf");
-    TEST_TRUE(runner, window->offset == 0, "Release_Window() resets offset");
-    TEST_TRUE(runner, window->len == 0, "Release_Window() resets len");
+    TEST_TRUE(runner, window_ivars->buf == NULL, "Release_Window() resets buf");
+    TEST_TRUE(runner, window_ivars->offset == 0, "Release_Window() resets offset");
+    TEST_TRUE(runner, window_ivars->len == 0, "Release_Window() resets len");
 
     DECREF(window);
     DECREF(fh);

http://git-wip-us.apache.org/repos/asf/lucy/blob/3a3bf226/core/Lucy/Test/TestSchema.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Test/TestSchema.c b/core/Lucy/Test/TestSchema.c
index 6dcb80e..2507bfb 100644
--- a/core/Lucy/Test/TestSchema.c
+++ b/core/Lucy/Test/TestSchema.c
@@ -73,8 +73,8 @@ test_Equals(TestBatchRunner *runner) {
     TEST_FALSE(runner, TestSchema_Equals(schema, (Obj*)spec_differs),
                "Equals spoiled by differing FieldType");
 
-    DECREF(arch_differs->arch);
-    arch_differs->arch = Arch_new();
+    DECREF(TestSchema_IVARS(arch_differs)->arch);
+    TestSchema_IVARS(arch_differs)->arch = Arch_new();
     TEST_FALSE(runner, TestSchema_Equals(schema, (Obj*)arch_differs),
                "Equals spoiled by differing Architecture");
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/3a3bf226/core/Lucy/Test/Util/BBSortEx.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Test/Util/BBSortEx.c b/core/Lucy/Test/Util/BBSortEx.c
index cdff551..0e17b42 100644
--- a/core/Lucy/Test/Util/BBSortEx.c
+++ b/core/Lucy/Test/Util/BBSortEx.c
@@ -34,26 +34,29 @@ BBSortEx_new(uint32_t mem_threshold, VArray *external) {
 BBSortEx*
 BBSortEx_init(BBSortEx *self, uint32_t mem_threshold, VArray *external) {
     SortEx_init((SortExternal*)self, sizeof(Obj*));
-    self->external_tick = 0;
-    self->external = (VArray*)INCREF(external);
-    self->mem_consumed = 0;
+    BBSortExIVARS *const ivars = BBSortEx_IVARS(self);
+    ivars->external_tick = 0;
+    ivars->external = (VArray*)INCREF(external);
+    ivars->mem_consumed = 0;
     BBSortEx_Set_Mem_Thresh(self, mem_threshold);
     return self;
 }
 
 void
 BBSortEx_destroy(BBSortEx *self) {
-    DECREF(self->external);
+    BBSortExIVARS *const ivars = BBSortEx_IVARS(self);
+    DECREF(ivars->external);
     SUPER_DESTROY(self, BBSORTEX);
 }
 
 void
 BBSortEx_clear_cache(BBSortEx *self) {
-    Obj **const cache = (Obj**)self->cache;
-    for (uint32_t i = self->cache_tick, max = self->cache_max; i < max; i++) {
+    BBSortExIVARS *const ivars = BBSortEx_IVARS(self);
+    Obj **const cache = (Obj**)ivars->cache;
+    for (uint32_t i = ivars->cache_tick, max = ivars->cache_max; i < max; i++) {
         DECREF(cache[i]);
     }
-    self->mem_consumed = 0;
+    ivars->mem_consumed = 0;
     BBSortEx_Clear_Cache_t super_clear_cache
         = SUPER_METHOD_PTR(BBSORTEX, TestLucy_BBSortEx_Clear_Cache);
     super_clear_cache(self);
@@ -61,22 +64,24 @@ BBSortEx_clear_cache(BBSortEx *self) {
 
 void
 BBSortEx_feed(BBSortEx *self, void *data) {
+    BBSortExIVARS *const ivars = BBSortEx_IVARS(self);
     BBSortEx_Feed_t super_feed
         = SUPER_METHOD_PTR(BBSORTEX, TestLucy_BBSortEx_Feed);
     super_feed(self, data);
 
     // Flush() if necessary.
     ByteBuf *bytebuf = (ByteBuf*)CERTIFY(*(ByteBuf**)data, BYTEBUF);
-    self->mem_consumed += BB_Get_Size(bytebuf);
-    if (self->mem_consumed >= self->mem_thresh) {
+    ivars->mem_consumed += BB_Get_Size(bytebuf);
+    if (ivars->mem_consumed >= ivars->mem_thresh) {
         BBSortEx_Flush(self);
     }
 }
 
 void
 BBSortEx_flush(BBSortEx *self) {
-    uint32_t     cache_count = self->cache_max - self->cache_tick;
-    Obj        **cache = (Obj**)self->cache;
+    BBSortExIVARS *const ivars = BBSortEx_IVARS(self);
+    uint32_t     cache_count = ivars->cache_max - ivars->cache_tick;
+    Obj        **cache = (Obj**)ivars->cache;
     VArray      *elems;
 
     if (!cache_count) { return; }
@@ -84,7 +89,7 @@ BBSortEx_flush(BBSortEx *self) {
 
     // Sort, then create a new run.
     BBSortEx_Sort_Cache(self);
-    for (uint32_t i = self->cache_tick; i < self->cache_max; i++) {
+    for (uint32_t i = ivars->cache_tick; i < ivars->cache_max; i++) {
         VA_Push(elems, cache[i]);
     }
     BBSortEx *run = BBSortEx_new(0, elems);
@@ -92,71 +97,74 @@ BBSortEx_flush(BBSortEx *self) {
     BBSortEx_Add_Run(self, (SortExternal*)run);
 
     // Blank the cache vars.
-    self->cache_tick += cache_count;
+    ivars->cache_tick += cache_count;
     BBSortEx_Clear_Cache(self);
 }
 
 uint32_t
 BBSortEx_refill(BBSortEx *self) {
+    BBSortExIVARS *const ivars = BBSortEx_IVARS(self);
+
     // Make sure cache is empty, then set cache tick vars.
-    if (self->cache_max - self->cache_tick > 0) {
+    if (ivars->cache_max - ivars->cache_tick > 0) {
         THROW(ERR, "Refill called but cache contains %u32 items",
-              self->cache_max - self->cache_tick);
+              ivars->cache_max - ivars->cache_tick);
     }
-    self->cache_tick = 0;
-    self->cache_max  = 0;
+    ivars->cache_tick = 0;
+    ivars->cache_max  = 0;
 
     // Read in elements.
     while (1) {
         ByteBuf *elem = NULL;
 
-        if (self->mem_consumed >= self->mem_thresh) {
-            self->mem_consumed = 0;
+        if (ivars->mem_consumed >= ivars->mem_thresh) {
+            ivars->mem_consumed = 0;
             break;
         }
-        else if (self->external_tick >= VA_Get_Size(self->external)) {
+        else if (ivars->external_tick >= VA_Get_Size(ivars->external)) {
             break;
         }
         else {
-            elem = (ByteBuf*)VA_Fetch(self->external, self->external_tick);
-            self->external_tick++;
+            elem = (ByteBuf*)VA_Fetch(ivars->external, ivars->external_tick);
+            ivars->external_tick++;
             // Should be + sizeof(ByteBuf), but that's ok.
-            self->mem_consumed += BB_Get_Size(elem);
+            ivars->mem_consumed += BB_Get_Size(elem);
         }
 
-        if (self->cache_max == self->cache_cap) {
+        if (ivars->cache_max == ivars->cache_cap) {
             BBSortEx_Grow_Cache(self,
-                                Memory_oversize(self->cache_max + 1, self->width));
+                                Memory_oversize(ivars->cache_max + 1, ivars->width));
         }
-        Obj **cache = (Obj**)self->cache;
-        cache[self->cache_max++] = INCREF(elem);
+        Obj **cache = (Obj**)ivars->cache;
+        cache[ivars->cache_max++] = INCREF(elem);
     }
 
-    return self->cache_max;
+    return ivars->cache_max;
 }
 
 void
 BBSortEx_flip(BBSortEx *self) {
+    BBSortExIVARS *const ivars = BBSortEx_IVARS(self);
     uint32_t run_mem_thresh = 65536;
 
     BBSortEx_Flush(self);
 
     // Recalculate the approximate mem allowed for each run.
-    uint32_t num_runs = VA_Get_Size(self->runs);
+    uint32_t num_runs = VA_Get_Size(ivars->runs);
     if (num_runs) {
-        run_mem_thresh = (self->mem_thresh / 2) / num_runs;
+        run_mem_thresh = (ivars->mem_thresh / 2) / num_runs;
         if (run_mem_thresh < 65536) {
             run_mem_thresh = 65536;
         }
     }
 
     for (uint32_t i = 0; i < num_runs; i++) {
-        BBSortEx *run = (BBSortEx*)VA_Fetch(self->runs, i);
+        BBSortEx *run = (BBSortEx*)VA_Fetch(ivars->runs, i);
         BBSortEx_Set_Mem_Thresh(run, run_mem_thresh);
     }
 
     // OK to fetch now.
-    self->flipped = true;
+    ivars->flipped = true;
 }
 
 int

http://git-wip-us.apache.org/repos/asf/lucy/blob/3a3bf226/core/Lucy/Test/Util/TestMemoryPool.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Test/Util/TestMemoryPool.c b/core/Lucy/Test/Util/TestMemoryPool.c
index d671467..a13b577 100644
--- a/core/Lucy/Test/Util/TestMemoryPool.c
+++ b/core/Lucy/Test/Util/TestMemoryPool.c
@@ -35,6 +35,8 @@ TestMemPool_run(TestMemoryPool *self, TestBatchRunner *runner) {
 
     MemoryPool *mem_pool = MemPool_new(0);
     MemoryPool *other    = MemPool_new(0);
+    MemoryPoolIVARS *const ivars = MemPool_IVARS(mem_pool);
+    MemoryPoolIVARS *const ovars = MemPool_IVARS(other);
     char *ptr_a, *ptr_b;
 
     ptr_a = (char*)MemPool_Grab(mem_pool, 10);
@@ -44,15 +46,15 @@ TestMemPool_run(TestMemoryPool *self, TestBatchRunner *runner) {
     ptr_b = (char*)MemPool_Grab(mem_pool, 10);
     TEST_STR_EQ(runner, ptr_b, "foo", "Recycle RAM on Release_All");
 
-    ptr_a = mem_pool->buf;
+    ptr_a = ivars->buf;
     MemPool_Resize(mem_pool, ptr_b, 6);
-    TEST_TRUE(runner, mem_pool->buf < ptr_a, "Resize");
+    TEST_TRUE(runner, ivars->buf < ptr_a, "Resize");
 
     ptr_a = (char*)MemPool_Grab(other, 20);
     MemPool_Release_All(other);
     MemPool_Eat(other, mem_pool);
-    TEST_TRUE(runner, other->buf == mem_pool->buf, "Eat");
-    TEST_TRUE(runner, other->buf != NULL, "Eat");
+    TEST_TRUE(runner, ovars->buf == ivars->buf, "Eat");
+    TEST_TRUE(runner, ovars->buf != NULL, "Eat");
 
     DECREF(mem_pool);
     DECREF(other);


[lucy-commits] [28/34] git commit: refs/heads/master - Migrate more Lucy search classes to IVARS.

Posted by ma...@apache.org.
Migrate more Lucy search classes to IVARS.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/7ba2ba64
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/7ba2ba64
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/7ba2ba64

Branch: refs/heads/master
Commit: 7ba2ba64f954ca0d63ff80b407dd4187e00fe8ea
Parents: 14e863f
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Sun Jun 30 21:59:23 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 16:08:43 2013 -0700

----------------------------------------------------------------------
 core/Lucy/Search/Collector/SortCollector.c | 300 +++++++++++++-----------
 core/Lucy/Search/QueryParser/ParserElem.c  |  51 ++--
 core/Lucy/Search/QueryParser/QueryLexer.c  |  10 +-
 3 files changed, 193 insertions(+), 168 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/7ba2ba64/core/Lucy/Search/Collector/SortCollector.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/Collector/SortCollector.c b/core/Lucy/Search/Collector/SortCollector.c
index 9c4d182..7c877bf 100644
--- a/core/Lucy/Search/Collector/SortCollector.c
+++ b/core/Lucy/Search/Collector/SortCollector.c
@@ -63,7 +63,7 @@ S_derive_action(SortRule *rule, SortCache *sort_cache);
 
 // Decide whether a doc should be inserted into the HitQueue.
 static INLINE bool
-SI_competitive(SortCollector *self, int32_t doc_id);
+SI_competitive(SortCollectorIVARS *ivars, int32_t doc_id);
 
 SortCollector*
 SortColl_new(Schema *schema, SortSpec *sort_spec, uint32_t wanted) {
@@ -98,33 +98,34 @@ SortColl_init(SortCollector *self, Schema *schema, SortSpec *sort_spec,
 
     // Init.
     Coll_init((Collector*)self);
-    self->total_hits    = 0;
-    self->bubble_doc    = INT32_MAX;
-    self->bubble_score  = F32_NEGINF;
-    self->seg_doc_max   = 0;
+    SortCollectorIVARS *const ivars = SortColl_IVARS(self);
+    ivars->total_hits    = 0;
+    ivars->bubble_doc    = INT32_MAX;
+    ivars->bubble_score  = F32_NEGINF;
+    ivars->seg_doc_max   = 0;
 
     // Assign.
-    self->wanted        = wanted;
+    ivars->wanted        = wanted;
 
     // Derive.
-    self->hit_q         = HitQ_new(schema, sort_spec, wanted);
-    self->rules         = rules; // absorb refcount.
-    self->num_rules     = num_rules;
-    self->sort_caches   = (SortCache**)CALLOCATE(num_rules, sizeof(SortCache*));
-    self->ord_arrays    = (void**)CALLOCATE(num_rules, sizeof(void*));
-    self->actions       = (uint8_t*)CALLOCATE(num_rules, sizeof(uint8_t));
+    ivars->hit_q         = HitQ_new(schema, sort_spec, wanted);
+    ivars->rules         = rules; // absorb refcount.
+    ivars->num_rules     = num_rules;
+    ivars->sort_caches   = (SortCache**)CALLOCATE(num_rules, sizeof(SortCache*));
+    ivars->ord_arrays    = (void**)CALLOCATE(num_rules, sizeof(void*));
+    ivars->actions       = (uint8_t*)CALLOCATE(num_rules, sizeof(uint8_t));
 
     // Build up an array of "actions" which we will execute during each call
     // to Collect(). Determine whether we need to track scores and field
     // values.
-    self->need_score  = false;
-    self->need_values = false;
+    ivars->need_score  = false;
+    ivars->need_values = false;
     for (uint32_t i = 0; i < num_rules; i++) {
         SortRule *rule   = (SortRule*)VA_Fetch(rules, i);
         int32_t rule_type  = SortRule_Get_Type(rule);
-        self->actions[i] = S_derive_action(rule, NULL);
+        ivars->actions[i] = S_derive_action(rule, NULL);
         if (rule_type == SortRule_SCORE) {
-            self->need_score = true;
+            ivars->need_score = true;
         }
         else if (rule_type == SortRule_FIELD) {
             CharBuf *field = SortRule_Get_Field(rule);
@@ -132,30 +133,30 @@ SortColl_init(SortCollector *self, Schema *schema, SortSpec *sort_spec,
             if (!type || !FType_Sortable(type)) {
                 THROW(ERR, "'%o' isn't a sortable field", field);
             }
-            self->need_values = true;
+            ivars->need_values = true;
         }
     }
 
     // Perform an optimization.  So long as we always collect docs in
     // ascending order, Collect() will favor lower doc numbers -- so we may
     // not need to execute a final COMPARE_BY_DOC_ID action.
-    self->num_actions = num_rules;
-    if (self->actions[num_rules - 1] == COMPARE_BY_DOC_ID) {
-        self->num_actions--;
+    ivars->num_actions = num_rules;
+    if (ivars->actions[num_rules - 1] == COMPARE_BY_DOC_ID) {
+        ivars->num_actions--;
     }
 
     // Override our derived actions with an action which will be excecuted
     // autmatically until the queue fills up.
-    self->auto_actions    = (uint8_t*)MALLOCATE(1);
-    self->auto_actions[0] = wanted ? AUTO_ACCEPT : AUTO_REJECT;
-    self->derived_actions = self->actions;
-    self->actions         = self->auto_actions;
+    ivars->auto_actions    = (uint8_t*)MALLOCATE(1);
+    ivars->auto_actions[0] = wanted ? AUTO_ACCEPT : AUTO_REJECT;
+    ivars->derived_actions = ivars->actions;
+    ivars->actions         = ivars->auto_actions;
 
 
     // Prepare a MatchDoc-in-waiting.
-    VArray *values = self->need_values ? VA_new(num_rules) : NULL;
-    float   score  = self->need_score  ? F32_NEGINF : F32_NAN;
-    self->bumped = MatchDoc_new(INT32_MAX, score, values);
+    VArray *values = ivars->need_values ? VA_new(num_rules) : NULL;
+    float   score  = ivars->need_score  ? F32_NEGINF : F32_NAN;
+    ivars->bumped = MatchDoc_new(INT32_MAX, score, values);
     DECREF(values);
 
     return self;
@@ -163,13 +164,14 @@ SortColl_init(SortCollector *self, Schema *schema, SortSpec *sort_spec,
 
 void
 SortColl_destroy(SortCollector *self) {
-    DECREF(self->hit_q);
-    DECREF(self->rules);
-    DECREF(self->bumped);
-    FREEMEM(self->sort_caches);
-    FREEMEM(self->ord_arrays);
-    FREEMEM(self->auto_actions);
-    FREEMEM(self->derived_actions);
+    SortCollectorIVARS *const ivars = SortColl_IVARS(self);
+    DECREF(ivars->hit_q);
+    DECREF(ivars->rules);
+    DECREF(ivars->bumped);
+    FREEMEM(ivars->sort_caches);
+    FREEMEM(ivars->ord_arrays);
+    FREEMEM(ivars->auto_actions);
+    FREEMEM(ivars->derived_actions);
     SUPER_DESTROY(self, SORTCOLLECTOR);
 }
 
@@ -221,69 +223,75 @@ S_derive_action(SortRule *rule, SortCache *cache) {
 
 void
 SortColl_set_reader(SortCollector *self, SegReader *reader) {
+    SortCollectorIVARS *const ivars = SortColl_IVARS(self);
     SortReader *sort_reader
         = (SortReader*)SegReader_Fetch(reader, VTable_Get_Name(SORTREADER));
 
     // Reset threshold variables and trigger auto-action behavior.
-    self->bumped->doc_id = INT32_MAX;
-    self->bubble_doc     = INT32_MAX;
-    self->bumped->score  = self->need_score ? F32_NEGINF : F32_NAN;
-    self->bubble_score   = self->need_score ? F32_NEGINF : F32_NAN;
-    self->actions        = self->auto_actions;
+    MatchDocIVARS *const bumped_ivars = MatchDoc_IVARS(ivars->bumped);
+    bumped_ivars->doc_id = INT32_MAX;
+    ivars->bubble_doc    = INT32_MAX;
+    bumped_ivars->score  = ivars->need_score ? F32_NEGINF : F32_NAN;
+    ivars->bubble_score  = ivars->need_score ? F32_NEGINF : F32_NAN;
+    ivars->actions       = ivars->auto_actions;
 
     // Obtain sort caches. Derive actions array for this segment.
-    if (self->need_values && sort_reader) {
-        for (uint32_t i = 0, max = self->num_rules; i < max; i++) {
-            SortRule  *rule  = (SortRule*)VA_Fetch(self->rules, i);
+    if (ivars->need_values && sort_reader) {
+        for (uint32_t i = 0, max = ivars->num_rules; i < max; i++) {
+            SortRule  *rule  = (SortRule*)VA_Fetch(ivars->rules, i);
             CharBuf   *field = SortRule_Get_Field(rule);
             SortCache *cache = field
                                ? SortReader_Fetch_Sort_Cache(sort_reader, field)
                                : NULL;
-            self->sort_caches[i] = cache;
-            self->derived_actions[i] = S_derive_action(rule, cache);
-            if (cache) { self->ord_arrays[i] = SortCache_Get_Ords(cache); }
-            else       { self->ord_arrays[i] = NULL; }
+            ivars->sort_caches[i] = cache;
+            ivars->derived_actions[i] = S_derive_action(rule, cache);
+            if (cache) { ivars->ord_arrays[i] = SortCache_Get_Ords(cache); }
+            else       { ivars->ord_arrays[i] = NULL; }
         }
     }
-    self->seg_doc_max = reader ? SegReader_Doc_Max(reader) : 0;
+    ivars->seg_doc_max = reader ? SegReader_Doc_Max(reader) : 0;
     Coll_set_reader((Collector*)self, reader);
 }
 
 VArray*
 SortColl_pop_match_docs(SortCollector *self) {
-    return HitQ_Pop_All(self->hit_q);
+    SortCollectorIVARS *const ivars = SortColl_IVARS(self);
+    return HitQ_Pop_All(ivars->hit_q);
 }
 
 uint32_t
 SortColl_get_total_hits(SortCollector *self) {
-    return self->total_hits;
+    return SortColl_IVARS(self)->total_hits;
 }
 
 bool
 SortColl_need_score(SortCollector *self) {
-    return self->need_score;
+    return SortColl_IVARS(self)->need_score;
 }
 
 void
 SortColl_collect(SortCollector *self, int32_t doc_id) {
+    SortCollectorIVARS *const ivars = SortColl_IVARS(self);
+
     // Add to the total number of hits.
-    self->total_hits++;
+    ivars->total_hits++;
 
     // Collect this hit if it's competitive.
-    if (SI_competitive(self, doc_id)) {
-        MatchDoc *const match_doc = self->bumped;
-        match_doc->doc_id = doc_id + self->base;
+    if (SI_competitive(ivars, doc_id)) {
+        MatchDoc *const match_doc = ivars->bumped;
+        MatchDocIVARS *const match_doc_ivars = MatchDoc_IVARS(match_doc);
+        match_doc_ivars->doc_id = doc_id + ivars->base;
 
-        if (self->need_score && match_doc->score == F32_NEGINF) {
-            match_doc->score = Matcher_Score(self->matcher);
+        if (ivars->need_score && match_doc_ivars->score == F32_NEGINF) {
+            match_doc_ivars->score = Matcher_Score(ivars->matcher);
         }
 
         // Fetch values so that cross-segment sorting can work.
-        if (self->need_values) {
-            VArray *values = match_doc->values;
+        if (ivars->need_values) {
+            VArray *values = match_doc_ivars->values;
 
-            for (uint32_t i = 0, max = self->num_rules; i < max; i++) {
-                SortCache *cache   = self->sort_caches[i];
+            for (uint32_t i = 0, max = ivars->num_rules; i < max; i++) {
+                SortCache *cache   = ivars->sort_caches[i];
                 Obj       *old_val = (Obj*)VA_Delete(values, i);
                 if (cache) {
                     int32_t ord = SortCache_Ordinal(cache, doc_id);
@@ -298,29 +306,31 @@ SortColl_collect(SortCollector *self, int32_t doc_id) {
         }
 
         // Insert the new MatchDoc.
-        self->bumped = (MatchDoc*)HitQ_Jostle(self->hit_q, (Obj*)match_doc);
+        ivars->bumped = (MatchDoc*)HitQ_Jostle(ivars->hit_q, (Obj*)match_doc);
 
-        if (self->bumped) {
-            if (self->bumped == match_doc) {
+        if (ivars->bumped) {
+            if (ivars->bumped == match_doc) {
                 /* The queue is full, and we have established a threshold for
                  * this segment as to what sort of document is definitely not
                  * acceptable.  Turn off AUTO_ACCEPT and start actually
                  * testing whether hits are competitive. */
-                self->bubble_score  = match_doc->score;
-                self->bubble_doc    = doc_id;
-                self->actions       = self->derived_actions;
+                ivars->bubble_score  = match_doc_ivars->score;
+                ivars->bubble_doc    = doc_id;
+                ivars->actions       = ivars->derived_actions;
             }
 
             // Recycle.
-            self->bumped->score = self->need_score ? F32_NEGINF : F32_NAN;
+            MatchDoc_IVARS(ivars->bumped)->score = ivars->need_score
+                                                   ? F32_NEGINF
+                                                   : F32_NAN;
         }
         else {
             // The queue isn't full yet, so create a fresh MatchDoc.
-            VArray *values = self->need_values
-                             ? VA_new(self->num_rules)
+            VArray *values = ivars->need_values
+                             ? VA_new(ivars->num_rules)
                              : NULL;
-            float fake_score = self->need_score ? F32_NEGINF : F32_NAN;
-            self->bumped = MatchDoc_new(INT32_MAX, fake_score, values);
+            float fake_score = ivars->need_score ? F32_NEGINF : F32_NAN;
+            ivars->bumped = MatchDoc_new(INT32_MAX, fake_score, values);
             DECREF(values);
         }
 
@@ -328,36 +338,41 @@ SortColl_collect(SortCollector *self, int32_t doc_id) {
 }
 
 static INLINE int32_t
-SI_compare_by_ord1(SortCollector *self, uint32_t tick, int32_t a, int32_t b) {
-    void *const ords = self->ord_arrays[tick];
+SI_compare_by_ord1(SortCollectorIVARS *ivars, uint32_t tick,
+                   int32_t a, int32_t b) {
+    void *const ords = ivars->ord_arrays[tick];
     int32_t a_ord = NumUtil_u1get(ords, a);
     int32_t b_ord = NumUtil_u1get(ords, b);
     return a_ord - b_ord;
 }
 static INLINE int32_t
-SI_compare_by_ord2(SortCollector *self, uint32_t tick, int32_t a, int32_t b) {
-    void *const ords = self->ord_arrays[tick];
+SI_compare_by_ord2(SortCollectorIVARS *ivars, uint32_t tick,
+                   int32_t a, int32_t b) {
+    void *const ords = ivars->ord_arrays[tick];
     int32_t a_ord = NumUtil_u2get(ords, a);
     int32_t b_ord = NumUtil_u2get(ords, b);
     return a_ord - b_ord;
 }
 static INLINE int32_t
-SI_compare_by_ord4(SortCollector *self, uint32_t tick, int32_t a, int32_t b) {
-    void *const ords = self->ord_arrays[tick];
+SI_compare_by_ord4(SortCollectorIVARS *ivars, uint32_t tick,
+                   int32_t a, int32_t b) {
+    void *const ords = ivars->ord_arrays[tick];
     int32_t a_ord = NumUtil_u4get(ords, a);
     int32_t b_ord = NumUtil_u4get(ords, b);
     return a_ord - b_ord;
 }
 static INLINE int32_t
-SI_compare_by_ord8(SortCollector *self, uint32_t tick, int32_t a, int32_t b) {
-    uint8_t *ords = (uint8_t*)self->ord_arrays[tick];
+SI_compare_by_ord8(SortCollectorIVARS *ivars, uint32_t tick,
+                   int32_t a, int32_t b) {
+    uint8_t *ords = (uint8_t*)ivars->ord_arrays[tick];
     int32_t a_ord = ords[a];
     int32_t b_ord = ords[b];
     return a_ord - b_ord;
 }
 static INLINE int32_t
-SI_compare_by_ord16(SortCollector *self, uint32_t tick, int32_t a, int32_t b) {
-    uint8_t *ord_bytes = (uint8_t*)self->ord_arrays[tick];
+SI_compare_by_ord16(SortCollectorIVARS *ivars, uint32_t tick,
+                    int32_t a, int32_t b) {
+    uint8_t *ord_bytes = (uint8_t*)ivars->ord_arrays[tick];
     uint8_t *address_a = ord_bytes + a * sizeof(uint16_t);
     uint8_t *address_b = ord_bytes + b * sizeof(uint16_t);
     int32_t  ord_a = NumUtil_decode_bigend_u16(address_a);
@@ -365,8 +380,9 @@ SI_compare_by_ord16(SortCollector *self, uint32_t tick, int32_t a, int32_t b) {
     return ord_a - ord_b;
 }
 static INLINE int32_t
-SI_compare_by_ord32(SortCollector *self, uint32_t tick, int32_t a, int32_t b) {
-    uint8_t *ord_bytes = (uint8_t*)self->ord_arrays[tick];
+SI_compare_by_ord32(SortCollectorIVARS *ivars, uint32_t tick,
+                    int32_t a, int32_t b) {
+    uint8_t *ord_bytes = (uint8_t*)ivars->ord_arrays[tick];
     uint8_t *address_a = ord_bytes + a * sizeof(uint32_t);
     uint8_t *address_b = ord_bytes + b * sizeof(uint32_t);
     int32_t  ord_a = NumUtil_decode_bigend_u32(address_a);
@@ -374,42 +390,42 @@ SI_compare_by_ord32(SortCollector *self, uint32_t tick, int32_t a, int32_t b) {
     return ord_a - ord_b;
 }
 static INLINE int32_t
-SI_compare_by_native_ord16(SortCollector *self, uint32_t tick,
+SI_compare_by_native_ord16(SortCollectorIVARS *ivars, uint32_t tick,
                            int32_t a, int32_t b) {
-    uint16_t *ords = (uint16_t*)self->ord_arrays[tick];
+    uint16_t *ords = (uint16_t*)ivars->ord_arrays[tick];
     int32_t a_ord = ords[a];
     int32_t b_ord = ords[b];
     return a_ord - b_ord;
 }
 static INLINE int32_t
-SI_compare_by_native_ord32(SortCollector *self, uint32_t tick,
+SI_compare_by_native_ord32(SortCollectorIVARS *ivars, uint32_t tick,
                            int32_t a, int32_t b) {
-    int32_t *ords = (int32_t*)self->ord_arrays[tick];
+    int32_t *ords = (int32_t*)ivars->ord_arrays[tick];
     return ords[a] - ords[b];
 }
 
 // Bounds checking for doc id against the segment doc_max.  We assume that any
 // sort cache ord arrays can accomodate lookups up to this number.
 static INLINE int32_t
-SI_validate_doc_id(SortCollector *self, int32_t doc_id) {
+SI_validate_doc_id(SortCollectorIVARS *ivars, int32_t doc_id) {
     // Check as uint32_t since we're using these doc ids as array indexes.
-    if ((uint32_t)doc_id > (uint32_t)self->seg_doc_max) {
+    if ((uint32_t)doc_id > (uint32_t)ivars->seg_doc_max) {
         THROW(ERR, "Doc ID %i32 greater than doc max %i32", doc_id,
-              self->seg_doc_max);
+              ivars->seg_doc_max);
     }
     return doc_id;
 }
 
 static INLINE bool
-SI_competitive(SortCollector *self, int32_t doc_id) {
+SI_competitive(SortCollectorIVARS *ivars, int32_t doc_id) {
     /* Ordinarily, we would cache local copies of more member variables in
      * const automatic variables in order to improve code clarity and provide
      * more hints to the compiler about what variables are actually invariant
      * for the duration of this routine:
      *
-     *     uint8_t *const actions    = self->actions;
-     *     const uint32_t num_rules  = self->num_rules;
-     *     const int32_t bubble_doc = self->bubble_doc;
+     *     uint8_t *const actions    = ivars->actions;
+     *     const uint32_t num_rules  = ivars->num_rules;
+     *     const int32_t bubble_doc = ivars->bubble_doc;
      *
      * However, our major goal is to return as quickly as possible, and the
      * common case is that we'll have our answer before the first loop iter
@@ -420,7 +436,7 @@ SI_competitive(SortCollector *self, int32_t doc_id) {
      * loop instead of a "for" loop, and the switch statement optimized for
      * compilation to a jump table.
      */
-    uint8_t *const actions = self->actions;
+    uint8_t *const actions = ivars->actions;
     uint32_t i = 0;
 
     // Iterate through our array of actions, returning as quickly as possible.
@@ -433,46 +449,46 @@ SI_competitive(SortCollector *self, int32_t doc_id) {
             case AUTO_TIE:
                 break;
             case COMPARE_BY_SCORE: {
-                    float score = Matcher_Score(self->matcher);
-                    if (*(int32_t*)&score == *(int32_t*)&self->bubble_score) {
+                    float score = Matcher_Score(ivars->matcher);
+                    if (*(int32_t*)&score == *(int32_t*)&ivars->bubble_score) {
                         break;
                     }
-                    if (score > self->bubble_score) {
-                        self->bumped->score = score;
+                    if (score > ivars->bubble_score) {
+                        MatchDoc_IVARS(ivars->bumped)->score = score;
                         return true;
                     }
-                    else if (score < self->bubble_score) {
+                    else if (score < ivars->bubble_score) {
                         return false;
                     }
                 }
                 break;
             case COMPARE_BY_SCORE_REV: {
-                    float score = Matcher_Score(self->matcher);
-                    if (*(int32_t*)&score == *(int32_t*)&self->bubble_score) {
+                    float score = Matcher_Score(ivars->matcher);
+                    if (*(int32_t*)&score == *(int32_t*)&ivars->bubble_score) {
                         break;
                     }
-                    if (score < self->bubble_score) {
-                        self->bumped->score = score;
+                    if (score < ivars->bubble_score) {
+                        MatchDoc_IVARS(ivars->bumped)->score = score;
                         return true;
                     }
-                    else if (score > self->bubble_score) {
+                    else if (score > ivars->bubble_score) {
                         return false;
                     }
                 }
                 break;
             case COMPARE_BY_DOC_ID:
-                if (doc_id > self->bubble_doc)      { return false; }
-                else if (doc_id < self->bubble_doc) { return true; }
+                if (doc_id > ivars->bubble_doc)      { return false; }
+                else if (doc_id < ivars->bubble_doc) { return true; }
                 break;
             case COMPARE_BY_DOC_ID_REV:
-                if (doc_id > self->bubble_doc)      { return true; }
-                else if (doc_id < self->bubble_doc) { return false; }
+                if (doc_id > ivars->bubble_doc)      { return true; }
+                else if (doc_id < ivars->bubble_doc) { return false; }
                 break;
             case COMPARE_BY_ORD1: {
                     int32_t comparison
                         = SI_compare_by_ord1(
-                              self, i, SI_validate_doc_id(self, doc_id),
-                              self->bubble_doc);
+                              ivars, i, SI_validate_doc_id(ivars, doc_id),
+                              ivars->bubble_doc);
                     if (comparison < 0)      { return true; }
                     else if (comparison > 0) { return false; }
                 }
@@ -480,8 +496,8 @@ SI_competitive(SortCollector *self, int32_t doc_id) {
             case COMPARE_BY_ORD1_REV: {
                     int32_t comparison
                         = SI_compare_by_ord1(
-                              self, i, self->bubble_doc,
-                              SI_validate_doc_id(self, doc_id));
+                              ivars, i, ivars->bubble_doc,
+                              SI_validate_doc_id(ivars, doc_id));
                     if (comparison < 0)      { return true; }
                     else if (comparison > 0) { return false; }
                 }
@@ -489,8 +505,8 @@ SI_competitive(SortCollector *self, int32_t doc_id) {
             case COMPARE_BY_ORD2: {
                     int32_t comparison
                         = SI_compare_by_ord2(
-                              self, i, SI_validate_doc_id(self, doc_id),
-                              self->bubble_doc);
+                              ivars, i, SI_validate_doc_id(ivars, doc_id),
+                              ivars->bubble_doc);
                     if (comparison < 0)      { return true; }
                     else if (comparison > 0) { return false; }
                 }
@@ -498,8 +514,8 @@ SI_competitive(SortCollector *self, int32_t doc_id) {
             case COMPARE_BY_ORD2_REV: {
                     int32_t comparison
                         = SI_compare_by_ord2(
-                              self, i, self->bubble_doc,
-                              SI_validate_doc_id(self, doc_id));
+                              ivars, i, ivars->bubble_doc,
+                              SI_validate_doc_id(ivars, doc_id));
                     if (comparison < 0)      { return true; }
                     else if (comparison > 0) { return false; }
                 }
@@ -507,8 +523,8 @@ SI_competitive(SortCollector *self, int32_t doc_id) {
             case COMPARE_BY_ORD4: {
                     int32_t comparison
                         = SI_compare_by_ord4(
-                              self, i, SI_validate_doc_id(self, doc_id),
-                              self->bubble_doc);
+                              ivars, i, SI_validate_doc_id(ivars, doc_id),
+                              ivars->bubble_doc);
                     if (comparison < 0)      { return true; }
                     else if (comparison > 0) { return false; }
                 }
@@ -516,8 +532,8 @@ SI_competitive(SortCollector *self, int32_t doc_id) {
             case COMPARE_BY_ORD4_REV: {
                     int32_t comparison
                         = SI_compare_by_ord4(
-                              self, i, self->bubble_doc,
-                              SI_validate_doc_id(self, doc_id));
+                              ivars, i, ivars->bubble_doc,
+                              SI_validate_doc_id(ivars, doc_id));
                     if (comparison < 0)      { return true; }
                     else if (comparison > 0) { return false; }
                 }
@@ -525,8 +541,8 @@ SI_competitive(SortCollector *self, int32_t doc_id) {
             case COMPARE_BY_ORD8: {
                     int32_t comparison
                         = SI_compare_by_ord8(
-                              self, i, SI_validate_doc_id(self, doc_id),
-                              self->bubble_doc);
+                              ivars, i, SI_validate_doc_id(ivars, doc_id),
+                              ivars->bubble_doc);
                     if (comparison < 0)      { return true; }
                     else if (comparison > 0) { return false; }
                 }
@@ -534,8 +550,8 @@ SI_competitive(SortCollector *self, int32_t doc_id) {
             case COMPARE_BY_ORD8_REV: {
                     int32_t comparison
                         = SI_compare_by_ord8(
-                              self, i, self->bubble_doc,
-                              SI_validate_doc_id(self, doc_id));
+                              ivars, i, ivars->bubble_doc,
+                              SI_validate_doc_id(ivars, doc_id));
                     if (comparison < 0)      { return true; }
                     else if (comparison > 0) { return false; }
                 }
@@ -543,8 +559,8 @@ SI_competitive(SortCollector *self, int32_t doc_id) {
             case COMPARE_BY_ORD16: {
                     int32_t comparison
                         = SI_compare_by_ord16(
-                              self, i, SI_validate_doc_id(self, doc_id),
-                              self->bubble_doc);
+                              ivars, i, SI_validate_doc_id(ivars, doc_id),
+                              ivars->bubble_doc);
                     if (comparison < 0)      { return true; }
                     else if (comparison > 0) { return false; }
                 }
@@ -552,8 +568,8 @@ SI_competitive(SortCollector *self, int32_t doc_id) {
             case COMPARE_BY_ORD16_REV: {
                     int32_t comparison
                         = SI_compare_by_ord16(
-                              self, i, self->bubble_doc,
-                              SI_validate_doc_id(self, doc_id));
+                              ivars, i, ivars->bubble_doc,
+                              SI_validate_doc_id(ivars, doc_id));
                     if (comparison < 0)      { return true; }
                     else if (comparison > 0) { return false; }
                 }
@@ -561,8 +577,8 @@ SI_competitive(SortCollector *self, int32_t doc_id) {
             case COMPARE_BY_ORD32: {
                     int32_t comparison
                         = SI_compare_by_ord32(
-                              self, i, SI_validate_doc_id(self, doc_id),
-                              self->bubble_doc);
+                              ivars, i, SI_validate_doc_id(ivars, doc_id),
+                              ivars->bubble_doc);
                     if (comparison < 0)      { return true; }
                     else if (comparison > 0) { return false; }
                 }
@@ -570,8 +586,8 @@ SI_competitive(SortCollector *self, int32_t doc_id) {
             case COMPARE_BY_ORD32_REV: {
                     int32_t comparison
                         = SI_compare_by_ord32(
-                              self, i, self->bubble_doc,
-                              SI_validate_doc_id(self, doc_id));
+                              ivars, i, ivars->bubble_doc,
+                              SI_validate_doc_id(ivars, doc_id));
                     if (comparison < 0)      { return true; }
                     else if (comparison > 0) { return false; }
                 }
@@ -579,8 +595,8 @@ SI_competitive(SortCollector *self, int32_t doc_id) {
             case COMPARE_BY_NATIVE_ORD16: {
                     int32_t comparison
                         = SI_compare_by_native_ord16(
-                              self, i, SI_validate_doc_id(self, doc_id),
-                              self->bubble_doc);
+                              ivars, i, SI_validate_doc_id(ivars, doc_id),
+                              ivars->bubble_doc);
                     if (comparison < 0)      { return true; }
                     else if (comparison > 0) { return false; }
                 }
@@ -588,8 +604,8 @@ SI_competitive(SortCollector *self, int32_t doc_id) {
             case COMPARE_BY_NATIVE_ORD16_REV: {
                     int32_t comparison
                         = SI_compare_by_native_ord16(
-                              self, i, self->bubble_doc,
-                              SI_validate_doc_id(self, doc_id));
+                              ivars, i, ivars->bubble_doc,
+                              SI_validate_doc_id(ivars, doc_id));
                     if (comparison < 0)      { return true; }
                     else if (comparison > 0) { return false; }
                 }
@@ -597,8 +613,8 @@ SI_competitive(SortCollector *self, int32_t doc_id) {
             case COMPARE_BY_NATIVE_ORD32: {
                     int32_t comparison
                         = SI_compare_by_native_ord32(
-                              self, i, SI_validate_doc_id(self, doc_id),
-                              self->bubble_doc);
+                              ivars, i, SI_validate_doc_id(ivars, doc_id),
+                              ivars->bubble_doc);
                     if (comparison < 0)      { return true; }
                     else if (comparison > 0) { return false; }
                 }
@@ -606,8 +622,8 @@ SI_competitive(SortCollector *self, int32_t doc_id) {
             case COMPARE_BY_NATIVE_ORD32_REV: {
                     int32_t comparison
                         = SI_compare_by_native_ord32(
-                              self, i, self->bubble_doc,
-                              SI_validate_doc_id(self, doc_id));
+                              ivars, i, ivars->bubble_doc,
+                              SI_validate_doc_id(ivars, doc_id));
                     if (comparison < 0)      { return true; }
                     else if (comparison > 0) { return false; }
                 }
@@ -615,7 +631,7 @@ SI_competitive(SortCollector *self, int32_t doc_id) {
             default:
                 THROW(ERR, "UNEXPECTED action %u8", actions[i]);
         }
-    } while (++i < self->num_actions);
+    } while (++i < ivars->num_actions);
 
     // If we've made it this far and we're still tied, reject the doc so that
     // we prefer items already in the queue.  This has the effect of

http://git-wip-us.apache.org/repos/asf/lucy/blob/7ba2ba64/core/Lucy/Search/QueryParser/ParserElem.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/QueryParser/ParserElem.c b/core/Lucy/Search/QueryParser/ParserElem.c
index 2bedc2d..a0c4e8c 100644
--- a/core/Lucy/Search/QueryParser/ParserElem.c
+++ b/core/Lucy/Search/QueryParser/ParserElem.c
@@ -27,93 +27,100 @@ ParserElem_new(uint32_t type, Obj *value) {
 
 ParserElem*
 ParserElem_init(ParserElem *self, uint32_t type, Obj *value) {
-    self->type  = type;
-    self->value = value;
-    self->occur = LUCY_QPARSER_SHOULD;
+    ParserElemIVARS *const ivars = ParserElem_IVARS(self);
+    ivars->type  = type;
+    ivars->value = value;
+    ivars->occur = LUCY_QPARSER_SHOULD;
     return self;
 }
 
 void
 ParserElem_destroy(ParserElem *self) {
-    DECREF(self->value);
+    ParserElemIVARS *const ivars = ParserElem_IVARS(self);
+    DECREF(ivars->value);
     SUPER_DESTROY(self, PARSERELEM);
 }
 
 void
 ParserElem_set_value(ParserElem *self, Obj *value) {
+    ParserElemIVARS *const ivars = ParserElem_IVARS(self);
     INCREF(value);
-    DECREF(self->value);
-    self->value = value;
+    DECREF(ivars->value);
+    ivars->value = value;
 }
 
 Obj*
 ParserElem_as(ParserElem *self, VTable *metaclass) {
-    if (self->value && Obj_Is_A(self->value, metaclass)) {
-        return self->value;
+    ParserElemIVARS *const ivars = ParserElem_IVARS(self);
+    if (ivars->value && Obj_Is_A(ivars->value, metaclass)) {
+        return ivars->value;
     }
     return NULL;
 }
 
 uint32_t
 ParserElem_get_type(ParserElem *self) {
-    return self->type;
+    return ParserElem_IVARS(self)->type;
 }
 
 void
 ParserElem_require(ParserElem *self) {
-    switch (self->occur) {
+    ParserElemIVARS *const ivars = ParserElem_IVARS(self);
+    switch (ivars->occur) {
         case LUCY_QPARSER_SHOULD:
-            self->occur = LUCY_QPARSER_MUST;
+            ivars->occur = LUCY_QPARSER_MUST;
             break;
         case LUCY_QPARSER_MUST_NOT:
         case LUCY_QPARSER_MUST:
             break;
         default:
-            THROW(ERR, "Internal error in value of occur: %u32", self->occur);
+            THROW(ERR, "Internal error in value of occur: %u32", ivars->occur);
     }
 }
 
 void
 ParserElem_unrequire(ParserElem *self) {
-    switch (self->occur) {
+    ParserElemIVARS *const ivars = ParserElem_IVARS(self);
+    switch (ivars->occur) {
         case LUCY_QPARSER_MUST:
-            self->occur = LUCY_QPARSER_SHOULD;
+            ivars->occur = LUCY_QPARSER_SHOULD;
             break;
         case LUCY_QPARSER_MUST_NOT:
         case LUCY_QPARSER_SHOULD:
             break;
         default:
-            THROW(ERR, "Internal error in value of occur: %u32", self->occur);
+            THROW(ERR, "Internal error in value of occur: %u32", ivars->occur);
     }
 }
 
 void
 ParserElem_negate(ParserElem *self) {
-    switch (self->occur) {
+    ParserElemIVARS *const ivars = ParserElem_IVARS(self);
+    switch (ivars->occur) {
         case LUCY_QPARSER_SHOULD:
         case LUCY_QPARSER_MUST:
-            self->occur = LUCY_QPARSER_MUST_NOT;
+            ivars->occur = LUCY_QPARSER_MUST_NOT;
             break;
         case LUCY_QPARSER_MUST_NOT:
-            self->occur = LUCY_QPARSER_MUST; // Apply double negative.
+            ivars->occur = LUCY_QPARSER_MUST; // Apply double negative.
             break;
         default:
-            THROW(ERR, "Internal error in value of occur: %u32", self->occur);
+            THROW(ERR, "Internal error in value of occur: %u32", ivars->occur);
     }
 }
 
 bool
 ParserElem_optional(ParserElem *self) {
-    return self->occur == LUCY_QPARSER_SHOULD;
+    return ParserElem_IVARS(self)->occur == LUCY_QPARSER_SHOULD;
 }
 
 bool
 ParserElem_required(ParserElem *self) {
-    return self->occur == LUCY_QPARSER_MUST;
+    return ParserElem_IVARS(self)->occur == LUCY_QPARSER_MUST;
 }
 
 bool
 ParserElem_negated(ParserElem *self) {
-    return self->occur == LUCY_QPARSER_MUST_NOT;
+    return ParserElem_IVARS(self)->occur == LUCY_QPARSER_MUST_NOT;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/7ba2ba64/core/Lucy/Search/QueryParser/QueryLexer.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/QueryParser/QueryLexer.c b/core/Lucy/Search/QueryParser/QueryLexer.c
index 851380c..847a69f 100644
--- a/core/Lucy/Search/QueryParser/QueryLexer.c
+++ b/core/Lucy/Search/QueryParser/QueryLexer.c
@@ -55,22 +55,24 @@ QueryLexer_new() {
 
 QueryLexer*
 QueryLexer_init(QueryLexer *self) {
-    self->heed_colons = false;
+    QueryLexerIVARS *const ivars = QueryLexer_IVARS(self);
+    ivars->heed_colons = false;
     return self;
 }
 
 bool
 QueryLexer_heed_colons(QueryLexer *self) {
-    return self->heed_colons;
+    return QueryLexer_IVARS(self)->heed_colons;
 }
 
 void
 QueryLexer_set_heed_colons(QueryLexer *self, bool heed_colons) {
-    self->heed_colons = heed_colons;
+    QueryLexer_IVARS(self)->heed_colons = heed_colons;
 }
 
 VArray*
 QueryLexer_tokenize(QueryLexer *self, const CharBuf *query_string) {
+    QueryLexerIVARS *const ivars = QueryLexer_IVARS(self);
     CharBuf *copy = query_string
                     ? CB_Clone(query_string)
                     : CB_new_from_trusted_utf8("", 0);
@@ -86,7 +88,7 @@ QueryLexer_tokenize(QueryLexer *self, const CharBuf *query_string) {
             continue;
         }
 
-        if (self->heed_colons) {
+        if (ivars->heed_colons) {
             ParserElem *elem = S_consume_field(qstring);
             if (elem) {
                 VA_Push(elems, (Obj*)elem);


[lucy-commits] [14/34] git commit: refs/heads/master - Migrate Lucy's plan classes to IVARS.

Posted by ma...@apache.org.
Migrate Lucy's plan classes to IVARS.

Change all Lucy's plan classes to access instance vars via an IVARS
struct rather than via `self`.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/c2adaf55
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/c2adaf55
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/c2adaf55

Branch: refs/heads/master
Commit: c2adaf555844dfb444766fe1fe12b5c673bda76b
Parents: 4f7440f
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Sat Jun 29 16:09:15 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 16:08:42 2013 -0700

----------------------------------------------------------------------
 core/Lucy/Plan/BlobType.c     | 28 +++++++----
 core/Lucy/Plan/FieldType.c    | 44 +++++++++--------
 core/Lucy/Plan/FullTextType.c | 62 ++++++++++++------------
 core/Lucy/Plan/NumericType.c  | 20 ++++----
 core/Lucy/Plan/Schema.c       | 98 ++++++++++++++++++++++----------------
 core/Lucy/Plan/StringType.c   | 34 ++++++-------
 core/Lucy/Plan/TextType.c     | 33 ++++++++-----
 7 files changed, 177 insertions(+), 142 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/c2adaf55/core/Lucy/Plan/BlobType.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Plan/BlobType.c b/core/Lucy/Plan/BlobType.c
index e8492c9..1892d5a 100644
--- a/core/Lucy/Plan/BlobType.c
+++ b/core/Lucy/Plan/BlobType.c
@@ -28,7 +28,8 @@ BlobType_new(bool stored) {
 BlobType*
 BlobType_init(BlobType *self, bool stored) {
     FType_init((FieldType*)self);
-    self->stored = stored;
+    BlobTypeIVARS *const ivars = BlobType_IVARS(self);
+    ivars->stored = stored;
     return self;
 }
 
@@ -58,26 +59,26 @@ BlobType_primitive_id(BlobType *self) {
 
 bool
 BlobType_equals(BlobType *self, Obj *other) {
-    BlobType *twin = (BlobType*)other;
-    if (twin == self)               { return true; }
+    if ((BlobType*)other == self)   { return true; }
     if (!Obj_Is_A(other, BLOBTYPE)) { return false; }
     return FType_equals((FieldType*)self, other);
 }
 
 Hash*
 BlobType_dump_for_schema(BlobType *self) {
+    BlobTypeIVARS *const ivars = BlobType_IVARS(self);
     Hash *dump = Hash_new(0);
     Hash_Store_Str(dump, "type", 4, (Obj*)CB_newf("blob"));
 
     // Store attributes that override the defaults -- even if they're
     // meaningless.
-    if (self->boost != 1.0) {
-        Hash_Store_Str(dump, "boost", 5, (Obj*)CB_newf("%f64", self->boost));
+    if (ivars->boost != 1.0) {
+        Hash_Store_Str(dump, "boost", 5, (Obj*)CB_newf("%f64", ivars->boost));
     }
-    if (self->indexed) {
+    if (ivars->indexed) {
         Hash_Store_Str(dump, "indexed", 7, (Obj*)CFISH_TRUE);
     }
-    if (self->stored) {
+    if (ivars->stored) {
         Hash_Store_Str(dump, "stored", 6, (Obj*)CFISH_TRUE);
     }
 
@@ -108,9 +109,16 @@ BlobType_load(BlobType *self, Obj *dump) {
     UNUSED_VAR(self);
 
     BlobType_init(loaded, false);
-    if (boost_dump)   { loaded->boost   = (float)Obj_To_F64(boost_dump);    }
-    if (indexed_dump) { loaded->indexed = Obj_To_Bool(indexed_dump); }
-    if (stored_dump)  { loaded->stored  = Obj_To_Bool(stored_dump);  }
+    BlobTypeIVARS *const loaded_ivars = BlobType_IVARS(loaded);
+    if (boost_dump) {
+        loaded_ivars->boost = (float)Obj_To_F64(boost_dump);
+    }
+    if (indexed_dump) {
+        loaded_ivars->indexed = Obj_To_Bool(indexed_dump);
+    }
+    if (stored_dump){
+        loaded_ivars->stored = Obj_To_Bool(stored_dump);
+    }
 
     return loaded;
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/c2adaf55/core/Lucy/Plan/FieldType.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Plan/FieldType.c b/core/Lucy/Plan/FieldType.c
index 00139ae..089f7c1 100644
--- a/core/Lucy/Plan/FieldType.c
+++ b/core/Lucy/Plan/FieldType.c
@@ -30,52 +30,53 @@ FType_init(FieldType *self) {
 FieldType*
 FType_init2(FieldType *self, float boost, bool indexed, bool stored,
             bool sortable) {
-    self->boost              = boost;
-    self->indexed            = indexed;
-    self->stored             = stored;
-    self->sortable           = sortable;
+    FieldTypeIVARS *const ivars = FType_IVARS(self);
+    ivars->boost             = boost;
+    ivars->indexed           = indexed;
+    ivars->stored            = stored;
+    ivars->sortable          = sortable;
     ABSTRACT_CLASS_CHECK(self, FIELDTYPE);
     return self;
 }
 
 void
 FType_set_boost(FieldType *self, float boost) {
-    self->boost = boost;
+    FType_IVARS(self)->boost = boost;
 }
 
 void
 FType_set_indexed(FieldType *self, bool indexed) {
-    self->indexed = !!indexed;
+    FType_IVARS(self)->indexed = !!indexed;
 }
 
 void
 FType_set_stored(FieldType *self, bool stored) {
-    self->stored = !!stored;
+    FType_IVARS(self)->stored = !!stored;
 }
 
 void
 FType_set_sortable(FieldType *self, bool sortable) {
-    self->sortable = !!sortable;
+    FType_IVARS(self)->sortable = !!sortable;
 }
 
 float
 FType_get_boost(FieldType *self) {
-    return self->boost;
+    return FType_IVARS(self)->boost;
 }
 
 bool
 FType_indexed(FieldType *self) {
-    return self->indexed;
+    return FType_IVARS(self)->indexed;
 }
 
 bool
 FType_stored(FieldType *self) {
-    return self->stored;
+    return FType_IVARS(self)->stored;
 }
 
 bool
 FType_sortable(FieldType *self) {
-    return self->sortable;
+    return FType_IVARS(self)->sortable;
 }
 
 bool
@@ -98,14 +99,17 @@ FType_compare_values(FieldType *self, Obj *a, Obj *b) {
 
 bool
 FType_equals(FieldType *self, Obj *other) {
-    FieldType *twin = (FieldType*)other;
-    if (twin == self)                                     { return true; }
-    if (FType_Get_VTable(self) != FType_Get_VTable(twin)) { return false; }
-    if (self->boost != twin->boost)                       { return false; }
-    if (!!self->indexed    != !!twin->indexed)            { return false; }
-    if (!!self->stored     != !!twin->stored)             { return false; }
-    if (!!self->sortable   != !!twin->sortable)           { return false; }
-    if (!!FType_Binary(self) != !!FType_Binary(twin))     { return false; }
+    if ((FieldType*)other == self)                       { return true; }
+    if (FType_Get_VTable(self) != Obj_Get_VTable(other)) { return false; }
+    FieldTypeIVARS *const ivars = FType_IVARS(self);
+    FieldTypeIVARS *const ovars = FType_IVARS((FieldType*)other);
+    if (ivars->boost != ovars->boost)                    { return false; }
+    if (!!ivars->indexed    != !!ovars->indexed)         { return false; }
+    if (!!ivars->stored     != !!ovars->stored)          { return false; }
+    if (!!ivars->sortable   != !!ovars->sortable)        { return false; }
+    if (!!FType_Binary(self) != !!FType_Binary((FieldType*)other)) {
+        return false;
+    }
     return true;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/c2adaf55/core/Lucy/Plan/FullTextType.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Plan/FullTextType.c b/core/Lucy/Plan/FullTextType.c
index 4c30b2b..ac379eb 100644
--- a/core/Lucy/Plan/FullTextType.c
+++ b/core/Lucy/Plan/FullTextType.c
@@ -38,33 +38,36 @@ FullTextType_init2(FullTextType *self, Analyzer *analyzer, float boost,
                    bool indexed, bool stored, bool sortable,
                    bool highlightable) {
     FType_init((FieldType*)self);
+    FullTextTypeIVARS *const ivars = FullTextType_IVARS(self);
 
     /* Assign */
-    self->boost         = boost;
-    self->indexed       = indexed;
-    self->stored        = stored;
-    self->sortable      = sortable;
-    self->highlightable = highlightable;
-    self->analyzer      = (Analyzer*)INCREF(analyzer);
+    ivars->boost         = boost;
+    ivars->indexed       = indexed;
+    ivars->stored        = stored;
+    ivars->sortable      = sortable;
+    ivars->highlightable = highlightable;
+    ivars->analyzer      = (Analyzer*)INCREF(analyzer);
 
     return self;
 }
 
 void
 FullTextType_destroy(FullTextType *self) {
-    DECREF(self->analyzer);
+    FullTextTypeIVARS *const ivars = FullTextType_IVARS(self);
+    DECREF(ivars->analyzer);
     SUPER_DESTROY(self, FULLTEXTTYPE);
 }
 
 bool
 FullTextType_equals(FullTextType *self, Obj *other) {
-    FullTextType *twin = (FullTextType*)other;
-    if (twin == self)                                   { return true; }
-    if (!Obj_Is_A(other, FULLTEXTTYPE))                 { return false; }
-    if (!FType_equals((FieldType*)self, other))         { return false; }
-    if (!!self->sortable != !!twin->sortable)           { return false; }
-    if (!!self->highlightable != !!twin->highlightable) { return false; }
-    if (!Analyzer_Equals(self->analyzer, (Obj*)twin->analyzer)) {
+    if ((FullTextType*)other == self)                     { return true; }
+    if (!Obj_Is_A(other, FULLTEXTTYPE))                   { return false; }
+    FullTextTypeIVARS *const ivars = FullTextType_IVARS(self);
+    FullTextTypeIVARS *const ovars = FullTextType_IVARS((FullTextType*)other);
+    if (!FType_equals((FieldType*)self, other))           { return false; }
+    if (!!ivars->sortable      != !!ovars->sortable)      { return false; }
+    if (!!ivars->highlightable != !!ovars->highlightable) { return false; }
+    if (!Analyzer_Equals(ivars->analyzer, (Obj*)ovars->analyzer)) {
         return false;
     }
     return true;
@@ -72,23 +75,24 @@ FullTextType_equals(FullTextType *self, Obj *other) {
 
 Hash*
 FullTextType_dump_for_schema(FullTextType *self) {
+    FullTextTypeIVARS *const ivars = FullTextType_IVARS(self);
     Hash *dump = Hash_new(0);
     Hash_Store_Str(dump, "type", 4, (Obj*)CB_newf("fulltext"));
 
     // Store attributes that override the defaults.
-    if (self->boost != 1.0) {
-        Hash_Store_Str(dump, "boost", 5, (Obj*)CB_newf("%f64", self->boost));
+    if (ivars->boost != 1.0) {
+        Hash_Store_Str(dump, "boost", 5, (Obj*)CB_newf("%f64", ivars->boost));
     }
-    if (!self->indexed) {
+    if (!ivars->indexed) {
         Hash_Store_Str(dump, "indexed", 7, (Obj*)CFISH_FALSE);
     }
-    if (!self->stored) {
+    if (!ivars->stored) {
         Hash_Store_Str(dump, "stored", 6, (Obj*)CFISH_FALSE);
     }
-    if (self->sortable) {
+    if (ivars->sortable) {
         Hash_Store_Str(dump, "sortable", 8, (Obj*)CFISH_TRUE);
     }
-    if (self->highlightable) {
+    if (ivars->highlightable) {
         Hash_Store_Str(dump, "highlightable", 13, (Obj*)CFISH_TRUE);
     }
 
@@ -97,11 +101,12 @@ FullTextType_dump_for_schema(FullTextType *self) {
 
 Hash*
 FullTextType_dump(FullTextType *self) {
+    FullTextTypeIVARS *const ivars = FullTextType_IVARS(self);
     Hash *dump = FullTextType_Dump_For_Schema(self);
     Hash_Store_Str(dump, "_class", 6,
                    (Obj*)CB_Clone(FullTextType_Get_Class_Name(self)));
     Hash_Store_Str(dump, "analyzer", 8,
-                   (Obj*)Analyzer_Dump(self->analyzer));
+                   (Obj*)Analyzer_Dump(ivars->analyzer));
     DECREF(Hash_Delete_Str(dump, "type", 4));
 
     return dump;
@@ -146,30 +151,25 @@ FullTextType_load(FullTextType *self, Obj *dump) {
     }
     CERTIFY(analyzer, ANALYZER);
 
-    FullTextType_init(loaded, analyzer);
+    FullTextType_init2(loaded, analyzer, boost, indexed, stored,
+                       sortable, hl);
     DECREF(analyzer);
-    if (boost_dump)   { loaded->boost         = boost;    }
-    if (indexed_dump) { loaded->indexed       = indexed;  }
-    if (stored_dump)  { loaded->stored        = stored;   }
-    if (sort_dump)    { loaded->sortable      = sortable; }
-    if (hl_dump)      { loaded->highlightable = hl;       }
-
     return loaded;
 }
 
 void
 FullTextType_set_highlightable(FullTextType *self, bool highlightable) {
-    self->highlightable = highlightable;
+    FullTextType_IVARS(self)->highlightable = highlightable;
 }
 
 Analyzer*
 FullTextType_get_analyzer(FullTextType *self) {
-    return self->analyzer;
+    return FullTextType_IVARS(self)->analyzer;
 }
 
 bool
 FullTextType_highlightable(FullTextType *self) {
-    return self->highlightable;
+    return FullTextType_IVARS(self)->highlightable;
 }
 
 Similarity*

http://git-wip-us.apache.org/repos/asf/lucy/blob/c2adaf55/core/Lucy/Plan/NumericType.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Plan/NumericType.c b/core/Lucy/Plan/NumericType.c
index a71602a..2d73119 100644
--- a/core/Lucy/Plan/NumericType.c
+++ b/core/Lucy/Plan/NumericType.c
@@ -28,10 +28,11 @@ NumericType*
 NumType_init2(NumericType *self, float boost, bool indexed, bool stored,
               bool sortable) {
     FType_init((FieldType*)self);
-    self->boost      = boost;
-    self->indexed    = indexed;
-    self->stored     = stored;
-    self->sortable   = sortable;
+    NumericTypeIVARS *const ivars = NumType_IVARS(self);
+    ivars->boost      = boost;
+    ivars->indexed    = indexed;
+    ivars->stored     = stored;
+    ivars->sortable   = sortable;
     return self;
 }
 
@@ -43,20 +44,21 @@ NumType_binary(NumericType *self) {
 
 Hash*
 NumType_dump_for_schema(NumericType *self) {
+    NumericTypeIVARS *const ivars = NumType_IVARS(self);
     Hash *dump = Hash_new(0);
     Hash_Store_Str(dump, "type", 4, (Obj*)NumType_Specifier(self));
 
     // Store attributes that override the defaults.
-    if (self->boost != 1.0) {
-        Hash_Store_Str(dump, "boost", 5, (Obj*)CB_newf("%f64", self->boost));
+    if (ivars->boost != 1.0) {
+        Hash_Store_Str(dump, "boost", 5, (Obj*)CB_newf("%f64", ivars->boost));
     }
-    if (!self->indexed) {
+    if (!ivars->indexed) {
         Hash_Store_Str(dump, "indexed", 7, (Obj*)CFISH_FALSE);
     }
-    if (!self->stored) {
+    if (!ivars->stored) {
         Hash_Store_Str(dump, "stored", 6, (Obj*)CFISH_FALSE);
     }
-    if (self->sortable) {
+    if (ivars->sortable) {
         Hash_Store_Str(dump, "sortable", 8, (Obj*)CFISH_TRUE);
     }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/c2adaf55/core/Lucy/Plan/Schema.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Plan/Schema.c b/core/Lucy/Plan/Schema.c
index ba6de0b..64f9281 100644
--- a/core/Lucy/Plan/Schema.c
+++ b/core/Lucy/Plan/Schema.c
@@ -53,28 +53,30 @@ Schema_new() {
 
 Schema*
 Schema_init(Schema *self) {
+    SchemaIVARS *const ivars = Schema_IVARS(self);
     // Init.
-    self->analyzers      = Hash_new(0);
-    self->types          = Hash_new(0);
-    self->sims           = Hash_new(0);
-    self->uniq_analyzers = VA_new(2);
-    VA_Resize(self->uniq_analyzers, 1);
+    ivars->analyzers      = Hash_new(0);
+    ivars->types          = Hash_new(0);
+    ivars->sims           = Hash_new(0);
+    ivars->uniq_analyzers = VA_new(2);
+    VA_Resize(ivars->uniq_analyzers, 1);
 
     // Assign.
-    self->arch = Schema_Architecture(self);
-    self->sim  = Arch_Make_Similarity(self->arch);
+    ivars->arch = Schema_Architecture(self);
+    ivars->sim  = Arch_Make_Similarity(ivars->arch);
 
     return self;
 }
 
 void
 Schema_destroy(Schema *self) {
-    DECREF(self->arch);
-    DECREF(self->analyzers);
-    DECREF(self->uniq_analyzers);
-    DECREF(self->types);
-    DECREF(self->sims);
-    DECREF(self->sim);
+    SchemaIVARS *const ivars = Schema_IVARS(self);
+    DECREF(ivars->arch);
+    DECREF(ivars->analyzers);
+    DECREF(ivars->uniq_analyzers);
+    DECREF(ivars->types);
+    DECREF(ivars->sims);
+    DECREF(ivars->sim);
     SUPER_DESTROY(self, SCHEMA);
 }
 
@@ -94,12 +96,13 @@ S_add_unique(VArray *array, Obj *elem) {
 
 bool
 Schema_equals(Schema *self, Obj *other) {
-    Schema *twin = (Schema*)other;
-    if (twin == self)                                 { return true; }
-    if (!Obj_Is_A(other, SCHEMA))                     { return false; }
-    if (!Arch_Equals(self->arch, (Obj*)twin->arch))   { return false; }
-    if (!Sim_Equals(self->sim, (Obj*)twin->sim))      { return false; }
-    if (!Hash_Equals(self->types, (Obj*)twin->types)) { return false; }
+    if ((Schema*)other == self)                         { return true; }
+    if (!Obj_Is_A(other, SCHEMA))                       { return false; }
+    SchemaIVARS *const ivars = Schema_IVARS(self);
+    SchemaIVARS *const ovars = Schema_IVARS((Schema*)other);
+    if (!Arch_Equals(ivars->arch, (Obj*)ovars->arch))   { return false; }
+    if (!Sim_Equals(ivars->sim, (Obj*)ovars->sim))      { return false; }
+    if (!Hash_Equals(ivars->types, (Obj*)ovars->types)) { return false; }
     return true;
 }
 
@@ -138,82 +141,90 @@ Schema_spec_field(Schema *self, const CharBuf *field, FieldType *type) {
 
 static void
 S_add_text_field(Schema *self, const CharBuf *field, FieldType *type) {
+    SchemaIVARS *const ivars = Schema_IVARS(self);
     FullTextType *fttype    = (FullTextType*)CERTIFY(type, FULLTEXTTYPE);
     Similarity   *sim       = FullTextType_Make_Similarity(fttype);
     Analyzer     *analyzer  = FullTextType_Get_Analyzer(fttype);
 
     // Cache helpers.
-    Hash_Store(self->sims, (Obj*)field, (Obj*)sim);
-    Hash_Store(self->analyzers, (Obj*)field, INCREF(analyzer));
-    S_add_unique(self->uniq_analyzers, (Obj*)analyzer);
+    Hash_Store(ivars->sims, (Obj*)field, (Obj*)sim);
+    Hash_Store(ivars->analyzers, (Obj*)field, INCREF(analyzer));
+    S_add_unique(ivars->uniq_analyzers, (Obj*)analyzer);
 
     // Store FieldType.
-    Hash_Store(self->types, (Obj*)field, INCREF(type));
+    Hash_Store(ivars->types, (Obj*)field, INCREF(type));
 }
 
 static void
 S_add_string_field(Schema *self, const CharBuf *field, FieldType *type) {
+    SchemaIVARS *const ivars = Schema_IVARS(self);
     StringType *string_type = (StringType*)CERTIFY(type, STRINGTYPE);
     Similarity *sim         = StringType_Make_Similarity(string_type);
 
     // Cache helpers.
-    Hash_Store(self->sims, (Obj*)field, (Obj*)sim);
+    Hash_Store(ivars->sims, (Obj*)field, (Obj*)sim);
 
     // Store FieldType.
-    Hash_Store(self->types, (Obj*)field, INCREF(type));
+    Hash_Store(ivars->types, (Obj*)field, INCREF(type));
 }
 
 static void
 S_add_blob_field(Schema *self, const CharBuf *field, FieldType *type) {
+    SchemaIVARS *const ivars = Schema_IVARS(self);
     BlobType *blob_type = (BlobType*)CERTIFY(type, BLOBTYPE);
-    Hash_Store(self->types, (Obj*)field, INCREF(blob_type));
+    Hash_Store(ivars->types, (Obj*)field, INCREF(blob_type));
 }
 
 static void
 S_add_numeric_field(Schema *self, const CharBuf *field, FieldType *type) {
+    SchemaIVARS *const ivars = Schema_IVARS(self);
     NumericType *num_type = (NumericType*)CERTIFY(type, NUMERICTYPE);
-    Hash_Store(self->types, (Obj*)field, INCREF(num_type));
+    Hash_Store(ivars->types, (Obj*)field, INCREF(num_type));
 }
 
 FieldType*
 Schema_fetch_type(Schema *self, const CharBuf *field) {
-    return (FieldType*)Hash_Fetch(self->types, (Obj*)field);
+    SchemaIVARS *const ivars = Schema_IVARS(self);
+    return (FieldType*)Hash_Fetch(ivars->types, (Obj*)field);
 }
 
 Analyzer*
 Schema_fetch_analyzer(Schema *self, const CharBuf *field) {
+    SchemaIVARS *const ivars = Schema_IVARS(self);
     return field
-           ? (Analyzer*)Hash_Fetch(self->analyzers, (Obj*)field)
+           ? (Analyzer*)Hash_Fetch(ivars->analyzers, (Obj*)field)
            : NULL;
 }
 
 Similarity*
 Schema_fetch_sim(Schema *self, const CharBuf *field) {
+    SchemaIVARS *const ivars = Schema_IVARS(self);
     Similarity *sim = NULL;
     if (field != NULL) {
-        sim = (Similarity*)Hash_Fetch(self->sims, (Obj*)field);
+        sim = (Similarity*)Hash_Fetch(ivars->sims, (Obj*)field);
     }
     return sim;
 }
 
 uint32_t
 Schema_num_fields(Schema *self) {
-    return Hash_Get_Size(self->types);
+    SchemaIVARS *const ivars = Schema_IVARS(self);
+    return Hash_Get_Size(ivars->types);
 }
 
 Architecture*
 Schema_get_architecture(Schema *self) {
-    return self->arch;
+    return Schema_IVARS(self)->arch;
 }
 
 Similarity*
 Schema_get_similarity(Schema *self) {
-    return self->sim;
+    return Schema_IVARS(self)->sim;
 }
 
 VArray*
 Schema_all_fields(Schema *self) {
-    return Hash_Keys(self->types);
+    return Hash_Keys(Schema_IVARS(self)->types);
 }
 
 uint32_t
@@ -237,20 +248,21 @@ S_find_in_array(VArray *array, Obj *obj) {
 
 Hash*
 Schema_dump(Schema *self) {
+    SchemaIVARS *const ivars = Schema_IVARS(self);
     Hash *dump = Hash_new(0);
-    Hash *type_dumps = Hash_new(Hash_Get_Size(self->types));
+    Hash *type_dumps = Hash_new(Hash_Get_Size(ivars->types));
     CharBuf *field;
     FieldType *type;
 
     // Record class name, store dumps of unique Analyzers.
     Hash_Store_Str(dump, "_class", 6,
                    (Obj*)CB_Clone(Schema_Get_Class_Name(self)));
-    Hash_Store_Str(dump, "analyzers", 9, (Obj*)VA_Dump(self->uniq_analyzers));
+    Hash_Store_Str(dump, "analyzers", 9, (Obj*)VA_Dump(ivars->uniq_analyzers));
 
     // Dump FieldTypes.
     Hash_Store_Str(dump, "fields", 6, (Obj*)type_dumps);
-    Hash_Iterate(self->types);
-    while (Hash_Next(self->types, (Obj**)&field, (Obj**)&type)) {
+    Hash_Iterate(ivars->types);
+    while (Hash_Next(ivars->types, (Obj**)&field, (Obj**)&type)) {
         VTable *type_vtable = FType_Get_VTable(type);
 
         // Dump known types to simplified format.
@@ -259,7 +271,7 @@ Schema_dump(Schema *self) {
             Hash *type_dump = FullTextType_Dump_For_Schema(fttype);
             Analyzer *analyzer = FullTextType_Get_Analyzer(fttype);
             uint32_t tick
-                = S_find_in_array(self->uniq_analyzers, (Obj*)analyzer);
+                = S_find_in_array(ivars->uniq_analyzers, (Obj*)analyzer);
 
             // Store the tick which references a unique analyzer.
             Hash_Store_Str(type_dump, "analyzer", 8,
@@ -299,7 +311,8 @@ Schema_load(Schema *self, Obj *dump) {
 
     // Start with a blank Schema.
     Schema_init(loaded);
-    VA_Grow(loaded->uniq_analyzers, VA_Get_Size(analyzers));
+    SchemaIVARS *const loaded_ivars = Schema_IVARS(loaded);
+    VA_Grow(loaded_ivars->uniq_analyzers, VA_Get_Size(analyzers));
 
     Hash_Iterate(type_dumps);
     while (Hash_Next(type_dumps, (Obj**)&field, (Obj**)&type_dump)) {
@@ -390,8 +403,9 @@ Schema_eat(Schema *self, Schema *other) {
 
     CharBuf *field;
     FieldType *type;
-    Hash_Iterate(other->types);
-    while (Hash_Next(other->types, (Obj**)&field, (Obj**)&type)) {
+    SchemaIVARS *const ovars = Schema_IVARS(other);
+    Hash_Iterate(ovars->types);
+    while (Hash_Next(ovars->types, (Obj**)&field, (Obj**)&type)) {
         Schema_Spec_Field(self, field, type);
     }
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/c2adaf55/core/Lucy/Plan/StringType.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Plan/StringType.c b/core/Lucy/Plan/StringType.c
index d27cd37..2965121 100644
--- a/core/Lucy/Plan/StringType.c
+++ b/core/Lucy/Plan/StringType.c
@@ -36,37 +36,38 @@ StringType*
 StringType_init2(StringType *self, float boost, bool indexed,
                  bool stored, bool sortable) {
     FType_init((FieldType*)self);
-    self->boost      = boost;
-    self->indexed    = indexed;
-    self->stored     = stored;
-    self->sortable   = sortable;
+    StringTypeIVARS *const ivars = StringType_IVARS(self);
+    ivars->boost      = boost;
+    ivars->indexed    = indexed;
+    ivars->stored     = stored;
+    ivars->sortable   = sortable;
     return self;
 }
 
 bool
 StringType_equals(StringType *self, Obj *other) {
-    StringType *twin = (StringType*)other;
-    if (twin == self)                           { return true; }
+    if ((StringType*)other == self)             { return true; }
     if (!FType_equals((FieldType*)self, other)) { return false; }
     return true;
 }
 
 Hash*
 StringType_dump_for_schema(StringType *self) {
+    StringTypeIVARS *const ivars = StringType_IVARS(self);
     Hash *dump = Hash_new(0);
     Hash_Store_Str(dump, "type", 4, (Obj*)CB_newf("string"));
 
     // Store attributes that override the defaults.
-    if (self->boost != 1.0) {
-        Hash_Store_Str(dump, "boost", 5, (Obj*)CB_newf("%f64", self->boost));
+    if (ivars->boost != 1.0) {
+        Hash_Store_Str(dump, "boost", 5, (Obj*)CB_newf("%f64", ivars->boost));
     }
-    if (!self->indexed) {
+    if (!ivars->indexed) {
         Hash_Store_Str(dump, "indexed", 7, (Obj*)CFISH_FALSE);
     }
-    if (!self->stored) {
+    if (!ivars->stored) {
         Hash_Store_Str(dump, "stored", 6, (Obj*)CFISH_FALSE);
     }
-    if (self->sortable) {
+    if (ivars->sortable) {
         Hash_Store_Str(dump, "sortable", 8, (Obj*)CFISH_TRUE);
     }
 
@@ -97,13 +98,12 @@ StringType_load(StringType *self, Obj *dump) {
     Obj *sortable_dump   = Hash_Fetch_Str(source, "sortable", 8);
     UNUSED_VAR(self);
 
-    StringType_init(loaded);
-    if (boost_dump)    { loaded->boost    = (float)Obj_To_F64(boost_dump); }
-    if (indexed_dump)  { loaded->indexed  = Obj_To_Bool(indexed_dump); }
-    if (stored_dump)   { loaded->stored   = Obj_To_Bool(stored_dump); }
-    if (sortable_dump) { loaded->sortable = Obj_To_Bool(sortable_dump); }
+    float boost    = boost_dump    ? (float)Obj_To_F64(boost_dump) : 1.0f;
+    bool  indexed  = indexed_dump  ? Obj_To_Bool(indexed_dump)     : true;
+    bool  stored   = stored_dump   ? Obj_To_Bool(stored_dump)      : true;
+    bool  sortable = sortable_dump ? Obj_To_Bool(sortable_dump)    : false;
 
-    return loaded;
+    return StringType_init2(loaded, boost, indexed, stored, sortable);
 }
 
 Similarity*

http://git-wip-us.apache.org/repos/asf/lucy/blob/c2adaf55/core/Lucy/Plan/TextType.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Plan/TextType.c b/core/Lucy/Plan/TextType.c
index 44a290d..25ee102 100644
--- a/core/Lucy/Plan/TextType.c
+++ b/core/Lucy/Plan/TextType.c
@@ -53,37 +53,42 @@ TextTermStepper_new() {
 TextTermStepper*
 TextTermStepper_init(TextTermStepper *self) {
     TermStepper_init((TermStepper*)self);
-    self->value = (Obj*)CB_new(0);
+    TextTermStepperIVARS *const ivars = TextTermStepper_IVARS(self);
+    ivars->value = (Obj*)CB_new(0);
     return self;
 }
 
 void
 TextTermStepper_set_value(TextTermStepper *self, Obj *value) {
+    TextTermStepperIVARS *const ivars = TextTermStepper_IVARS(self);
     CERTIFY(value, CHARBUF);
-    DECREF(self->value);
-    self->value = INCREF(value);
+    DECREF(ivars->value);
+    ivars->value = INCREF(value);
 }
 
 void
 TextTermStepper_reset(TextTermStepper *self) {
-    CB_Set_Size((CharBuf*)self->value, 0);
+    TextTermStepperIVARS *const ivars = TextTermStepper_IVARS(self);
+    CB_Set_Size((CharBuf*)ivars->value, 0);
 }
 
 void
 TextTermStepper_write_key_frame(TextTermStepper *self, OutStream *outstream,
                                 Obj *value) {
+    TextTermStepperIVARS *const ivars = TextTermStepper_IVARS(self);
     uint8_t *buf  = CB_Get_Ptr8((CharBuf*)value);
     size_t   size = CB_Get_Size((CharBuf*)value);
     OutStream_Write_C32(outstream, size);
     OutStream_Write_Bytes(outstream, buf, size);
-    Obj_Mimic(self->value, value);
+    Obj_Mimic(ivars->value, value);
 }
 
 void
 TextTermStepper_write_delta(TextTermStepper *self, OutStream *outstream,
                             Obj *value) {
+    TextTermStepperIVARS *const ivars = TextTermStepper_IVARS(self);
     CharBuf *new_value  = (CharBuf*)CERTIFY(value, CHARBUF);
-    CharBuf *last_value = (CharBuf*)self->value;
+    CharBuf *last_value = (CharBuf*)ivars->value;
     char    *new_text  = (char*)CB_Get_Ptr8(new_value);
     size_t   new_size  = CB_Get_Size(new_value);
     char    *last_text = (char*)CB_Get_Ptr8(last_value);
@@ -100,18 +105,19 @@ TextTermStepper_write_delta(TextTermStepper *self, OutStream *outstream,
     OutStream_Write_String(outstream, diff_start_str, diff_len);
 
     // Update value.
-    CB_Mimic((CharBuf*)self->value, value);
+    CB_Mimic((CharBuf*)ivars->value, value);
 }
 
 void
 TextTermStepper_read_key_frame(TextTermStepper *self, InStream *instream) {
+    TextTermStepperIVARS *const ivars = TextTermStepper_IVARS(self);
     const uint32_t text_len = InStream_Read_C32(instream);
 
     // Allocate space.
-    if (self->value == NULL) {
-        self->value = (Obj*)CB_new(text_len);
+    if (ivars->value == NULL) {
+        ivars->value = (Obj*)CB_new(text_len);
     }
-    CharBuf *value = (CharBuf*)self->value;
+    CharBuf *value = (CharBuf*)ivars->value;
     char *ptr      = CB_Grow(value, text_len);
 
     // Set the value text.
@@ -129,15 +135,16 @@ TextTermStepper_read_key_frame(TextTermStepper *self, InStream *instream) {
 
 void
 TextTermStepper_read_delta(TextTermStepper *self, InStream *instream) {
+    TextTermStepperIVARS *const ivars = TextTermStepper_IVARS(self);
     const uint32_t text_overlap     = InStream_Read_C32(instream);
     const uint32_t finish_chars_len = InStream_Read_C32(instream);
     const uint32_t total_text_len   = text_overlap + finish_chars_len;
 
     // Allocate space.
-    if (self->value == NULL) {
-        self->value = (Obj*)CB_new(total_text_len);
+    if (ivars->value == NULL) {
+        ivars->value = (Obj*)CB_new(total_text_len);
     }
-    CharBuf *value = (CharBuf*)self->value;
+    CharBuf *value = (CharBuf*)ivars->value;
     char *ptr      = CB_Grow(value, total_text_len);
 
     // Set the value text.


[lucy-commits] [20/34] git commit: refs/heads/master - Migrate LucyX classes to IVARS.

Posted by ma...@apache.org.
Migrate LucyX classes to IVARS.

Change all the LucyX class implementations to access instance vars via an IVARS
struct rather than via `self`.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/5d0cc098
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/5d0cc098
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/5d0cc098

Branch: refs/heads/master
Commit: 5d0cc0985e97fdc6a15274cfe8aa20dd3a71f6e5
Parents: 811358d
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Mon Jul 1 14:23:39 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 16:08:43 2013 -0700

----------------------------------------------------------------------
 core/LucyX/Search/FilterMatcher.c    |  23 +++--
 core/LucyX/Search/MockMatcher.c      |  31 +++---
 core/LucyX/Search/ProximityMatcher.c | 112 ++++++++++++----------
 core/LucyX/Search/ProximityQuery.c   | 152 +++++++++++++++++-------------
 4 files changed, 178 insertions(+), 140 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/5d0cc098/core/LucyX/Search/FilterMatcher.c
----------------------------------------------------------------------
diff --git a/core/LucyX/Search/FilterMatcher.c b/core/LucyX/Search/FilterMatcher.c
index a510ca9..cb26c0c 100644
--- a/core/LucyX/Search/FilterMatcher.c
+++ b/core/LucyX/Search/FilterMatcher.c
@@ -28,37 +28,40 @@ FilterMatcher_new(BitVector *bits, int32_t doc_max) {
 FilterMatcher*
 FilterMatcher_init(FilterMatcher *self, BitVector *bits, int32_t doc_max) {
     Matcher_init((Matcher*)self);
+    FilterMatcherIVARS *const ivars = FilterMatcher_IVARS(self);
 
     // Init.
-    self->doc_id       = 0;
+    ivars->doc_id       = 0;
 
     // Assign.
-    self->bits         = (BitVector*)INCREF(bits);
-    self->doc_max      = doc_max;
+    ivars->bits         = (BitVector*)INCREF(bits);
+    ivars->doc_max      = doc_max;
 
     return self;
 }
 
 void
 FilterMatcher_destroy(FilterMatcher *self) {
-    DECREF(self->bits);
+    FilterMatcherIVARS *const ivars = FilterMatcher_IVARS(self);
+    DECREF(ivars->bits);
     SUPER_DESTROY(self, FILTERMATCHER);
 }
 
 int32_t
 FilterMatcher_next(FilterMatcher* self) {
+    FilterMatcherIVARS *const ivars = FilterMatcher_IVARS(self);
     do {
-        if (++self->doc_id > self->doc_max) {
-            self->doc_id--;
+        if (++ivars->doc_id > ivars->doc_max) {
+            ivars->doc_id--;
             return 0;
         }
-    } while (!BitVec_Get(self->bits, self->doc_id));
-    return self->doc_id;
+    } while (!BitVec_Get(ivars->bits, ivars->doc_id));
+    return ivars->doc_id;
 }
 
 int32_t
 FilterMatcher_skip_to(FilterMatcher* self, int32_t target) {
-    self->doc_id = target - 1;
+    FilterMatcher_IVARS(self)->doc_id = target - 1;
     return FilterMatcher_next(self);
 }
 
@@ -70,7 +73,7 @@ FilterMatcher_score(FilterMatcher* self) {
 
 int32_t
 FilterMatcher_get_doc_id(FilterMatcher* self) {
-    return self->doc_id;
+    return FilterMatcher_IVARS(self)->doc_id;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/5d0cc098/core/LucyX/Search/MockMatcher.c
----------------------------------------------------------------------
diff --git a/core/LucyX/Search/MockMatcher.c b/core/LucyX/Search/MockMatcher.c
index 9153cae..c7b77a6 100644
--- a/core/LucyX/Search/MockMatcher.c
+++ b/core/LucyX/Search/MockMatcher.c
@@ -28,41 +28,46 @@ MockMatcher_new(I32Array *doc_ids, ByteBuf *scores) {
 MockMatcher*
 MockMatcher_init(MockMatcher *self, I32Array *doc_ids, ByteBuf *scores) {
     Matcher_init((Matcher*)self);
-    self->tick    = -1;
-    self->size    = I32Arr_Get_Size(doc_ids);
-    self->doc_ids = (I32Array*)INCREF(doc_ids);
-    self->scores  = (ByteBuf*)INCREF(scores);
+    MockMatcherIVARS *const ivars = MockMatcher_IVARS(self);
+    ivars->tick    = -1;
+    ivars->size    = I32Arr_Get_Size(doc_ids);
+    ivars->doc_ids = (I32Array*)INCREF(doc_ids);
+    ivars->scores  = (ByteBuf*)INCREF(scores);
     return self;
 }
 
 void
 MockMatcher_destroy(MockMatcher *self) {
-    DECREF(self->doc_ids);
-    DECREF(self->scores);
+    MockMatcherIVARS *const ivars = MockMatcher_IVARS(self);
+    DECREF(ivars->doc_ids);
+    DECREF(ivars->scores);
     SUPER_DESTROY(self, MOCKMATCHER);
 }
 
 int32_t
 MockMatcher_next(MockMatcher* self) {
-    if (++self->tick >= (int32_t)self->size) {
-        self->tick--;
+    MockMatcherIVARS *const ivars = MockMatcher_IVARS(self);
+    if (++ivars->tick >= (int32_t)ivars->size) {
+        ivars->tick--;
         return 0;
     }
-    return I32Arr_Get(self->doc_ids, self->tick);
+    return I32Arr_Get(ivars->doc_ids, ivars->tick);
 }
 
 float
 MockMatcher_score(MockMatcher* self) {
-    if (!self->scores) {
+    MockMatcherIVARS *const ivars = MockMatcher_IVARS(self);
+    if (!ivars->scores) {
         THROW(ERR, "Can't call Score() unless scores supplied");
     }
-    float *raw_scores = (float*)BB_Get_Buf(self->scores);
-    return raw_scores[self->tick];
+    float *raw_scores = (float*)BB_Get_Buf(ivars->scores);
+    return raw_scores[ivars->tick];
 }
 
 int32_t
 MockMatcher_get_doc_id(MockMatcher* self) {
-    return I32Arr_Get(self->doc_ids, self->tick);
+    MockMatcherIVARS *const ivars = MockMatcher_IVARS(self);
+    return I32Arr_Get(ivars->doc_ids, ivars->tick);
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/5d0cc098/core/LucyX/Search/ProximityMatcher.c
----------------------------------------------------------------------
diff --git a/core/LucyX/Search/ProximityMatcher.c b/core/LucyX/Search/ProximityMatcher.c
index c7cc495..9918620 100644
--- a/core/LucyX/Search/ProximityMatcher.c
+++ b/core/LucyX/Search/ProximityMatcher.c
@@ -39,57 +39,60 @@ ProximityMatcher*
 ProximityMatcher_init(ProximityMatcher *self, Similarity *similarity,
                       VArray *plists, Compiler *compiler, uint32_t within) {
     Matcher_init((Matcher*)self);
+    ProximityMatcherIVARS *const ivars = ProximityMatcher_IVARS(self);
 
     // Init.
-    self->anchor_set       = BB_new(0);
-    self->proximity_freq   = 0.0;
-    self->proximity_boost  = 0.0;
-    self->first_time       = true;
-    self->more             = true;
-    self->within           = within;
+    ivars->anchor_set       = BB_new(0);
+    ivars->proximity_freq   = 0.0;
+    ivars->proximity_boost  = 0.0;
+    ivars->first_time       = true;
+    ivars->more             = true;
+    ivars->within           = within;
 
     // Extract PostingLists out of VArray into local C array for quick access.
-    self->num_elements = VA_Get_Size(plists);
-    self->plists = (PostingList**)MALLOCATE(
-                       self->num_elements * sizeof(PostingList*));
-    for (size_t i = 0; i < self->num_elements; i++) {
+    ivars->num_elements = VA_Get_Size(plists);
+    ivars->plists = (PostingList**)MALLOCATE(
+                       ivars->num_elements * sizeof(PostingList*));
+    for (size_t i = 0; i < ivars->num_elements; i++) {
         PostingList *const plist
             = (PostingList*)CERTIFY(VA_Fetch(plists, i), POSTINGLIST);
         if (plist == NULL) {
             THROW(ERR, "Missing element %u32", i);
         }
-        self->plists[i] = (PostingList*)INCREF(plist);
+        ivars->plists[i] = (PostingList*)INCREF(plist);
     }
 
     // Assign.
-    self->sim       = (Similarity*)INCREF(similarity);
-    self->compiler  = (Compiler*)INCREF(compiler);
-    self->weight    = Compiler_Get_Weight(compiler);
+    ivars->sim       = (Similarity*)INCREF(similarity);
+    ivars->compiler  = (Compiler*)INCREF(compiler);
+    ivars->weight    = Compiler_Get_Weight(compiler);
 
     return self;
 }
 
 void
 ProximityMatcher_destroy(ProximityMatcher *self) {
-    if (self->plists) {
-        for (size_t i = 0; i < self->num_elements; i++) {
-            DECREF(self->plists[i]);
+    ProximityMatcherIVARS *const ivars = ProximityMatcher_IVARS(self);
+    if (ivars->plists) {
+        for (size_t i = 0; i < ivars->num_elements; i++) {
+            DECREF(ivars->plists[i]);
         }
-        FREEMEM(self->plists);
+        FREEMEM(ivars->plists);
     }
-    DECREF(self->sim);
-    DECREF(self->anchor_set);
-    DECREF(self->compiler);
+    DECREF(ivars->sim);
+    DECREF(ivars->anchor_set);
+    DECREF(ivars->compiler);
     SUPER_DESTROY(self, PROXIMITYMATCHER);
 }
 
 int32_t
 ProximityMatcher_next(ProximityMatcher *self) {
-    if (self->first_time) {
+    ProximityMatcherIVARS *const ivars = ProximityMatcher_IVARS(self);
+    if (ivars->first_time) {
         return ProximityMatcher_Advance(self, 1);
     }
-    else if (self->more) {
-        const int32_t target = PList_Get_Doc_ID(self->plists[0]) + 1;
+    else if (ivars->more) {
+        const int32_t target = PList_Get_Doc_ID(ivars->plists[0]) + 1;
         return ProximityMatcher_Advance(self, target);
     }
     else {
@@ -99,25 +102,26 @@ ProximityMatcher_next(ProximityMatcher *self) {
 
 int32_t
 ProximityMatcher_advance(ProximityMatcher *self, int32_t target) {
-    PostingList **const plists       = self->plists;
-    const uint32_t      num_elements = self->num_elements;
+    ProximityMatcherIVARS *const ivars = ProximityMatcher_IVARS(self);
+    PostingList **const plists       = ivars->plists;
+    const uint32_t      num_elements = ivars->num_elements;
     int32_t             highest      = 0;
 
     // Reset match variables to indicate no match.  New values will be
     // assigned if a match succeeds.
-    self->proximity_freq = 0.0;
-    self->doc_id         = 0;
+    ivars->proximity_freq = 0.0;
+    ivars->doc_id         = 0;
 
     // Find the lowest possible matching doc ID greater than the current doc
     // ID.  If any one of the PostingLists is exhausted, we're done.
-    if (self->first_time) {
-        self->first_time = false;
+    if (ivars->first_time) {
+        ivars->first_time = false;
 
         // On the first call to Advance(), advance all PostingLists.
-        for (size_t i = 0, max = self->num_elements; i < max; i++) {
+        for (size_t i = 0, max = ivars->num_elements; i < max; i++) {
             int32_t candidate = PList_Advance(plists[i], target);
             if (!candidate) {
-                self->more = false;
+                ivars->more = false;
                 return 0;
             }
             else if (candidate > highest) {
@@ -131,7 +135,7 @@ ProximityMatcher_advance(ProximityMatcher *self, int32_t target) {
         // becomes the minimum target which all the others must move up to.
         highest = PList_Advance(plists[0], target);
         if (highest == 0) {
-            self->more = false;
+            ivars->more = false;
             return 0;
         }
     }
@@ -156,7 +160,7 @@ ProximityMatcher_advance(ProximityMatcher *self, int32_t target) {
 
                 // If this PostingList is exhausted, we're done.
                 if (candidate == 0) {
-                    self->more = false;
+                    ivars->more = false;
                     return 0;
                 }
 
@@ -178,14 +182,14 @@ ProximityMatcher_advance(ProximityMatcher *self, int32_t target) {
         // If we've found a doc with all terms in it, see if they form a
         // phrase.
         if (agreement && highest >= target) {
-            self->proximity_freq = ProximityMatcher_Calc_Proximity_Freq(self);
-            if (self->proximity_freq == 0.0) {
+            ivars->proximity_freq = ProximityMatcher_Calc_Proximity_Freq(self);
+            if (ivars->proximity_freq == 0.0) {
                 // No phrase.  Move on to another doc.
                 target += 1;
             }
             else {
                 // Success!
-                self->doc_id = highest;
+                ivars->doc_id = highest;
                 return highest;
             }
         }
@@ -246,7 +250,8 @@ DONE:
 
 float
 ProximityMatcher_calc_proximity_freq(ProximityMatcher *self) {
-    PostingList **const plists   = self->plists;
+    ProximityMatcherIVARS *const ivars = ProximityMatcher_IVARS(self);
+    PostingList **const plists = ivars->plists;
 
     /* Create a overwriteable "anchor set" from the first posting.
      *
@@ -268,25 +273,27 @@ ProximityMatcher_calc_proximity_freq(ProximityMatcher *self) {
      * is our proximity freq.
      */
     ScorePosting *posting = (ScorePosting*)PList_Get_Posting(plists[0]);
-    uint32_t anchors_remaining = posting->freq;
+    ScorePostingIVARS *const post_ivars = ScorePost_IVARS(posting);
+    uint32_t anchors_remaining = post_ivars->freq;
     if (!anchors_remaining) { return 0.0f; }
 
     size_t    amount        = anchors_remaining * sizeof(uint32_t);
-    uint32_t *anchors_start = (uint32_t*)BB_Grow(self->anchor_set, amount);
+    uint32_t *anchors_start = (uint32_t*)BB_Grow(ivars->anchor_set, amount);
     uint32_t *anchors_end   = anchors_start + anchors_remaining;
-    memcpy(anchors_start, posting->prox, amount);
+    memcpy(anchors_start, post_ivars->prox, amount);
 
     // Match the positions of other terms against the anchor set.
-    for (uint32_t i = 1, max = self->num_elements; i < max; i++) {
+    for (uint32_t i = 1, max = ivars->num_elements; i < max; i++) {
         // Get the array of positions for the next term.  Unlike the anchor
         // set (which is a copy), these won't be overwritten.
-        ScorePosting *posting = (ScorePosting*)PList_Get_Posting(plists[i]);
-        uint32_t *candidates_start = posting->prox;
-        uint32_t *candidates_end   = candidates_start + posting->freq;
+        ScorePosting *next_post = (ScorePosting*)PList_Get_Posting(plists[i]);
+        ScorePostingIVARS *const next_post_ivars = ScorePost_IVARS(next_post);
+        uint32_t *candidates_start = next_post_ivars->prox;
+        uint32_t *candidates_end   = candidates_start + next_post_ivars->freq;
 
         // Splice out anchors that don't match the next term.  Bail out if
         // we've eliminated all possible anchors.
-        if (self->within == 1) { // exact phrase match
+        if (ivars->within == 1) { // exact phrase match
             anchors_remaining = SI_winnow_anchors(anchors_start, anchors_end,
                                                   candidates_start,
                                                   candidates_end, i, 1);
@@ -295,7 +302,7 @@ ProximityMatcher_calc_proximity_freq(ProximityMatcher *self) {
             anchors_remaining = SI_winnow_anchors(anchors_start, anchors_end,
                                                   candidates_start,
                                                   candidates_end, i,
-                                                  self->within);
+                                                  ivars->within);
         }
         if (!anchors_remaining) { return 0.0f; }
 
@@ -309,15 +316,16 @@ ProximityMatcher_calc_proximity_freq(ProximityMatcher *self) {
 
 int32_t
 ProximityMatcher_get_doc_id(ProximityMatcher *self) {
-    return self->doc_id;
+    return ProximityMatcher_IVARS(self)->doc_id;
 }
 
 float
 ProximityMatcher_score(ProximityMatcher *self) {
-    ScorePosting *posting = (ScorePosting*)PList_Get_Posting(self->plists[0]);
-    float score = Sim_TF(self->sim, self->proximity_freq)
-                  * self->weight
-                  * posting->weight;
+    ProximityMatcherIVARS *const ivars = ProximityMatcher_IVARS(self);
+    ScorePosting *posting = (ScorePosting*)PList_Get_Posting(ivars->plists[0]);
+    float score = Sim_TF(ivars->sim, ivars->proximity_freq)
+                  * ivars->weight
+                  * ScorePost_IVARS(posting)->weight;
     return score;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/5d0cc098/core/LucyX/Search/ProximityQuery.c
----------------------------------------------------------------------
diff --git a/core/LucyX/Search/ProximityQuery.c b/core/LucyX/Search/ProximityQuery.c
index 7cd5bdc..3e8a435 100644
--- a/core/LucyX/Search/ProximityQuery.c
+++ b/core/LucyX/Search/ProximityQuery.c
@@ -58,8 +58,9 @@ ProximityQuery_init(ProximityQuery *self, const CharBuf *field, VArray *terms,
 
 void
 ProximityQuery_destroy(ProximityQuery *self) {
-    DECREF(self->terms);
-    DECREF(self->field);
+    ProximityQueryIVARS *const ivars = ProximityQuery_IVARS(self);
+    DECREF(ivars->terms);
+    DECREF(ivars->field);
     SUPER_DESTROY(self, PROXIMITYQUERY);
 }
 
@@ -67,21 +68,23 @@ static ProximityQuery*
 S_do_init(ProximityQuery *self, CharBuf *field, VArray *terms, float boost,
           uint32_t within) {
     Query_init((Query*)self, boost);
+    ProximityQueryIVARS *const ivars = ProximityQuery_IVARS(self);
     for (uint32_t i = 0, max = VA_Get_Size(terms); i < max; i++) {
         CERTIFY(VA_Fetch(terms, i), OBJ);
     }
-    self->field  = field;
-    self->terms  = terms;
-    self->within = within;
+    ivars->field  = field;
+    ivars->terms  = terms;
+    ivars->within = within;
     return self;
 }
 
 void
 ProximityQuery_serialize(ProximityQuery *self, OutStream *outstream) {
-    OutStream_Write_F32(outstream, self->boost);
-    Freezer_serialize_charbuf(self->field, outstream);
-    Freezer_serialize_varray(self->terms, outstream);
-    OutStream_Write_C32(outstream, self->within);
+    ProximityQueryIVARS *const ivars = ProximityQuery_IVARS(self);
+    OutStream_Write_F32(outstream, ivars->boost);
+    Freezer_serialize_charbuf(ivars->field, outstream);
+    Freezer_serialize_varray(ivars->terms, outstream);
+    OutStream_Write_C32(outstream, ivars->within);
 }
 
 ProximityQuery*
@@ -95,27 +98,31 @@ ProximityQuery_deserialize(ProximityQuery *self, InStream *instream) {
 
 bool
 ProximityQuery_equals(ProximityQuery *self, Obj *other) {
-    ProximityQuery *twin = (ProximityQuery*)other;
-    if (twin == self)                     { return true; }
+    if ((ProximityQuery*)other == self)   { return true; }
     if (!Obj_Is_A(other, PROXIMITYQUERY)) { return false; }
-    if (self->boost != twin->boost)       { return false; }
-    if (self->field && !twin->field)      { return false; }
-    if (!self->field && twin->field)      { return false; }
-    if (self->field && !CB_Equals(self->field, (Obj*)twin->field)) {
+    ProximityQueryIVARS *const ivars = ProximityQuery_IVARS(self);
+    ProximityQueryIVARS *const ovars
+        = ProximityQuery_IVARS((ProximityQuery*)other);
+
+    if (ivars->boost != ovars->boost)       { return false; }
+    if (ivars->field && !ovars->field)      { return false; }
+    if (!ivars->field && ovars->field)      { return false; }
+    if (ivars->field && !CB_Equals(ivars->field, (Obj*)ovars->field)) {
         return false;
     }
-    if (!VA_Equals(twin->terms, (Obj*)self->terms)) { return false; }
-    if (self->within != twin->within)               { return false; }
+    if (!VA_Equals(ovars->terms, (Obj*)ivars->terms)) { return false; }
+    if (ivars->within != ovars->within)               { return false; }
     return true;
 }
 
 CharBuf*
 ProximityQuery_to_string(ProximityQuery *self) {
-    uint32_t num_terms = VA_Get_Size(self->terms);
-    CharBuf *retval = CB_Clone(self->field);
+    ProximityQueryIVARS *const ivars = ProximityQuery_IVARS(self);
+    uint32_t num_terms = VA_Get_Size(ivars->terms);
+    CharBuf *retval = CB_Clone(ivars->field);
     CB_Cat_Trusted_Str(retval, ":\"", 2);
     for (uint32_t i = 0; i < num_terms; i++) {
-        Obj *term = VA_Fetch(self->terms, i);
+        Obj *term = VA_Fetch(ivars->terms, i);
         CharBuf *term_string = Obj_To_String(term);
         CB_Cat(retval, term_string);
         DECREF(term_string);
@@ -124,18 +131,19 @@ ProximityQuery_to_string(ProximityQuery *self) {
         }
     }
     CB_Cat_Trusted_Str(retval, "\"", 1);
-    CB_catf(retval, "~%u32", self->within);
+    CB_catf(retval, "~%u32", ivars->within);
     return retval;
 }
 
 Compiler*
 ProximityQuery_make_compiler(ProximityQuery *self, Searcher *searcher,
                              float boost, bool subordinate) {
-    if (VA_Get_Size(self->terms) == 1) {
+    ProximityQueryIVARS *const ivars = ProximityQuery_IVARS(self);
+    if (VA_Get_Size(ivars->terms) == 1) {
         // Optimize for one-term "phrases".
-        Obj *term = VA_Fetch(self->terms, 0);
-        TermQuery *term_query = TermQuery_new(self->field, term);
-        TermQuery_Set_Boost(term_query, self->boost);
+        Obj *term = VA_Fetch(ivars->terms, 0);
+        TermQuery *term_query = TermQuery_new(ivars->field, term);
+        TermQuery_Set_Boost(term_query, ivars->boost);
         TermCompiler *term_compiler
             = (TermCompiler*)TermQuery_Make_Compiler(term_query, searcher,
                                                      boost, subordinate);
@@ -144,7 +152,7 @@ ProximityQuery_make_compiler(ProximityQuery *self, Searcher *searcher,
     }
     else {
         ProximityCompiler *compiler
-            = ProximityCompiler_new(self, searcher, boost, self->within);
+            = ProximityCompiler_new(self, searcher, boost, ivars->within);
         if (!subordinate) {
             ProximityCompiler_Normalize(compiler);
         }
@@ -154,17 +162,17 @@ ProximityQuery_make_compiler(ProximityQuery *self, Searcher *searcher,
 
 CharBuf*
 ProximityQuery_get_field(ProximityQuery *self) {
-    return self->field;
+    return ProximityQuery_IVARS(self)->field;
 }
 
 VArray*
 ProximityQuery_get_terms(ProximityQuery *self) {
-    return self->terms;
+    return ProximityQuery_IVARS(self)->terms;
 }
 
 uint32_t
 ProximityQuery_get_within(ProximityQuery  *self) {
-    return self->within;
+    return ProximityQuery_IVARS(self)->within;
 }
 
 /*********************************************************************/
@@ -180,11 +188,13 @@ ProximityCompiler_new(ProximityQuery *parent, Searcher *searcher, float boost,
 ProximityCompiler*
 ProximityCompiler_init(ProximityCompiler *self, ProximityQuery *parent,
                        Searcher *searcher, float boost, uint32_t within) {
+    ProximityCompilerIVARS *const ivars = ProximityCompiler_IVARS(self);
+    ProximityQueryIVARS *const parent_ivars = ProximityQuery_IVARS(parent);
     Schema     *schema = Searcher_Get_Schema(searcher);
-    Similarity *sim    = Schema_Fetch_Sim(schema, parent->field);
-    VArray     *terms  = parent->terms;
+    Similarity *sim    = Schema_Fetch_Sim(schema, parent_ivars->field);
+    VArray     *terms  = parent_ivars->terms;
 
-    self->within = within;
+    ivars->within = within;
 
     // Try harder to find a Similarity if necessary.
     if (!sim) { sim = Schema_Get_Similarity(schema); }
@@ -193,16 +203,17 @@ ProximityCompiler_init(ProximityCompiler *self, ProximityQuery *parent,
     Compiler_init((Compiler*)self, (Query*)parent, searcher, sim, boost);
 
     // Store IDF for the phrase.
-    self->idf = 0;
+    ivars->idf = 0;
     for (uint32_t i = 0, max = VA_Get_Size(terms); i < max; i++) {
         Obj *term = VA_Fetch(terms, i);
         int32_t doc_max  = Searcher_Doc_Max(searcher);
-        int32_t doc_freq = Searcher_Doc_Freq(searcher, parent->field, term);
-        self->idf += Sim_IDF(sim, doc_freq, doc_max);
+        int32_t doc_freq
+            = Searcher_Doc_Freq(searcher, parent_ivars->field,term);
+        ivars->idf += Sim_IDF(sim, doc_freq, doc_max);
     }
 
     // Calculate raw weight.
-    self->raw_weight = self->idf * self->boost;
+    ivars->raw_weight = ivars->idf * ivars->boost;
 
     return self;
 }
@@ -212,11 +223,12 @@ ProximityCompiler_serialize(ProximityCompiler *self, OutStream *outstream) {
     ProximityCompiler_Serialize_t super_serialize
             = SUPER_METHOD_PTR(PROXIMITYCOMPILER, Lucy_ProximityCompiler_Serialize);
     super_serialize(self, outstream);
-    OutStream_Write_F32(outstream, self->idf);
-    OutStream_Write_F32(outstream, self->raw_weight);
-    OutStream_Write_F32(outstream, self->query_norm_factor);
-    OutStream_Write_F32(outstream, self->normalized_weight);
-    OutStream_Write_C32(outstream, self->within);
+    ProximityCompilerIVARS *const ivars = ProximityCompiler_IVARS(self);
+    OutStream_Write_F32(outstream, ivars->idf);
+    OutStream_Write_F32(outstream, ivars->raw_weight);
+    OutStream_Write_F32(outstream, ivars->query_norm_factor);
+    OutStream_Write_F32(outstream, ivars->normalized_weight);
+    OutStream_Write_C32(outstream, ivars->within);
 }
 
 ProximityCompiler*
@@ -224,49 +236,57 @@ ProximityCompiler_deserialize(ProximityCompiler *self, InStream *instream) {
     ProximityCompiler_Deserialize_t super_deserialize
             = SUPER_METHOD_PTR(PROXIMITYCOMPILER, Lucy_ProximityCompiler_Deserialize);
     self = super_deserialize(self, instream);
-    self->idf               = InStream_Read_F32(instream);
-    self->raw_weight        = InStream_Read_F32(instream);
-    self->query_norm_factor = InStream_Read_F32(instream);
-    self->normalized_weight = InStream_Read_F32(instream);
-    self->within            = InStream_Read_C32(instream);
+    ProximityCompilerIVARS *const ivars = ProximityCompiler_IVARS(self);
+    ivars->idf               = InStream_Read_F32(instream);
+    ivars->raw_weight        = InStream_Read_F32(instream);
+    ivars->query_norm_factor = InStream_Read_F32(instream);
+    ivars->normalized_weight = InStream_Read_F32(instream);
+    ivars->within            = InStream_Read_C32(instream);
     return self;
 }
 
 bool
 ProximityCompiler_equals(ProximityCompiler *self, Obj *other) {
-    ProximityCompiler *twin = (ProximityCompiler*)other;
-    if (!Obj_Is_A(other, PROXIMITYCOMPILER))                { return false; }
-    if (!Compiler_equals((Compiler*)self, other))           { return false; }
-    if (self->idf != twin->idf)                             { return false; }
-    if (self->raw_weight != twin->raw_weight)               { return false; }
-    if (self->query_norm_factor != twin->query_norm_factor) { return false; }
-    if (self->normalized_weight != twin->normalized_weight) { return false; }
-    if (self->within            != twin->within)            { return false; }
+    if ((ProximityCompiler*)other == self)        { return true; }
+    if (!Obj_Is_A(other, PROXIMITYCOMPILER))      { return false; }
+    if (!Compiler_equals((Compiler*)self, other)) { return false; }
+    ProximityCompilerIVARS *const ivars = ProximityCompiler_IVARS(self);
+    ProximityCompilerIVARS *const ovars
+        = ProximityCompiler_IVARS((ProximityCompiler*)other);
+    if (ivars->idf != ovars->idf)                             { return false; }
+    if (ivars->raw_weight != ovars->raw_weight)               { return false; }
+    if (ivars->query_norm_factor != ovars->query_norm_factor) { return false; }
+    if (ivars->normalized_weight != ovars->normalized_weight) { return false; }
+    if (ivars->within            != ovars->within)            { return false; }
     return true;
 }
 
 float
 ProximityCompiler_get_weight(ProximityCompiler *self) {
-    return self->normalized_weight;
+    return ProximityCompiler_IVARS(self)->normalized_weight;
 }
 
 float
 ProximityCompiler_sum_of_squared_weights(ProximityCompiler *self) {
-    return self->raw_weight * self->raw_weight;
+    ProximityCompilerIVARS *const ivars = ProximityCompiler_IVARS(self);
+    return ivars->raw_weight * ivars->raw_weight;
 }
 
 void
 ProximityCompiler_apply_norm_factor(ProximityCompiler *self, float factor) {
-    self->query_norm_factor = factor;
-    self->normalized_weight = self->raw_weight * self->idf * factor;
+    ProximityCompilerIVARS *const ivars = ProximityCompiler_IVARS(self);
+    ivars->query_norm_factor = factor;
+    ivars->normalized_weight = ivars->raw_weight * ivars->idf * factor;
 }
 
 Matcher*
 ProximityCompiler_make_matcher(ProximityCompiler *self, SegReader *reader,
                                bool need_score) {
+    ProximityCompilerIVARS *const ivars = ProximityCompiler_IVARS(self);
     UNUSED_VAR(need_score);
-    ProximityQuery *const parent = (ProximityQuery*)self->parent;
-    VArray *const      terms     = parent->terms;
+    ProximityQueryIVARS *const parent_ivars
+        = ProximityQuery_IVARS((ProximityQuery*)ivars->parent);
+    VArray *const      terms     = parent_ivars->terms;
     uint32_t           num_terms = VA_Get_Size(terms);
 
     // Bail if there are no terms.
@@ -292,7 +312,7 @@ ProximityCompiler_make_matcher(ProximityCompiler *self, SegReader *reader,
     for (uint32_t i = 0; i < num_terms; i++) {
         Obj *term = VA_Fetch(terms, i);
         PostingList *plist
-            = PListReader_Posting_List(plist_reader, parent->field, term);
+            = PListReader_Posting_List(plist_reader, parent_ivars->field, term);
 
         // Bail if any one of the terms isn't in the index.
         if (!plist || !PList_Get_Doc_Freq(plist)) {
@@ -304,7 +324,7 @@ ProximityCompiler_make_matcher(ProximityCompiler *self, SegReader *reader,
     }
 
     Matcher *retval
-        = (Matcher*)ProximityMatcher_new(sim, plists, (Compiler*)self, self->within);
+        = (Matcher*)ProximityMatcher_new(sim, plists, (Compiler*)self, ivars->within);
     DECREF(plists);
     return retval;
 }
@@ -312,15 +332,17 @@ ProximityCompiler_make_matcher(ProximityCompiler *self, SegReader *reader,
 VArray*
 ProximityCompiler_highlight_spans(ProximityCompiler *self, Searcher *searcher,
                                   DocVector *doc_vec, const CharBuf *field) {
-    ProximityQuery *const parent = (ProximityQuery*)self->parent;
-    VArray         *const terms  = parent->terms;
+    ProximityCompilerIVARS *const ivars = ProximityCompiler_IVARS(self);
+    ProximityQueryIVARS *const parent_ivars
+        = ProximityQuery_IVARS((ProximityQuery*)ivars->parent);
+    VArray         *const terms  = parent_ivars->terms;
     VArray         *const spans  = VA_new(0);
     const uint32_t  num_terms    = VA_Get_Size(terms);
     UNUSED_VAR(searcher);
 
     // Bail if no terms or field doesn't match.
     if (!num_terms) { return spans; }
-    if (!CB_Equals(field, (Obj*)parent->field)) { return spans; }
+    if (!CB_Equals(field, (Obj*)parent_ivars->field)) { return spans; }
 
     VArray      *term_vectors    = VA_new(num_terms);
     BitVector   *posit_vec       = BitVec_new(0);


[lucy-commits] [21/34] git commit: refs/heads/master - Migrate Perl host code to IVARS.

Posted by ma...@apache.org.
Migrate Perl host code to IVARS.

Migrate host-specific code for Perl to use IVARS rather than access struct
members through `self`.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/811358d9
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/811358d9
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/811358d9

Branch: refs/heads/master
Commit: 811358d9f87133f6987eb64259f4b4bbcaafddc2
Parents: ff0ec8d
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Mon Jul 1 08:45:46 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 16:08:43 2013 -0700

----------------------------------------------------------------------
 perl/xs/Lucy/Analysis/RegexTokenizer.c | 27 +++++++------
 perl/xs/Lucy/Document/Doc.c            | 60 ++++++++++++++++-------------
 perl/xs/Lucy/Index/DocReader.c         |  7 ++--
 perl/xs/Lucy/Index/Inverter.c          | 27 +++++++------
 4 files changed, 69 insertions(+), 52 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/811358d9/perl/xs/Lucy/Analysis/RegexTokenizer.c
----------------------------------------------------------------------
diff --git a/perl/xs/Lucy/Analysis/RegexTokenizer.c b/perl/xs/Lucy/Analysis/RegexTokenizer.c
index d175b59..86738fc 100644
--- a/perl/xs/Lucy/Analysis/RegexTokenizer.c
+++ b/perl/xs/Lucy/Analysis/RegexTokenizer.c
@@ -42,6 +42,7 @@ lucy_RegexTokenizer*
 lucy_RegexTokenizer_init(lucy_RegexTokenizer *self,
                          const cfish_CharBuf *pattern) {
     lucy_Analyzer_init((lucy_Analyzer*)self);
+    lucy_RegexTokenizerIVARS *const ivars = lucy_RegexTokenizer_IVARS(self);
     #define DEFAULT_PATTERN "\\w+(?:['\\x{2019}]\\w+)*"
     if (pattern) {
         if (Cfish_CB_Find_Str(pattern, "\\p", 2) != -1
@@ -50,15 +51,15 @@ lucy_RegexTokenizer_init(lucy_RegexTokenizer *self,
             CFISH_DECREF(self);
             THROW(CFISH_ERR, "\\p and \\P constructs forbidden");
         }
-        self->pattern = Cfish_CB_Clone(pattern);
+        ivars->pattern = Cfish_CB_Clone(pattern);
     }
     else {
-        self->pattern = cfish_CB_new_from_trusted_utf8(
+        ivars->pattern = cfish_CB_new_from_trusted_utf8(
                             DEFAULT_PATTERN, sizeof(DEFAULT_PATTERN) - 1);
     }
 
     // Acquire a compiled regex engine for matching one token.
-    SV *token_re_sv = S_compile_token_re(self->pattern);
+    SV *token_re_sv = S_compile_token_re(ivars->pattern);
     S_set_token_re_but_not_pattern(self, SvRV(token_re_sv));
     SvREFCNT_dec(token_re_sv);
 
@@ -86,6 +87,7 @@ S_compile_token_re(const cfish_CharBuf *pattern) {
 
 static void
 S_set_token_re_but_not_pattern(lucy_RegexTokenizer *self, void *token_re) {
+    lucy_RegexTokenizerIVARS *const ivars = lucy_RegexTokenizer_IVARS(self);
 #if (PERL_VERSION > 10)
     REGEXP *rx = SvRX((SV*)token_re);
 #else
@@ -102,17 +104,18 @@ S_set_token_re_but_not_pattern(lucy_RegexTokenizer *self, void *token_re) {
         THROW(CFISH_ERR, "Failed to extract REGEXP from token_re '%s'",
               SvPV_nolen((SV*)token_re));
     }
-    if (self->token_re) { ReREFCNT_dec(((REGEXP*)self->token_re)); }
-    self->token_re = rx;
-    (void)ReREFCNT_inc(((REGEXP*)self->token_re));
+    if (ivars->token_re) { ReREFCNT_dec(((REGEXP*)ivars->token_re)); }
+    ivars->token_re = rx;
+    (void)ReREFCNT_inc(((REGEXP*)ivars->token_re));
 }
 
 static void
 S_set_pattern_from_token_re(lucy_RegexTokenizer *self, void *token_re) {
+    lucy_RegexTokenizerIVARS *const ivars = lucy_RegexTokenizer_IVARS(self);
     SV *rv = newRV((SV*)token_re);
     STRLEN len = 0;
     char *ptr = SvPVutf8((SV*)rv, len);
-    Cfish_CB_Mimic_Str(self->pattern, ptr, len);
+    Cfish_CB_Mimic_Str(ivars->pattern, ptr, len);
     SvREFCNT_dec(rv);
 }
 
@@ -125,8 +128,9 @@ lucy_RegexTokenizer_set_token_re(lucy_RegexTokenizer *self, void *token_re) {
 
 void
 lucy_RegexTokenizer_destroy(lucy_RegexTokenizer *self) {
-    CFISH_DECREF(self->pattern);
-    ReREFCNT_dec(((REGEXP*)self->token_re));
+    lucy_RegexTokenizerIVARS *const ivars = lucy_RegexTokenizer_IVARS(self);
+    CFISH_DECREF(ivars->pattern);
+    ReREFCNT_dec(((REGEXP*)ivars->token_re));
     CFISH_SUPER_DESTROY(self, LUCY_REGEXTOKENIZER);
 }
 
@@ -134,13 +138,14 @@ void
 lucy_RegexTokenizer_tokenize_str(lucy_RegexTokenizer *self,
                                  const char *string, size_t string_len,
                                  lucy_Inversion *inversion) {
+    lucy_RegexTokenizerIVARS *const ivars = lucy_RegexTokenizer_IVARS(self);
     uint32_t   num_code_points = 0;
     SV        *wrapper    = sv_newmortal();
 #if (PERL_VERSION > 10)
-    REGEXP    *rx         = (REGEXP*)self->token_re;
+    REGEXP    *rx         = (REGEXP*)ivars->token_re;
     regexp    *rx_struct  = (regexp*)SvANY(rx);
 #else
-    REGEXP    *rx         = (REGEXP*)self->token_re;
+    REGEXP    *rx         = (REGEXP*)ivars->token_re;
     regexp    *rx_struct  = rx;
 #endif
     char      *string_beg = (char*)string;

http://git-wip-us.apache.org/repos/asf/lucy/blob/811358d9/perl/xs/Lucy/Document/Doc.c
----------------------------------------------------------------------
diff --git a/perl/xs/Lucy/Document/Doc.c b/perl/xs/Lucy/Document/Doc.c
index c20c2b0..220a7bf 100644
--- a/perl/xs/Lucy/Document/Doc.c
+++ b/perl/xs/Lucy/Document/Doc.c
@@ -23,32 +23,36 @@
 
 lucy_Doc*
 lucy_Doc_init(lucy_Doc *self, void *fields, int32_t doc_id) {
+    lucy_DocIVARS *const ivars = lucy_Doc_IVARS(self);
     // Assign.
     if (fields) {
         if (SvTYPE((SV*)fields) != SVt_PVHV) { THROW(CFISH_ERR, "Not a hash"); }
-        self->fields = SvREFCNT_inc((SV*)fields);
+        ivars->fields = SvREFCNT_inc((SV*)fields);
     }
     else {
-        self->fields = newHV();
+        ivars->fields = newHV();
     }
-    self->doc_id = doc_id;
+    ivars->doc_id = doc_id;
 
     return self;
 }
 
 void
 lucy_Doc_set_fields(lucy_Doc *self, void *fields) {
-    if (self->fields) { SvREFCNT_dec((SV*)self->fields); }
-    self->fields = SvREFCNT_inc((SV*)fields);
+    lucy_DocIVARS *const ivars = lucy_Doc_IVARS(self);
+    if (ivars->fields) { SvREFCNT_dec((SV*)ivars->fields); }
+    ivars->fields = SvREFCNT_inc((SV*)fields);
 }
 
 uint32_t
 lucy_Doc_get_size(lucy_Doc *self) {
-    return self->fields ? HvKEYS((HV*)self->fields) : 0;
+    lucy_DocIVARS *const ivars = lucy_Doc_IVARS(self);
+    return ivars->fields ? HvKEYS((HV*)ivars->fields) : 0;
 }
 
 void
 lucy_Doc_store(lucy_Doc *self, const cfish_CharBuf *field, cfish_Obj *value) {
+    lucy_DocIVARS *const ivars = lucy_Doc_IVARS(self);
     char   *key      = (char*)Cfish_CB_Get_Ptr8(field);
     size_t  key_size = Cfish_CB_Get_Size(field);
     SV *key_sv = newSVpvn(key, key_size);
@@ -58,19 +62,20 @@ lucy_Doc_store(lucy_Doc *self, const cfish_CharBuf *field, cfish_Obj *value) {
                  ? XSBind_cb_to_sv((cfish_CharBuf*)value)
                  : (SV*)Cfish_Obj_To_Host(value);
     SvUTF8_on(key_sv);
-    (void)hv_store_ent((HV*)self->fields, key_sv, val_sv, 0);
+    (void)hv_store_ent((HV*)ivars->fields, key_sv, val_sv, 0);
     // TODO: make this a thread-local instead of creating it every time?
     SvREFCNT_dec(key_sv);
 }
 
 static SV*
 S_nfreeze_fields(lucy_Doc *self) {
+    lucy_DocIVARS *const ivars = lucy_Doc_IVARS(self);
     dSP;
     ENTER;
     SAVETMPS;
     EXTEND(SP, 1);
     PUSHMARK(SP);
-    mPUSHs((SV*)newRV_inc((SV*)self->fields));
+    mPUSHs((SV*)newRV_inc((SV*)ivars->fields));
     PUTBACK;
     call_pv("Storable::nfreeze", G_SCALAR);
     SPAGAIN;
@@ -84,7 +89,8 @@ S_nfreeze_fields(lucy_Doc *self) {
 
 void
 lucy_Doc_serialize(lucy_Doc *self, lucy_OutStream *outstream) {
-    Lucy_OutStream_Write_C32(outstream, self->doc_id);
+    lucy_DocIVARS *const ivars = lucy_Doc_IVARS(self);
+    Lucy_OutStream_Write_C32(outstream, ivars->doc_id);
     SV *frozen = S_nfreeze_fields(self);
     STRLEN len;
     char *buf = SvPV(frozen, len);
@@ -138,8 +144,9 @@ lucy_Doc_deserialize(lucy_Doc *self, lucy_InStream *instream) {
 cfish_Obj*
 lucy_Doc_extract(lucy_Doc *self, cfish_CharBuf *field,
                  cfish_ViewCharBuf *target) {
+    lucy_DocIVARS *const ivars = lucy_Doc_IVARS(self);
     cfish_Obj *retval = NULL;
-    SV **sv_ptr = hv_fetch((HV*)self->fields, (char*)Cfish_CB_Get_Ptr8(field),
+    SV **sv_ptr = hv_fetch((HV*)ivars->fields, (char*)Cfish_CB_Get_Ptr8(field),
                            Cfish_CB_Get_Size(field), 0);
 
     if (sv_ptr && XSBind_sv_defined(*sv_ptr)) {
@@ -170,13 +177,14 @@ lucy_Doc_to_host(lucy_Doc *self) {
 
 cfish_Hash*
 lucy_Doc_dump(lucy_Doc *self) {
+    lucy_DocIVARS *const ivars = lucy_Doc_IVARS(self);
     cfish_Hash *dump = cfish_Hash_new(0);
     Cfish_Hash_Store_Str(dump, "_class", 6,
                         (cfish_Obj*)Cfish_CB_Clone(Lucy_Doc_Get_Class_Name(self)));
     Cfish_Hash_Store_Str(dump, "doc_id", 7,
-                        (cfish_Obj*)cfish_CB_newf("%i32", self->doc_id));
+                        (cfish_Obj*)cfish_CB_newf("%i32", ivars->doc_id));
     Cfish_Hash_Store_Str(dump, "fields", 6,
-                        XSBind_perl_to_cfish((SV*)self->fields));
+                        XSBind_perl_to_cfish((SV*)ivars->fields));
     return dump;
 }
 
@@ -197,8 +205,9 @@ lucy_Doc_load(lucy_Doc *self, cfish_Obj *dump) {
     SV *fields_sv = XSBind_cfish_to_perl((cfish_Obj*)fields);
     CHY_UNUSED_VAR(self);
 
-    loaded->doc_id = (int32_t)Cfish_Obj_To_I64(doc_id);
-    loaded->fields  = SvREFCNT_inc(SvRV(fields_sv));
+    lucy_DocIVARS *const loaded_ivars = lucy_Doc_IVARS(loaded);
+    loaded_ivars->doc_id = (int32_t)Cfish_Obj_To_I64(doc_id);
+    loaded_ivars->fields  = SvREFCNT_inc(SvRV(fields_sv));
     SvREFCNT_dec(fields_sv);
 
     return loaded;
@@ -206,21 +215,19 @@ lucy_Doc_load(lucy_Doc *self, cfish_Obj *dump) {
 
 bool
 lucy_Doc_equals(lucy_Doc *self, cfish_Obj *other) {
-    lucy_Doc *twin = (lucy_Doc*)other;
-    HV *my_fields;
-    HV *other_fields;
-    I32 num_fields;
-
-    if (twin == self)                    { return true;  }
+    if ((lucy_Doc*)other  == self)        { return true;  }
     if (!Cfish_Obj_Is_A(other, LUCY_DOC)) { return false; }
-    if (!self->doc_id == twin->doc_id)   { return false; }
-    if (!!self->fields ^ !!twin->fields) { return false; }
+    lucy_DocIVARS *const ivars = lucy_Doc_IVARS(self);
+    lucy_DocIVARS *const ovars = lucy_Doc_IVARS((lucy_Doc*)other);
+
+    if (!ivars->doc_id == ovars->doc_id)   { return false; }
+    if (!!ivars->fields ^ !!ovars->fields) { return false; }
 
     // Verify fields.  Don't allow any deep data structures.
-    my_fields    = (HV*)self->fields;
-    other_fields = (HV*)twin->fields;
+    HV *my_fields    = (HV*)ivars->fields;
+    HV *other_fields = (HV*)ovars->fields;
     if (HvKEYS(my_fields) != HvKEYS(other_fields)) { return false; }
-    num_fields = hv_iterinit(my_fields);
+    I32 num_fields = hv_iterinit(my_fields);
     while (num_fields--) {
         HE *my_entry = hv_iternext(my_fields);
         SV *my_val_sv = HeVAL(my_entry);
@@ -236,7 +243,8 @@ lucy_Doc_equals(lucy_Doc *self, cfish_Obj *other) {
 
 void
 lucy_Doc_destroy(lucy_Doc *self) {
-    if (self->fields) { SvREFCNT_dec((SV*)self->fields); }
+    lucy_DocIVARS *const ivars = lucy_Doc_IVARS(self);
+    if (ivars->fields) { SvREFCNT_dec((SV*)ivars->fields); }
     CFISH_SUPER_DESTROY(self, LUCY_DOC);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/811358d9/perl/xs/Lucy/Index/DocReader.c
----------------------------------------------------------------------
diff --git a/perl/xs/Lucy/Index/DocReader.c b/perl/xs/Lucy/Index/DocReader.c
index 0c7b2ac..d4e27ae 100644
--- a/perl/xs/Lucy/Index/DocReader.c
+++ b/perl/xs/Lucy/Index/DocReader.c
@@ -29,9 +29,10 @@
 
 lucy_HitDoc*
 lucy_DefDocReader_fetch_doc(lucy_DefaultDocReader *self, int32_t doc_id) {
-    lucy_Schema   *const schema = self->schema;
-    lucy_InStream *const dat_in = self->dat_in;
-    lucy_InStream *const ix_in  = self->ix_in;
+    lucy_DefaultDocReaderIVARS *const ivars = lucy_DefDocReader_IVARS(self);
+    lucy_Schema   *const schema = ivars->schema;
+    lucy_InStream *const dat_in = ivars->dat_in;
+    lucy_InStream *const ix_in  = ivars->ix_in;
     HV *fields = newHV();
     int64_t start;
     uint32_t num_fields;

http://git-wip-us.apache.org/repos/asf/lucy/blob/811358d9/perl/xs/Lucy/Index/Inverter.c
----------------------------------------------------------------------
diff --git a/perl/xs/Lucy/Index/Inverter.c b/perl/xs/Lucy/Index/Inverter.c
index 7f0bc95..d3ad2a8 100644
--- a/perl/xs/Lucy/Index/Inverter.c
+++ b/perl/xs/Lucy/Index/Inverter.c
@@ -30,7 +30,8 @@
 
 static lucy_InverterEntry*
 S_fetch_entry(lucy_Inverter *self, HE *hash_entry) {
-    lucy_Schema *const schema = self->schema;
+    lucy_InverterIVARS *const ivars = lucy_Inverter_IVARS(self);
+    lucy_Schema *const schema = ivars->schema;
     char *key;
     STRLEN key_len;
     STRLEN he_key_len = HeKLEN(hash_entry);
@@ -51,13 +52,13 @@ S_fetch_entry(lucy_Inverter *self, HE *hash_entry) {
 
     cfish_ZombieCharBuf *field = CFISH_ZCB_WRAP_STR(key, key_len);
     int32_t field_num
-        = Lucy_Seg_Field_Num(self->segment, (cfish_CharBuf*)field);
+        = Lucy_Seg_Field_Num(ivars->segment, (cfish_CharBuf*)field);
     if (!field_num) {
         // This field seems not to be in the segment yet.  Try to find it in
         // the Schema.
         if (Lucy_Schema_Fetch_Type(schema, (cfish_CharBuf*)field)) {
             // The field is in the Schema.  Get a field num from the Segment.
-            field_num = Lucy_Seg_Add_Field(self->segment,
+            field_num = Lucy_Seg_Add_Field(ivars->segment,
                                            (cfish_CharBuf*)field);
         }
         else {
@@ -68,10 +69,10 @@ S_fetch_entry(lucy_Inverter *self, HE *hash_entry) {
     }
 
     lucy_InverterEntry *entry
-        = (lucy_InverterEntry*)Cfish_VA_Fetch(self->entry_pool, field_num);
+        = (lucy_InverterEntry*)Cfish_VA_Fetch(ivars->entry_pool, field_num);
     if (!entry) {
         entry = lucy_InvEntry_new(schema, (cfish_CharBuf*)field, field_num);
-        Cfish_VA_Store(self->entry_pool, field_num, (cfish_Obj*)entry);
+        Cfish_VA_Store(ivars->entry_pool, field_num, (cfish_Obj*)entry);
     }
     return entry;
 }
@@ -89,7 +90,9 @@ lucy_Inverter_invert_doc(lucy_Inverter *self, lucy_Doc *doc) {
         HE *hash_entry = hv_iternext(fields);
         lucy_InverterEntry *inv_entry = S_fetch_entry(self, hash_entry);
         SV *value_sv = HeVAL(hash_entry);
-        lucy_FieldType *type = inv_entry->type;
+        lucy_InverterEntryIVARS *const entry_ivars
+            = lucy_InvEntry_IVARS(inv_entry);
+        lucy_FieldType *type = entry_ivars->type;
 
         // Get the field value, forcing text fields to UTF-8.
         switch (Lucy_FType_Primitive_ID(type) & lucy_FType_PRIMITIVE_ID_MASK) {
@@ -97,7 +100,7 @@ lucy_Inverter_invert_doc(lucy_Inverter *self, lucy_Doc *doc) {
                     STRLEN val_len;
                     char *val_ptr = SvPVutf8(value_sv, val_len);
                     cfish_ViewCharBuf *value
-                        = (cfish_ViewCharBuf*)inv_entry->value;
+                        = (cfish_ViewCharBuf*)entry_ivars->value;
                     Cfish_ViewCB_Assign_Str(value, val_ptr, val_len);
                     break;
                 }
@@ -105,17 +108,17 @@ lucy_Inverter_invert_doc(lucy_Inverter *self, lucy_Doc *doc) {
                     STRLEN val_len;
                     char *val_ptr = SvPV(value_sv, val_len);
                     cfish_ViewByteBuf *value
-                        = (cfish_ViewByteBuf*)inv_entry->value;
+                        = (cfish_ViewByteBuf*)entry_ivars->value;
                     Cfish_ViewBB_Assign_Bytes(value, val_ptr, val_len);
                     break;
                 }
             case lucy_FType_INT32: {
-                    cfish_Integer32* value = (cfish_Integer32*)inv_entry->value;
+                    cfish_Integer32* value = (cfish_Integer32*)entry_ivars->value;
                     Cfish_Int32_Set_Value(value, SvIV(value_sv));
                     break;
                 }
             case lucy_FType_INT64: {
-                    cfish_Integer64* value = (cfish_Integer64*)inv_entry->value;
+                    cfish_Integer64* value = (cfish_Integer64*)entry_ivars->value;
                     int64_t val = sizeof(IV) == 8
                                   ? SvIV(value_sv)
                                   : (int64_t)SvNV(value_sv); // lossy
@@ -123,12 +126,12 @@ lucy_Inverter_invert_doc(lucy_Inverter *self, lucy_Doc *doc) {
                     break;
                 }
             case lucy_FType_FLOAT32: {
-                    cfish_Float32* value = (cfish_Float32*)inv_entry->value;
+                    cfish_Float32* value = (cfish_Float32*)entry_ivars->value;
                     Cfish_Float32_Set_Value(value, (float)SvNV(value_sv));
                     break;
                 }
             case lucy_FType_FLOAT64: {
-                    cfish_Float64* value = (cfish_Float64*)inv_entry->value;
+                    cfish_Float64* value = (cfish_Float64*)entry_ivars->value;
                     Cfish_Float64_Set_Value(value, SvNV(value_sv));
                     break;
                 }


[lucy-commits] [24/34] git commit: refs/heads/master - Migrate CFCDumpable to IVARS.

Posted by ma...@apache.org.
Migrate CFCDumpable to IVARS.

Change code autogenerated by CFCDumpable to access instance vars via an IVARS
struct rather than via `self`.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/bbdd3c7b
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/bbdd3c7b
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/bbdd3c7b

Branch: refs/heads/master
Commit: bbdd3c7b25673d31abfbb2d42a55d57b742a811d
Parents: 3a3bf22
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Thu Jul 11 15:25:57 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 16:08:43 2013 -0700

----------------------------------------------------------------------
 clownfish/compiler/src/CFCDumpable.c | 32 +++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/bbdd3c7b/clownfish/compiler/src/CFCDumpable.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCDumpable.c b/clownfish/compiler/src/CFCDumpable.c
index c8bbf92..269eddd 100644
--- a/clownfish/compiler/src/CFCDumpable.c
+++ b/clownfish/compiler/src/CFCDumpable.c
@@ -164,6 +164,8 @@ S_add_dump_method(CFCClass *klass) {
     const char *full_func_sym = CFCMethod_implementing_func_sym(method);
     const char *full_struct   = CFCClass_full_struct_sym(klass);
     const char *vtable_var    = CFCClass_full_vtable_var(klass);
+    const char *prefix        = CFCClass_get_prefix(klass);
+    const char *class_cnick   = CFCClass_get_cnick(klass);
     CFCClass   *parent        = CFCClass_get_parent(klass);
     char buf[BUF_SIZE];
 
@@ -175,10 +177,12 @@ S_add_dump_method(CFCClass *klass) {
             "cfish_Obj*\n"
             "%s(%s *self)\n"
             "{\n"
+            "    %sIVARS *ivars = %s%s_IVARS(self);\n"
             "    %s super_dump = CFISH_SUPER_METHOD_PTR(%s, %s);\n"
             "    cfish_Hash *dump = (cfish_Hash*)super_dump(self);\n";
         char *autocode
             = CFCUtil_sprintf(pattern, full_func_sym, full_struct,
+                              full_struct, prefix, class_cnick,
                               full_typedef, vtable_var, full_meth);
         CFCClass_append_autocode(klass, autocode);
         FREEMEM(full_meth);
@@ -196,10 +200,13 @@ S_add_dump_method(CFCClass *klass) {
             "cfish_Obj*\n"
             "%s(%s *self)\n"
             "{\n"
+            "    %sIVARS *ivars = %s%s_IVARS(self);\n"
             "    cfish_Hash *dump = cfish_Hash_new(0);\n"
             "    Cfish_Hash_Store_Str(dump, \"_class\", 6,\n"
             "        (cfish_Obj*)Cfish_CB_Clone(Cfish_Obj_Get_Class_Name((cfish_Obj*)self)));\n";
-        char *autocode = CFCUtil_sprintf(pattern, full_func_sym, full_struct);
+        char *autocode
+            = CFCUtil_sprintf(pattern, full_func_sym, full_struct,
+                              full_struct, prefix, class_cnick);
         CFCClass_append_autocode(klass, autocode);
         FREEMEM(autocode);
         CFCVariable **members = CFCClass_member_vars(klass);
@@ -220,6 +227,8 @@ S_add_load_method(CFCClass *klass) {
     const char *full_struct   = CFCClass_full_struct_sym(klass);
     const char *vtable_var    = CFCClass_full_vtable_var(klass);
     CFCClass   *parent        = CFCClass_get_parent(klass);
+    const char *prefix        = CFCClass_get_prefix(klass);
+    const char *class_cnick   = CFCClass_get_cnick(klass);
     char buf[BUF_SIZE];
 
     if (parent && CFCClass_has_attribute(parent, "dumpable")) {
@@ -232,11 +241,12 @@ S_add_load_method(CFCClass *klass) {
             "{\n"
             "    cfish_Hash *source = (cfish_Hash*)CFISH_CERTIFY(dump, CFISH_HASH);\n"
             "    %s super_load = CFISH_SUPER_METHOD_PTR(%s, %s);\n"
-            "    %s *loaded = (%s*)super_load(self, dump);\n";
+            "    %s *loaded = (%s*)super_load(self, dump);\n"
+            "    %sIVARS *ivars = %s%s_IVARS(loaded);\n";
         char *autocode
             = CFCUtil_sprintf(pattern, full_func_sym, full_struct,
                               full_typedef, vtable_var, full_meth, full_struct,
-                              full_struct);
+                              full_struct, full_struct, prefix, class_cnick);
         CFCClass_append_autocode(klass, autocode);
         FREEMEM(full_meth);
         FREEMEM(full_typedef);
@@ -258,10 +268,12 @@ S_add_load_method(CFCClass *klass) {
             "        Cfish_Hash_Fetch_Str(source, \"_class\", 6), CFISH_CHARBUF);\n"
             "    cfish_VTable *vtable = cfish_VTable_singleton(class_name, NULL);\n"
             "    %s *loaded = (%s*)Cfish_VTable_Make_Obj(vtable);\n"
+            "    %sIVARS *ivars = %s%s_IVARS(loaded);\n"
             "    CHY_UNUSED_VAR(self);\n";
         char *autocode
             = CFCUtil_sprintf(pattern, full_func_sym, full_struct, full_struct,
-                              full_struct);
+                              full_struct,
+                              full_struct, prefix, class_cnick);
         CFCClass_append_autocode(klass, autocode);
         FREEMEM(autocode);
         CFCVariable **members = CFCClass_member_vars(klass);
@@ -289,11 +301,11 @@ S_process_dump_member(CFCClass *klass, CFCVariable *member, char *buf,
 
     if (CFCType_is_integer(type) || CFCType_is_floating(type)) {
         char int_pattern[] =
-            "    Cfish_Hash_Store_Str(dump, \"%s\", %u, (cfish_Obj*)cfish_CB_newf(\"%%i64\", (int64_t)self->%s));\n";
+            "    Cfish_Hash_Store_Str(dump, \"%s\", %u, (cfish_Obj*)cfish_CB_newf(\"%%i64\", (int64_t)ivars->%s));\n";
         char float_pattern[] =
-            "    Cfish_Hash_Store_Str(dump, \"%s\", %u, (cfish_Obj*)cfish_CB_newf(\"%%f64\", (double)self->%s));\n";
+            "    Cfish_Hash_Store_Str(dump, \"%s\", %u, (cfish_Obj*)cfish_CB_newf(\"%%f64\", (double)ivars->%s));\n";
         char bool_pattern[] =
-            "    Cfish_Hash_Store_Str(dump, \"%s\", %u, (cfish_Obj*)cfish_Bool_singleton(self->%s));\n";
+            "    Cfish_Hash_Store_Str(dump, \"%s\", %u, (cfish_Obj*)cfish_Bool_singleton(ivars->%s));\n";
         const char *pattern;
         if (strcmp(specifier, "bool") == 0) {
             pattern = bool_pattern;
@@ -313,8 +325,8 @@ S_process_dump_member(CFCClass *klass, CFCVariable *member, char *buf,
     }
     else if (CFCType_is_object(type)) {
         char pattern[] =
-            "    if (self->%s) {\n"
-            "        Cfish_Hash_Store_Str(dump, \"%s\", %u, Cfish_Obj_Dump((cfish_Obj*)self->%s));\n"
+            "    if (ivars->%s) {\n"
+            "        Cfish_Hash_Store_Str(dump, \"%s\", %u, Cfish_Obj_Dump((cfish_Obj*)ivars->%s));\n"
             "    }\n";
 
         size_t needed = strlen(pattern) + name_len * 3 + 20;
@@ -375,7 +387,7 @@ S_process_load_member(CFCClass *klass, CFCVariable *member, char *buf,
     const char *pattern =
         "    {\n"
         "        cfish_Obj *var = Cfish_Hash_Fetch_Str(source, \"%s\", %u);\n"
-        "        if (var) { loaded->%s = %s; }\n"
+        "        if (var) { ivars->%s = %s; }\n"
         "    }\n";
     size_t needed = sizeof(pattern)
                     + (name_len * 2)


[lucy-commits] [11/34] Migrate Lucy's index classes to IVARS.

Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/PostingListWriter.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/PostingListWriter.c b/core/Lucy/Index/PostingListWriter.c
index f56e8f8..9436e18 100644
--- a/core/Lucy/Index/PostingListWriter.c
+++ b/core/Lucy/Index/PostingListWriter.c
@@ -62,36 +62,38 @@ PListWriter_init(PostingListWriter *self, Schema *schema, Snapshot *snapshot,
                  Segment *segment, PolyReader *polyreader,
                  LexiconWriter *lex_writer) {
     DataWriter_init((DataWriter*)self, schema, snapshot, segment, polyreader);
+    PostingListWriterIVARS *const ivars = PListWriter_IVARS(self);
 
     // Assign.
-    self->lex_writer = (LexiconWriter*)INCREF(lex_writer);
+    ivars->lex_writer = (LexiconWriter*)INCREF(lex_writer);
 
     // Init.
-    self->pools          = VA_new(Schema_Num_Fields(schema));
-    self->mem_thresh     = default_mem_thresh;
-    self->mem_pool       = MemPool_new(0);
-    self->lex_temp_out   = NULL;
-    self->post_temp_out  = NULL;
+    ivars->pools          = VA_new(Schema_Num_Fields(schema));
+    ivars->mem_thresh     = default_mem_thresh;
+    ivars->mem_pool       = MemPool_new(0);
+    ivars->lex_temp_out   = NULL;
+    ivars->post_temp_out  = NULL;
 
     return self;
 }
 
 static void
 S_lazy_init(PostingListWriter *self) {
-    if (!self->lex_temp_out) {
-        Folder  *folder         = self->folder;
-        CharBuf *seg_name       = Seg_Get_Name(self->segment);
+    PostingListWriterIVARS *const ivars = PListWriter_IVARS(self);
+    if (!ivars->lex_temp_out) {
+        Folder  *folder         = ivars->folder;
+        CharBuf *seg_name       = Seg_Get_Name(ivars->segment);
         CharBuf *lex_temp_path  = CB_newf("%o/lextemp", seg_name);
         CharBuf *post_temp_path = CB_newf("%o/ptemp", seg_name);
         CharBuf *skip_path      = CB_newf("%o/postings.skip", seg_name);
 
         // Open temp streams and final skip stream.
-        self->lex_temp_out  = Folder_Open_Out(folder, lex_temp_path);
-        if (!self->lex_temp_out) { RETHROW(INCREF(Err_get_error())); }
-        self->post_temp_out = Folder_Open_Out(folder, post_temp_path);
-        if (!self->post_temp_out) { RETHROW(INCREF(Err_get_error())); }
-        self->skip_out = Folder_Open_Out(folder, skip_path);
-        if (!self->skip_out) { RETHROW(INCREF(Err_get_error())); }
+        ivars->lex_temp_out  = Folder_Open_Out(folder, lex_temp_path);
+        if (!ivars->lex_temp_out) { RETHROW(INCREF(Err_get_error())); }
+        ivars->post_temp_out = Folder_Open_Out(folder, post_temp_path);
+        if (!ivars->post_temp_out) { RETHROW(INCREF(Err_get_error())); }
+        ivars->skip_out = Folder_Open_Out(folder, skip_path);
+        if (!ivars->skip_out) { RETHROW(INCREF(Err_get_error())); }
 
         DECREF(skip_path);
         DECREF(post_temp_path);
@@ -101,26 +103,28 @@ S_lazy_init(PostingListWriter *self) {
 
 static PostingPool*
 S_lazy_init_posting_pool(PostingListWriter *self, int32_t field_num) {
-    PostingPool *pool = (PostingPool*)VA_Fetch(self->pools, field_num);
+    PostingListWriterIVARS *const ivars = PListWriter_IVARS(self);
+    PostingPool *pool = (PostingPool*)VA_Fetch(ivars->pools, field_num);
     if (!pool && field_num != 0) {
-        CharBuf *field = Seg_Field_Name(self->segment, field_num);
-        pool = PostPool_new(self->schema, self->snapshot, self->segment,
-                            self->polyreader, field, self->lex_writer,
-                            self->mem_pool, self->lex_temp_out,
-                            self->post_temp_out, self->skip_out);
-        VA_Store(self->pools, field_num, (Obj*)pool);
+        CharBuf *field = Seg_Field_Name(ivars->segment, field_num);
+        pool = PostPool_new(ivars->schema, ivars->snapshot, ivars->segment,
+                            ivars->polyreader, field, ivars->lex_writer,
+                            ivars->mem_pool, ivars->lex_temp_out,
+                            ivars->post_temp_out, ivars->skip_out);
+        VA_Store(ivars->pools, field_num, (Obj*)pool);
     }
     return pool;
 }
 
 void
 PListWriter_destroy(PostingListWriter *self) {
-    DECREF(self->lex_writer);
-    DECREF(self->mem_pool);
-    DECREF(self->pools);
-    DECREF(self->lex_temp_out);
-    DECREF(self->post_temp_out);
-    DECREF(self->skip_out);
+    PostingListWriterIVARS *const ivars = PListWriter_IVARS(self);
+    DECREF(ivars->lex_writer);
+    DECREF(ivars->mem_pool);
+    DECREF(ivars->pools);
+    DECREF(ivars->lex_temp_out);
+    DECREF(ivars->post_temp_out);
+    DECREF(ivars->skip_out);
     SUPER_DESTROY(self, POSTINGLISTWRITER);
 }
 
@@ -139,6 +143,7 @@ void
 PListWriter_add_inverted_doc(PostingListWriter *self, Inverter *inverter,
                              int32_t doc_id) {
     S_lazy_init(self);
+    PostingListWriterIVARS *const ivars = PListWriter_IVARS(self);
 
     // Iterate over fields in document, adding the content of indexed fields
     // to their respective PostingPools.
@@ -161,21 +166,22 @@ PListWriter_add_inverted_doc(PostingListWriter *self, Inverter *inverter,
     // If our PostingPools have collectively passed the memory threshold,
     // flush all of them, then release all the RawPostings with a single
     // action.
-    if (MemPool_Get_Consumed(self->mem_pool) > self->mem_thresh) {
-        for (uint32_t i = 0, max = VA_Get_Size(self->pools); i < max; i++) {
-            PostingPool *const pool = (PostingPool*)VA_Fetch(self->pools, i);
+    if (MemPool_Get_Consumed(ivars->mem_pool) > ivars->mem_thresh) {
+        for (uint32_t i = 0, max = VA_Get_Size(ivars->pools); i < max; i++) {
+            PostingPool *const pool = (PostingPool*)VA_Fetch(ivars->pools, i);
             if (pool) { PostPool_Flush(pool); }
         }
-        MemPool_Release_All(self->mem_pool);
+        MemPool_Release_All(ivars->mem_pool);
     }
 }
 
 void
 PListWriter_add_segment(PostingListWriter *self, SegReader *reader,
                         I32Array *doc_map) {
+    PostingListWriterIVARS *const ivars = PListWriter_IVARS(self);
     Segment *other_segment = SegReader_Get_Segment(reader);
-    Schema  *schema        = self->schema;
-    Segment *segment       = self->segment;
+    Schema  *schema        = ivars->schema;
+    Segment *segment       = ivars->segment;
     VArray  *all_fields    = Schema_All_Fields(schema);
     S_lazy_init(self);
 
@@ -202,32 +208,34 @@ PListWriter_add_segment(PostingListWriter *self, SegReader *reader,
 
 void
 PListWriter_finish(PostingListWriter *self) {
+    PostingListWriterIVARS *const ivars = PListWriter_IVARS(self);
+
     // If S_lazy_init was never called, we have no data, so bail out.
-    if (!self->lex_temp_out) { return; }
+    if (!ivars->lex_temp_out) { return; }
 
-    Folder  *folder = self->folder;
-    CharBuf *seg_name = Seg_Get_Name(self->segment);
+    Folder  *folder = ivars->folder;
+    CharBuf *seg_name = Seg_Get_Name(ivars->segment);
     CharBuf *lex_temp_path  = CB_newf("%o/lextemp", seg_name);
     CharBuf *post_temp_path = CB_newf("%o/ptemp", seg_name);
 
     // Close temp streams.
-    OutStream_Close(self->lex_temp_out);
-    OutStream_Close(self->post_temp_out);
+    OutStream_Close(ivars->lex_temp_out);
+    OutStream_Close(ivars->post_temp_out);
 
     // Try to free up some memory.
-    for (uint32_t i = 0, max = VA_Get_Size(self->pools); i < max; i++) {
-        PostingPool *pool = (PostingPool*)VA_Fetch(self->pools, i);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->pools); i < max; i++) {
+        PostingPool *pool = (PostingPool*)VA_Fetch(ivars->pools, i);
         if (pool) { PostPool_Shrink(pool); }
     }
 
     // Write postings for each field.
-    for (uint32_t i = 0, max = VA_Get_Size(self->pools); i < max; i++) {
-        PostingPool *pool = (PostingPool*)VA_Delete(self->pools, i);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->pools); i < max; i++) {
+        PostingPool *pool = (PostingPool*)VA_Delete(ivars->pools, i);
         if (pool) {
             // Write out content for each PostingPool.  Let each PostingPool
             // use more RAM while finishing.  (This is a little dicy, because if
             // Shrink() was ineffective, we may double the RAM footprint.)
-            PostPool_Set_Mem_Thresh(pool, self->mem_thresh);
+            PostPool_Set_Mem_Thresh(pool, ivars->mem_thresh);
             PostPool_Flip(pool);
             PostPool_Finish(pool);
             DECREF(pool);
@@ -235,24 +243,24 @@ PListWriter_finish(PostingListWriter *self) {
     }
 
     // Store metadata.
-    Seg_Store_Metadata_Str(self->segment, "postings", 8,
+    Seg_Store_Metadata_Str(ivars->segment, "postings", 8,
                            (Obj*)PListWriter_Metadata(self));
 
     // Close down and clean up.
-    OutStream_Close(self->skip_out);
+    OutStream_Close(ivars->skip_out);
     if (!Folder_Delete(folder, lex_temp_path)) {
         THROW(ERR, "Couldn't delete %o", lex_temp_path);
     }
     if (!Folder_Delete(folder, post_temp_path)) {
         THROW(ERR, "Couldn't delete %o", post_temp_path);
     }
-    DECREF(self->skip_out);
-    self->skip_out = NULL;
+    DECREF(ivars->skip_out);
+    ivars->skip_out = NULL;
     DECREF(post_temp_path);
     DECREF(lex_temp_path);
 
     // Dispatch the LexiconWriter.
-    LexWriter_Finish(self->lex_writer);
+    LexWriter_Finish(ivars->lex_writer);
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/PostingPool.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/PostingPool.c b/core/Lucy/Index/PostingPool.c
index f2c1146..6bd21b0 100644
--- a/core/Lucy/Index/PostingPool.c
+++ b/core/Lucy/Index/PostingPool.c
@@ -76,68 +76,70 @@ PostPool_init(PostingPool *self, Schema *schema, Snapshot *snapshot,
               OutStream *skip_out) {
     // Init.
     SortEx_init((SortExternal*)self, sizeof(Obj*));
-    self->doc_base         = 0;
-    self->last_doc_id      = 0;
-    self->doc_map          = NULL;
-    self->post_count       = 0;
-    self->lexicon          = NULL;
-    self->plist            = NULL;
-    self->lex_temp_in      = NULL;
-    self->post_temp_in     = NULL;
-    self->lex_start        = INT64_MAX;
-    self->post_start       = INT64_MAX;
-    self->lex_end          = 0;
-    self->post_end         = 0;
-    self->skip_stepper     = SkipStepper_new();
+    PostingPoolIVARS *const ivars = PostPool_IVARS(self);
+    ivars->doc_base         = 0;
+    ivars->last_doc_id      = 0;
+    ivars->doc_map          = NULL;
+    ivars->post_count       = 0;
+    ivars->lexicon          = NULL;
+    ivars->plist            = NULL;
+    ivars->lex_temp_in      = NULL;
+    ivars->post_temp_in     = NULL;
+    ivars->lex_start        = INT64_MAX;
+    ivars->post_start       = INT64_MAX;
+    ivars->lex_end          = 0;
+    ivars->post_end         = 0;
+    ivars->skip_stepper     = SkipStepper_new();
 
     // Assign.
-    self->schema         = (Schema*)INCREF(schema);
-    self->snapshot       = (Snapshot*)INCREF(snapshot);
-    self->segment        = (Segment*)INCREF(segment);
-    self->polyreader     = (PolyReader*)INCREF(polyreader);
-    self->lex_writer     = (LexiconWriter*)INCREF(lex_writer);
-    self->mem_pool       = (MemoryPool*)INCREF(mem_pool);
-    self->field          = CB_Clone(field);
-    self->lex_temp_out   = (OutStream*)INCREF(lex_temp_out);
-    self->post_temp_out  = (OutStream*)INCREF(post_temp_out);
-    self->skip_out       = (OutStream*)INCREF(skip_out);
+    ivars->schema         = (Schema*)INCREF(schema);
+    ivars->snapshot       = (Snapshot*)INCREF(snapshot);
+    ivars->segment        = (Segment*)INCREF(segment);
+    ivars->polyreader     = (PolyReader*)INCREF(polyreader);
+    ivars->lex_writer     = (LexiconWriter*)INCREF(lex_writer);
+    ivars->mem_pool       = (MemoryPool*)INCREF(mem_pool);
+    ivars->field          = CB_Clone(field);
+    ivars->lex_temp_out   = (OutStream*)INCREF(lex_temp_out);
+    ivars->post_temp_out  = (OutStream*)INCREF(post_temp_out);
+    ivars->skip_out       = (OutStream*)INCREF(skip_out);
 
     // Derive.
     Similarity *sim = Schema_Fetch_Sim(schema, field);
-    self->posting   = Sim_Make_Posting(sim);
-    self->type      = (FieldType*)INCREF(Schema_Fetch_Type(schema, field));
-    self->field_num = Seg_Field_Num(segment, field);
+    ivars->posting   = Sim_Make_Posting(sim);
+    ivars->type      = (FieldType*)INCREF(Schema_Fetch_Type(schema, field));
+    ivars->field_num = Seg_Field_Num(segment, field);
 
     return self;
 }
 
 void
 PostPool_destroy(PostingPool *self) {
-    DECREF(self->schema);
-    DECREF(self->snapshot);
-    DECREF(self->segment);
-    DECREF(self->polyreader);
-    DECREF(self->lex_writer);
-    DECREF(self->mem_pool);
-    DECREF(self->field);
-    DECREF(self->doc_map);
-    DECREF(self->lexicon);
-    DECREF(self->plist);
-    DECREF(self->lex_temp_out);
-    DECREF(self->post_temp_out);
-    DECREF(self->skip_out);
-    DECREF(self->lex_temp_in);
-    DECREF(self->post_temp_in);
-    DECREF(self->posting);
-    DECREF(self->skip_stepper);
-    DECREF(self->type);
+    PostingPoolIVARS *const ivars = PostPool_IVARS(self);
+    DECREF(ivars->schema);
+    DECREF(ivars->snapshot);
+    DECREF(ivars->segment);
+    DECREF(ivars->polyreader);
+    DECREF(ivars->lex_writer);
+    DECREF(ivars->mem_pool);
+    DECREF(ivars->field);
+    DECREF(ivars->doc_map);
+    DECREF(ivars->lexicon);
+    DECREF(ivars->plist);
+    DECREF(ivars->lex_temp_out);
+    DECREF(ivars->post_temp_out);
+    DECREF(ivars->skip_out);
+    DECREF(ivars->lex_temp_in);
+    DECREF(ivars->post_temp_in);
+    DECREF(ivars->posting);
+    DECREF(ivars->skip_stepper);
+    DECREF(ivars->type);
     SUPER_DESTROY(self, POSTINGPOOL);
 }
 
 int
 PostPool_compare(PostingPool *self, void *va, void *vb) {
-    RawPosting *const a     = *(RawPosting**)va;
-    RawPosting *const b     = *(RawPosting**)vb;
+    RawPostingIVARS *const a     = RawPost_IVARS(*(RawPosting**)va);
+    RawPostingIVARS *const b     = RawPost_IVARS(*(RawPosting**)vb);
     const size_t      a_len = a->content_len;
     const size_t      b_len = b->content_len;
     const size_t      len   = a_len < b_len ? a_len : b_len;
@@ -159,27 +161,28 @@ PostPool_compare(PostingPool *self, void *va, void *vb) {
 
 MemoryPool*
 PostPool_get_mem_pool(PostingPool *self) {
-    return self->mem_pool;
+    return PostPool_IVARS(self)->mem_pool;
 }
 
 void
 PostPool_flip(PostingPool *self) {
-    uint32_t num_runs   = VA_Get_Size(self->runs);
+    PostingPoolIVARS *const ivars = PostPool_IVARS(self);
+    uint32_t num_runs   = VA_Get_Size(ivars->runs);
     uint32_t sub_thresh = num_runs > 0
-                          ? self->mem_thresh / num_runs
-                          : self->mem_thresh;
+                          ? ivars->mem_thresh / num_runs
+                          : ivars->mem_thresh;
 
     if (num_runs) {
-        Folder  *folder = PolyReader_Get_Folder(self->polyreader);
-        CharBuf *seg_name = Seg_Get_Name(self->segment);
+        Folder  *folder = PolyReader_Get_Folder(ivars->polyreader);
+        CharBuf *seg_name = Seg_Get_Name(ivars->segment);
         CharBuf *lex_temp_path  = CB_newf("%o/lextemp", seg_name);
         CharBuf *post_temp_path = CB_newf("%o/ptemp", seg_name);
-        self->lex_temp_in = Folder_Open_In(folder, lex_temp_path);
-        if (!self->lex_temp_in) {
+        ivars->lex_temp_in = Folder_Open_In(folder, lex_temp_path);
+        if (!ivars->lex_temp_in) {
             RETHROW(INCREF(Err_get_error()));
         }
-        self->post_temp_in = Folder_Open_In(folder, post_temp_path);
-        if (!self->post_temp_in) {
+        ivars->post_temp_in = Folder_Open_In(folder, post_temp_path);
+        if (!ivars->post_temp_in) {
             RETHROW(INCREF(Err_get_error()));
         }
         DECREF(lex_temp_path);
@@ -187,44 +190,47 @@ PostPool_flip(PostingPool *self) {
     }
 
     PostPool_Sort_Cache(self);
-    if (num_runs && (self->cache_max - self->cache_tick) > 0) {
+    if (num_runs && (ivars->cache_max - ivars->cache_tick) > 0) {
         uint32_t num_items = PostPool_Cache_Count(self);
         // Cheap imitation of flush. FIXME.
         PostingPool *run
-            = PostPool_new(self->schema, self->snapshot, self->segment,
-                           self->polyreader, self->field, self->lex_writer,
-                           self->mem_pool, self->lex_temp_out,
-                           self->post_temp_out, self->skip_out);
+            = PostPool_new(ivars->schema, ivars->snapshot, ivars->segment,
+                           ivars->polyreader, ivars->field, ivars->lex_writer,
+                           ivars->mem_pool, ivars->lex_temp_out,
+                           ivars->post_temp_out, ivars->skip_out);
         PostPool_Grow_Cache(run, num_items);
-        memcpy(run->cache, ((Obj**)self->cache) + self->cache_tick,
+        PostingPoolIVARS *const run_ivars = PostPool_IVARS(run);
+
+        memcpy(run_ivars->cache, ((Obj**)ivars->cache) + ivars->cache_tick,
                num_items * sizeof(Obj*));
-        run->cache_max = num_items;
+        run_ivars->cache_max = num_items;
         PostPool_Add_Run(self, (SortExternal*)run);
-        self->cache_tick = 0;
-        self->cache_max = 0;
+        ivars->cache_tick = 0;
+        ivars->cache_max = 0;
     }
 
     // Assign.
     for (uint32_t i = 0; i < num_runs; i++) {
-        PostingPool *run = (PostingPool*)VA_Fetch(self->runs, i);
+        PostingPool *run = (PostingPool*)VA_Fetch(ivars->runs, i);
         if (run != NULL) {
             PostPool_Set_Mem_Thresh(run, sub_thresh);
-            if (!run->lexicon) {
-                S_fresh_flip(run, self->lex_temp_in, self->post_temp_in);
+            if (!PostPool_IVARS(run)->lexicon) {
+                S_fresh_flip(run, ivars->lex_temp_in, ivars->post_temp_in);
             }
         }
     }
 
-    self->flipped = true;
+    ivars->flipped = true;
 }
 
 void
 PostPool_add_segment(PostingPool *self, SegReader *reader, I32Array *doc_map,
                      int32_t doc_base) {
+    PostingPoolIVARS *const ivars = PostPool_IVARS(self);
     LexiconReader *lex_reader = (LexiconReader*)SegReader_Fetch(
                                     reader, VTable_Get_Name(LEXICONREADER));
     Lexicon *lexicon = lex_reader
-                       ? LexReader_Lexicon(lex_reader, self->field, NULL)
+                       ? LexReader_Lexicon(lex_reader, ivars->field, NULL)
                        : NULL;
 
     if (lexicon) {
@@ -232,49 +238,51 @@ PostPool_add_segment(PostingPool *self, SegReader *reader, I32Array *doc_map,
             = (PostingListReader*)SegReader_Fetch(
                   reader, VTable_Get_Name(POSTINGLISTREADER));
         PostingList *plist = plist_reader
-                             ? PListReader_Posting_List(plist_reader, self->field, NULL)
+                             ? PListReader_Posting_List(plist_reader, ivars->field, NULL)
                              : NULL;
         if (!plist) {
             THROW(ERR, "Got a Lexicon but no PostingList for '%o' in '%o'",
-                  self->field, SegReader_Get_Seg_Name(reader));
+                  ivars->field, SegReader_Get_Seg_Name(reader));
         }
         PostingPool *run
-            = PostPool_new(self->schema, self->snapshot, self->segment,
-                           self->polyreader, self->field, self->lex_writer,
-                           self->mem_pool, self->lex_temp_out,
-                           self->post_temp_out, self->skip_out);
-        run->lexicon  = lexicon;
-        run->plist    = plist;
-        run->doc_base = doc_base;
-        run->doc_map  = (I32Array*)INCREF(doc_map);
+            = PostPool_new(ivars->schema, ivars->snapshot, ivars->segment,
+                           ivars->polyreader, ivars->field, ivars->lex_writer,
+                           ivars->mem_pool, ivars->lex_temp_out,
+                           ivars->post_temp_out, ivars->skip_out);
+        PostingPoolIVARS *const run_ivars = PostPool_IVARS(run);
+        run_ivars->lexicon  = lexicon;
+        run_ivars->plist    = plist;
+        run_ivars->doc_base = doc_base;
+        run_ivars->doc_map  = (I32Array*)INCREF(doc_map);
         PostPool_Add_Run(self, (SortExternal*)run);
     }
 }
 
 void
 PostPool_shrink(PostingPool *self) {
-    if (self->cache_max - self->cache_tick > 0) {
+    PostingPoolIVARS *const ivars = PostPool_IVARS(self);
+    if (ivars->cache_max - ivars->cache_tick > 0) {
         size_t cache_count = PostPool_Cache_Count(self);
         size_t size        = cache_count * sizeof(Obj*);
-        if (self->cache_tick > 0) {
-            Obj **start = ((Obj**)self->cache) + self->cache_tick;
-            memmove(self->cache, start, size);
+        if (ivars->cache_tick > 0) {
+            Obj **start = ((Obj**)ivars->cache) + ivars->cache_tick;
+            memmove(ivars->cache, start, size);
         }
-        self->cache      = (uint8_t*)REALLOCATE(self->cache, size);
-        self->cache_tick = 0;
-        self->cache_max  = cache_count;
-        self->cache_cap  = cache_count;
+        ivars->cache      = (uint8_t*)REALLOCATE(ivars->cache, size);
+        ivars->cache_tick = 0;
+        ivars->cache_max  = cache_count;
+        ivars->cache_cap  = cache_count;
     }
     else {
-        FREEMEM(self->cache);
-        self->cache      = NULL;
-        self->cache_tick = 0;
-        self->cache_max  = 0;
-        self->cache_cap  = 0;
+        FREEMEM(ivars->cache);
+        ivars->cache      = NULL;
+        ivars->cache_tick = 0;
+        ivars->cache_max  = 0;
+        ivars->cache_cap  = 0;
     }
-    self->scratch_cap = 0;
-    FREEMEM(self->scratch);
-    self->scratch = NULL;
+    ivars->scratch_cap = 0;
+    FREEMEM(ivars->scratch);
+    ivars->scratch = NULL;
 
     // It's not necessary to iterate over the runs, because they don't have
     // any cache costs until Refill() gets called.
@@ -282,42 +290,45 @@ PostPool_shrink(PostingPool *self) {
 
 void
 PostPool_flush(PostingPool *self) {
+    PostingPoolIVARS *const ivars = PostPool_IVARS(self);
+
     // Don't add a run unless we have data to put in it.
     if (PostPool_Cache_Count(self) == 0) { return; }
 
     PostingPool *run
-        = PostPool_new(self->schema, self->snapshot, self->segment,
-                       self->polyreader, self->field, self->lex_writer,
-                       self->mem_pool, self->lex_temp_out,
-                       self->post_temp_out, self->skip_out);
+        = PostPool_new(ivars->schema, ivars->snapshot, ivars->segment,
+                       ivars->polyreader, ivars->field, ivars->lex_writer,
+                       ivars->mem_pool, ivars->lex_temp_out,
+                       ivars->post_temp_out, ivars->skip_out);
+    PostingPoolIVARS *const run_ivars = PostPool_IVARS(run);
     PostingWriter *post_writer
-        = (PostingWriter*)RawPostWriter_new(self->schema, self->snapshot,
-                                            self->segment, self->polyreader,
-                                            self->post_temp_out);
+        = (PostingWriter*)RawPostWriter_new(ivars->schema, ivars->snapshot,
+                                            ivars->segment, ivars->polyreader,
+                                            ivars->post_temp_out);
 
     // Borrow the cache.
-    run->cache      = self->cache;
-    run->cache_tick = self->cache_tick;
-    run->cache_max  = self->cache_max;
-    run->cache_cap  = self->cache_cap;
+    run_ivars->cache      = ivars->cache;
+    run_ivars->cache_tick = ivars->cache_tick;
+    run_ivars->cache_max  = ivars->cache_max;
+    run_ivars->cache_cap  = ivars->cache_cap;
 
     // Write to temp files.
-    LexWriter_Enter_Temp_Mode(self->lex_writer, self->field,
-                              self->lex_temp_out);
-    run->lex_start  = OutStream_Tell(self->lex_temp_out);
-    run->post_start = OutStream_Tell(self->post_temp_out);
+    LexWriter_Enter_Temp_Mode(ivars->lex_writer, ivars->field,
+                              ivars->lex_temp_out);
+    run_ivars->lex_start  = OutStream_Tell(ivars->lex_temp_out);
+    run_ivars->post_start = OutStream_Tell(ivars->post_temp_out);
     PostPool_Sort_Cache(self);
     S_write_terms_and_postings(run, post_writer, NULL);
 
-    run->lex_end  = OutStream_Tell(self->lex_temp_out);
-    run->post_end = OutStream_Tell(self->post_temp_out);
-    LexWriter_Leave_Temp_Mode(self->lex_writer);
+    run_ivars->lex_end  = OutStream_Tell(ivars->lex_temp_out);
+    run_ivars->post_end = OutStream_Tell(ivars->post_temp_out);
+    LexWriter_Leave_Temp_Mode(ivars->lex_writer);
 
     // Return the cache and empty it.
-    run->cache      = NULL;
-    run->cache_tick = 0;
-    run->cache_max  = 0;
-    run->cache_cap  = 0;
+    run_ivars->cache      = NULL;
+    run_ivars->cache_tick = 0;
+    run_ivars->cache_max  = 0;
+    run_ivars->cache_cap  = 0;
     PostPool_Clear_Cache(self);
 
     // Add the run to the array.
@@ -328,38 +339,46 @@ PostPool_flush(PostingPool *self) {
 
 void
 PostPool_finish(PostingPool *self) {
+    PostingPoolIVARS *const ivars = PostPool_IVARS(self);
+
     // Bail if there's no data.
     if (!PostPool_Peek(self)) { return; }
 
-    Similarity *sim = Schema_Fetch_Sim(self->schema, self->field);
+    Similarity *sim = Schema_Fetch_Sim(ivars->schema, ivars->field);
     PostingWriter *post_writer
-        = Sim_Make_Posting_Writer(sim, self->schema, self->snapshot,
-                                  self->segment, self->polyreader,
-                                  self->field_num);
-    LexWriter_Start_Field(self->lex_writer, self->field_num);
-    S_write_terms_and_postings(self, post_writer, self->skip_out);
-    LexWriter_Finish_Field(self->lex_writer, self->field_num);
+        = Sim_Make_Posting_Writer(sim, ivars->schema, ivars->snapshot,
+                                  ivars->segment, ivars->polyreader,
+                                  ivars->field_num);
+    LexWriter_Start_Field(ivars->lex_writer, ivars->field_num);
+    S_write_terms_and_postings(self, post_writer, ivars->skip_out);
+    LexWriter_Finish_Field(ivars->lex_writer, ivars->field_num);
     DECREF(post_writer);
 }
 
 static void
 S_write_terms_and_postings(PostingPool *self, PostingWriter *post_writer,
                            OutStream *skip_stream) {
-    TermInfo      *const tinfo          = TInfo_new(0);
-    TermInfo      *const skip_tinfo     = TInfo_new(0);
-    CharBuf       *const last_term_text = CB_new(0);
-    LexiconWriter *const lex_writer     = self->lex_writer;
-    SkipStepper   *const skip_stepper   = self->skip_stepper;
-    int32_t        last_skip_doc        = 0;
-    int64_t        last_skip_filepos    = 0;
+    PostingPoolIVARS *const ivars = PostPool_IVARS(self);
+    TermInfo      *const tinfo            = TInfo_new(0);
+    TermInfo      *const skip_tinfo       = TInfo_new(0);
+    TermInfoIVARS *const tinfo_ivars      = TInfo_IVARS(tinfo);
+    TermInfoIVARS *const skip_tinfo_ivars = TInfo_IVARS(skip_tinfo);
+    CharBuf       *const last_term_text   = CB_new(0);
+    LexiconWriter *const lex_writer       = ivars->lex_writer;
+    SkipStepper   *const skip_stepper     = ivars->skip_stepper;
+    SkipStepperIVARS *const skip_stepper_ivars
+        = SkipStepper_IVARS(skip_stepper);
+    int32_t        last_skip_doc          = 0;
+    int64_t        last_skip_filepos      = 0;
     const int32_t  skip_interval
-        = Arch_Skip_Interval(Schema_Get_Architecture(self->schema));
+        = Arch_Skip_Interval(Schema_Get_Architecture(ivars->schema));
 
     // Prime heldover variables.
     RawPosting *posting = (RawPosting*)CERTIFY(
                               (*(RawPosting**)PostPool_Fetch(self)),
                               RAWPOSTING);
-    CB_Mimic_Str(last_term_text, posting->blob, posting->content_len);
+    RawPostingIVARS *post_ivars = RawPost_IVARS(posting);
+    CB_Mimic_Str(last_term_text, post_ivars->blob, post_ivars->content_len);
     char *last_text_buf = (char*)CB_Get_Ptr8(last_term_text);
     uint32_t last_text_size = CB_Get_Size(last_term_text);
     SkipStepper_Set_ID_And_Filepos(skip_stepper, 0, 0);
@@ -379,12 +398,13 @@ S_write_terms_and_postings(PostingPool *self, PostingWriter *post_writer,
             // On the last iter, use an empty string to make LexiconWriter
             // DTRT.
             posting = sentinel;
+            post_ivars = RawPost_IVARS(posting);
             same_text_as_last = false;
         }
         else {
             // Compare once.
-            if (posting->content_len != last_text_size
-                || memcmp(&posting->blob, last_text_buf, last_text_size) != 0
+            if (post_ivars->content_len != last_text_size
+                || memcmp(&post_ivars->blob, last_text_buf, last_text_size) != 0
                ) {
                 same_text_as_last = false;
             }
@@ -400,14 +420,14 @@ S_write_terms_and_postings(PostingPool *self, PostingWriter *post_writer,
             PostWriter_Start_Term(post_writer, tinfo);
 
             // Init skip data in preparation for the next term.
-            skip_stepper->doc_id  = 0;
-            skip_stepper->filepos = tinfo->post_filepos;
+            skip_stepper_ivars->doc_id  = 0;
+            skip_stepper_ivars->filepos = tinfo_ivars->post_filepos;
             last_skip_doc         = 0;
-            last_skip_filepos     = tinfo->post_filepos;
+            last_skip_filepos     = tinfo_ivars->post_filepos;
 
             // Remember the term_text so we can write string diffs.
-            CB_Mimic_Str(last_term_text, posting->blob,
-                         posting->content_len);
+            CB_Mimic_Str(last_term_text, post_ivars->blob,
+                         post_ivars->content_len);
             last_text_buf  = (char*)CB_Get_Ptr8(last_term_text);
             last_text_size = CB_Get_Size(last_term_text);
         }
@@ -419,24 +439,24 @@ S_write_terms_and_postings(PostingPool *self, PostingWriter *post_writer,
         PostWriter_Write_Posting(post_writer, posting);
 
         // Doc freq lags by one iter.
-        tinfo->doc_freq++;
+        tinfo_ivars->doc_freq++;
 
         //  Write skip data.
         if (skip_stream != NULL
             && same_text_as_last
-            && tinfo->doc_freq % skip_interval == 0
-            && tinfo->doc_freq != 0
+            && tinfo_ivars->doc_freq % skip_interval == 0
+            && tinfo_ivars->doc_freq != 0
            ) {
             // If first skip group, save skip stream pos for term info.
-            if (tinfo->doc_freq == skip_interval) {
-                tinfo->skip_filepos = OutStream_Tell(skip_stream);
+            if (tinfo_ivars->doc_freq == skip_interval) {
+                tinfo_ivars->skip_filepos = OutStream_Tell(skip_stream);
             }
             // Write deltas.
-            last_skip_doc         = skip_stepper->doc_id;
-            last_skip_filepos     = skip_stepper->filepos;
-            skip_stepper->doc_id  = posting->doc_id;
+            last_skip_doc               = skip_stepper_ivars->doc_id;
+            last_skip_filepos           = skip_stepper_ivars->filepos;
+            skip_stepper_ivars->doc_id  = post_ivars->doc_id;
             PostWriter_Update_Skip_Info(post_writer, skip_tinfo);
-            skip_stepper->filepos = skip_tinfo->post_filepos;
+            skip_stepper_ivars->filepos = skip_tinfo_ivars->post_filepos;
             SkipStepper_Write_Record(skip_stepper, skip_stream,
                                      last_skip_doc, last_skip_filepos);
         }
@@ -448,6 +468,7 @@ S_write_terms_and_postings(PostingPool *self, PostingWriter *post_writer,
         posting = address
                   ? *(RawPosting**)address
                   : NULL;
+        post_ivars = RawPost_IVARS(posting);
     }
 
     // Clean up.
@@ -458,45 +479,45 @@ S_write_terms_and_postings(PostingPool *self, PostingWriter *post_writer,
 
 uint32_t
 PostPool_refill(PostingPool *self) {
-    Lexicon *const     lexicon     = self->lexicon;
-    PostingList *const plist       = self->plist;
-    I32Array    *const doc_map     = self->doc_map;
-    const uint32_t     mem_thresh  = self->mem_thresh;
-    const int32_t      doc_base    = self->doc_base;
+    PostingPoolIVARS *const ivars = PostPool_IVARS(self);
+    Lexicon *const     lexicon     = ivars->lexicon;
+    PostingList *const plist       = ivars->plist;
+    I32Array    *const doc_map     = ivars->doc_map;
+    const uint32_t     mem_thresh  = ivars->mem_thresh;
+    const int32_t      doc_base    = ivars->doc_base;
     uint32_t           num_elems   = 0; // number of items recovered
-    MemoryPool        *mem_pool;
     CharBuf           *term_text   = NULL;
 
-    if (self->lexicon == NULL) { return 0; }
+    if (ivars->lexicon == NULL) { return 0; }
     else { term_text = (CharBuf*)Lex_Get_Term(lexicon); }
 
     // Make sure cache is empty.
-    if (self->cache_max - self->cache_tick > 0) {
+    if (ivars->cache_max - ivars->cache_tick > 0) {
         THROW(ERR, "Refill called but cache contains %u32 items",
-              self->cache_max - self->cache_tick);
+              ivars->cache_max - ivars->cache_tick);
     }
-    self->cache_max  = 0;
-    self->cache_tick = 0;
+    ivars->cache_max  = 0;
+    ivars->cache_tick = 0;
 
     // Ditch old MemoryPool and get another.
-    DECREF(self->mem_pool);
-    self->mem_pool = MemPool_new(0);
-    mem_pool       = self->mem_pool;
+    DECREF(ivars->mem_pool);
+    ivars->mem_pool = MemPool_new(0);
+    MemoryPool *const mem_pool = ivars->mem_pool;
+    MemoryPoolIVARS *const mem_pool_ivars = MemPool_IVARS(mem_pool);
 
-    while (1) {
-        RawPosting *raw_posting;
 
-        if (self->post_count == 0) {
+    while (1) {
+        if (ivars->post_count == 0) {
             // Read a term.
             if (Lex_Next(lexicon)) {
-                self->post_count = Lex_Doc_Freq(lexicon);
+                ivars->post_count = Lex_Doc_Freq(lexicon);
                 term_text = (CharBuf*)Lex_Get_Term(lexicon);
                 if (term_text && !Obj_Is_A((Obj*)term_text, CHARBUF)) {
                     THROW(ERR, "Only CharBuf terms are supported for now");
                 }
                 Posting *posting = PList_Get_Posting(plist);
                 Post_Set_Doc_ID(posting, doc_base);
-                self->last_doc_id = doc_base;
+                ivars->last_doc_id = doc_base;
             }
             // Bail if we've read everything in this run.
             else {
@@ -505,39 +526,40 @@ PostPool_refill(PostingPool *self) {
         }
 
         // Bail if we've hit the ceiling for this run's cache.
-        if (mem_pool->consumed >= mem_thresh && num_elems > 0) {
+        if (mem_pool_ivars->consumed >= mem_thresh && num_elems > 0) {
             break;
         }
 
         // Read a posting from the input stream.
-        raw_posting = PList_Read_Raw(plist, self->last_doc_id, term_text,
-                                     mem_pool);
-        self->last_doc_id = raw_posting->doc_id;
-        self->post_count--;
+        RawPosting *rawpost
+            = PList_Read_Raw(plist, ivars->last_doc_id, term_text, mem_pool);
+        RawPostingIVARS *const rawpost_ivars = RawPost_IVARS(rawpost);
+        ivars->last_doc_id = rawpost_ivars->doc_id;
+        ivars->post_count--;
 
         // Skip deletions.
         if (doc_map != NULL) {
             const int32_t remapped
-                = I32Arr_Get(doc_map, raw_posting->doc_id - doc_base);
+                = I32Arr_Get(doc_map, rawpost_ivars->doc_id - doc_base);
             if (!remapped) {
                 continue;
             }
-            raw_posting->doc_id = remapped;
+            rawpost_ivars->doc_id = remapped;
         }
 
         // Add to the run's cache.
-        if (num_elems >= self->cache_cap) {
+        if (num_elems >= ivars->cache_cap) {
             size_t new_cap = Memory_oversize(num_elems + 1, sizeof(Obj*));
             PostPool_Grow_Cache(self, new_cap);
         }
-        Obj **cache = (Obj**)self->cache;
-        cache[num_elems] = (Obj*)raw_posting;
+        Obj **cache = (Obj**)ivars->cache;
+        cache[num_elems] = (Obj*)rawpost;
         num_elems++;
     }
 
     // Reset the cache array position and length; remember file pos.
-    self->cache_max   = num_elems;
-    self->cache_tick  = 0;
+    ivars->cache_max   = num_elems;
+    ivars->cache_tick  = 0;
 
     return num_elems;
 }
@@ -545,46 +567,48 @@ PostPool_refill(PostingPool *self) {
 void
 PostPool_add_inversion(PostingPool *self, Inversion *inversion, int32_t doc_id,
                        float doc_boost, float length_norm) {
-    Post_Add_Inversion_To_Pool(self->posting, self, inversion, self->type,
+    PostingPoolIVARS *const ivars = PostPool_IVARS(self);
+    Post_Add_Inversion_To_Pool(ivars->posting, self, inversion, ivars->type,
                                doc_id, doc_boost, length_norm);
 }
 
 static void
 S_fresh_flip(PostingPool *self, InStream *lex_temp_in,
              InStream *post_temp_in) {
-    if (self->flipped) { THROW(ERR, "Can't Flip twice"); }
-    self->flipped = true;
+    PostingPoolIVARS *const ivars = PostPool_IVARS(self);
+    if (ivars->flipped) { THROW(ERR, "Can't Flip twice"); }
+    ivars->flipped = true;
 
     // Sort RawPostings in cache, if any.
     PostPool_Sort_Cache(self);
 
     // Bail if never flushed.
-    if (self->lex_end == 0) { return; }
+    if (ivars->lex_end == 0) { return; }
 
     // Get a Lexicon.
     CharBuf *lex_alias = CB_newf("%o-%i64-to-%i64",
                                  InStream_Get_Filename(lex_temp_in),
-                                 self->lex_start, self->lex_end);
+                                 ivars->lex_start, ivars->lex_end);
     InStream *lex_temp_in_dupe = InStream_Reopen(
-                                     lex_temp_in, lex_alias, self->lex_start,
-                                     self->lex_end - self->lex_start);
-    self->lexicon = (Lexicon*)RawLex_new(
-                        self->schema, self->field, lex_temp_in_dupe, 0,
-                        self->lex_end - self->lex_start);
+                                     lex_temp_in, lex_alias, ivars->lex_start,
+                                     ivars->lex_end - ivars->lex_start);
+    ivars->lexicon = (Lexicon*)RawLex_new(
+                        ivars->schema, ivars->field, lex_temp_in_dupe, 0,
+                        ivars->lex_end - ivars->lex_start);
     DECREF(lex_alias);
     DECREF(lex_temp_in_dupe);
 
     // Get a PostingList.
     CharBuf *post_alias
         = CB_newf("%o-%i64-to-%i64", InStream_Get_Filename(post_temp_in),
-                  self->post_start, self->post_end);
+                  ivars->post_start, ivars->post_end);
     InStream *post_temp_in_dupe
-        = InStream_Reopen(post_temp_in, post_alias, self->post_start,
-                          self->post_end - self->post_start);
-    self->plist
-        = (PostingList*)RawPList_new(self->schema, self->field,
+        = InStream_Reopen(post_temp_in, post_alias, ivars->post_start,
+                          ivars->post_end - ivars->post_start);
+    ivars->plist
+        = (PostingList*)RawPList_new(ivars->schema, ivars->field,
                                      post_temp_in_dupe, 0,
-                                     self->post_end - self->post_start);
+                                     ivars->post_end - ivars->post_start);
     DECREF(post_alias);
     DECREF(post_temp_in_dupe);
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/RawLexicon.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/RawLexicon.c b/core/Lucy/Index/RawLexicon.c
index eef6eac..49e4e20 100644
--- a/core/Lucy/Index/RawLexicon.c
+++ b/core/Lucy/Index/RawLexicon.c
@@ -37,47 +37,52 @@ RawLex_init(RawLexicon *self, Schema *schema, const CharBuf *field,
             InStream *instream, int64_t start, int64_t end) {
     FieldType *type = Schema_Fetch_Type(schema, field);
     Lex_init((Lexicon*)self, field);
+    RawLexiconIVARS *const ivars = RawLex_IVARS(self);
 
     // Assign
-    self->start = start;
-    self->end   = end;
-    self->len   = end - start;
-    self->instream = (InStream*)INCREF(instream);
+    ivars->start = start;
+    ivars->end   = end;
+    ivars->len   = end - start;
+    ivars->instream = (InStream*)INCREF(instream);
 
     // Get ready to begin.
-    InStream_Seek(self->instream, self->start);
+    InStream_Seek(ivars->instream, ivars->start);
 
     // Get steppers.
-    self->term_stepper  = FType_Make_Term_Stepper(type);
-    self->tinfo_stepper = (TermStepper*)MatchTInfoStepper_new(schema);
+    ivars->term_stepper  = FType_Make_Term_Stepper(type);
+    ivars->tinfo_stepper = (TermStepper*)MatchTInfoStepper_new(schema);
 
     return self;
 }
 
 void
 RawLex_destroy(RawLexicon *self) {
-    DECREF(self->instream);
-    DECREF(self->term_stepper);
-    DECREF(self->tinfo_stepper);
+    RawLexiconIVARS *const ivars = RawLex_IVARS(self);
+    DECREF(ivars->instream);
+    DECREF(ivars->term_stepper);
+    DECREF(ivars->tinfo_stepper);
     SUPER_DESTROY(self, RAWLEXICON);
 }
 
 bool
 RawLex_next(RawLexicon *self) {
-    if (InStream_Tell(self->instream) >= self->len) { return false; }
-    TermStepper_Read_Delta(self->term_stepper, self->instream);
-    TermStepper_Read_Delta(self->tinfo_stepper, self->instream);
+    RawLexiconIVARS *const ivars = RawLex_IVARS(self);
+    if (InStream_Tell(ivars->instream) >= ivars->len) { return false; }
+    TermStepper_Read_Delta(ivars->term_stepper, ivars->instream);
+    TermStepper_Read_Delta(ivars->tinfo_stepper, ivars->instream);
     return true;
 }
 
 Obj*
 RawLex_get_term(RawLexicon *self) {
-    return TermStepper_Get_Value(self->term_stepper);
+    RawLexiconIVARS *const ivars = RawLex_IVARS(self);
+    return TermStepper_Get_Value(ivars->term_stepper);
 }
 
 int32_t
 RawLex_doc_freq(RawLexicon *self) {
-    TermInfo *tinfo = (TermInfo*)TermStepper_Get_Value(self->tinfo_stepper);
+    RawLexiconIVARS *const ivars = RawLex_IVARS(self);
+    TermInfo *tinfo = (TermInfo*)TermStepper_Get_Value(ivars->tinfo_stepper);
     return tinfo ? TInfo_Get_Doc_Freq(tinfo) : 0;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/RawPostingList.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/RawPostingList.c b/core/Lucy/Index/RawPostingList.c
index a22a015..9d5dd0a 100644
--- a/core/Lucy/Index/RawPostingList.c
+++ b/core/Lucy/Index/RawPostingList.c
@@ -36,32 +36,35 @@ RawPostingList*
 RawPList_init(RawPostingList *self, Schema *schema, const CharBuf *field,
               InStream *instream, int64_t start, int64_t end) {
     PList_init((PostingList*)self);
-    self->start     = start;
-    self->end       = end;
-    self->len       = end - start;
-    self->instream  = (InStream*)INCREF(instream);
-    Similarity *sim = Schema_Fetch_Sim(schema, field);
-    self->posting   = Sim_Make_Posting(sim);
-    InStream_Seek(self->instream, self->start);
+    RawPostingListIVARS *const ivars = RawPList_IVARS(self);
+    ivars->start     = start;
+    ivars->end       = end;
+    ivars->len       = end - start;
+    ivars->instream  = (InStream*)INCREF(instream);
+    Similarity *sim  = Schema_Fetch_Sim(schema, field);
+    ivars->posting   = Sim_Make_Posting(sim);
+    InStream_Seek(ivars->instream, ivars->start);
     return self;
 }
 
 void
 RawPList_destroy(RawPostingList *self) {
-    DECREF(self->instream);
-    DECREF(self->posting);
+    RawPostingListIVARS *const ivars = RawPList_IVARS(self);
+    DECREF(ivars->instream);
+    DECREF(ivars->posting);
     SUPER_DESTROY(self, RAWPOSTINGLIST);
 }
 
 Posting*
 RawPList_get_posting(RawPostingList *self) {
-    return self->posting;
+    return RawPList_IVARS(self)->posting;
 }
 
 RawPosting*
 RawPList_read_raw(RawPostingList *self, int32_t last_doc_id, CharBuf *term_text,
                   MemoryPool *mem_pool) {
-    return Post_Read_Raw(self->posting, self->instream,
+    RawPostingListIVARS *const ivars = RawPList_IVARS(self);
+    return Post_Read_Raw(ivars->posting, ivars->instream,
                          last_doc_id, term_text, mem_pool);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/SegLexicon.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/SegLexicon.c b/core/Lucy/Index/SegLexicon.c
index 06704f2..3a6523f 100644
--- a/core/Lucy/Index/SegLexicon.c
+++ b/core/Lucy/Index/SegLexicon.c
@@ -58,6 +58,7 @@ SegLex_init(SegLexicon *self, Schema *schema, Folder *folder,
     CharBuf *filename = CB_newf("%o/lexicon-%i32.dat", seg_name, field_num);
 
     Lex_init((Lexicon*)self, field);
+    SegLexiconIVARS *const ivars = SegLex_IVARS(self);
 
     // Check format.
     if (!format) { THROW(ERR, "Missing 'format'"); }
@@ -72,19 +73,19 @@ SegLex_init(SegLexicon *self, Schema *schema, Folder *folder,
     if (!counts) { THROW(ERR, "Failed to extract 'counts'"); }
     else {
         Obj *count = CERTIFY(Hash_Fetch(counts, (Obj*)field), OBJ);
-        self->size = (int32_t)Obj_To_I64(count);
+        ivars->size = (int32_t)Obj_To_I64(count);
     }
 
     // Assign.
-    self->segment        = (Segment*)INCREF(segment);
+    ivars->segment        = (Segment*)INCREF(segment);
 
     // Derive.
-    self->lex_index      = LexIndex_new(schema, folder, segment, field);
-    self->field_num      = field_num;
-    self->index_interval = Arch_Index_Interval(arch);
-    self->skip_interval  = Arch_Skip_Interval(arch);
-    self->instream       = Folder_Open_In(folder, filename);
-    if (!self->instream) {
+    ivars->lex_index      = LexIndex_new(schema, folder, segment, field);
+    ivars->field_num      = field_num;
+    ivars->index_interval = Arch_Index_Interval(arch);
+    ivars->skip_interval  = Arch_Skip_Interval(arch);
+    ivars->instream       = Folder_Open_In(folder, filename);
+    if (!ivars->instream) {
         Err *error = (Err*)INCREF(Err_get_error());
         DECREF(filename);
         DECREF(self);
@@ -93,28 +94,30 @@ SegLex_init(SegLexicon *self, Schema *schema, Folder *folder,
     DECREF(filename);
 
     // Define the term_num as "not yet started".
-    self->term_num = -1;
+    ivars->term_num = -1;
 
     // Get steppers.
-    self->term_stepper  = FType_Make_Term_Stepper(type);
-    self->tinfo_stepper = (TermStepper*)MatchTInfoStepper_new(schema);
+    ivars->term_stepper  = FType_Make_Term_Stepper(type);
+    ivars->tinfo_stepper = (TermStepper*)MatchTInfoStepper_new(schema);
 
     return self;
 }
 
 void
 SegLex_destroy(SegLexicon *self) {
-    DECREF(self->segment);
-    DECREF(self->term_stepper);
-    DECREF(self->tinfo_stepper);
-    DECREF(self->lex_index);
-    DECREF(self->instream);
+    SegLexiconIVARS *const ivars = SegLex_IVARS(self);
+    DECREF(ivars->segment);
+    DECREF(ivars->term_stepper);
+    DECREF(ivars->tinfo_stepper);
+    DECREF(ivars->lex_index);
+    DECREF(ivars->instream);
     SUPER_DESTROY(self, SEGLEXICON);
 }
 
 void
 SegLex_seek(SegLexicon *self, Obj *target) {
-    LexIndex *const lex_index = self->lex_index;
+    SegLexiconIVARS *const ivars = SegLex_IVARS(self);
+    LexIndex *const lex_index = ivars->lex_index;
 
     // Reset upon null term.
     if (target == NULL) {
@@ -126,13 +129,13 @@ SegLex_seek(SegLexicon *self, Obj *target) {
     LexIndex_Seek(lex_index, target);
     TermInfo *target_tinfo = LexIndex_Get_Term_Info(lex_index);
     TermInfo *my_tinfo
-        = (TermInfo*)TermStepper_Get_Value(self->tinfo_stepper);
+        = (TermInfo*)TermStepper_Get_Value(ivars->tinfo_stepper);
     Obj *lex_index_term = Obj_Clone(LexIndex_Get_Term(lex_index));
     TInfo_Mimic(my_tinfo, (Obj*)target_tinfo);
-    TermStepper_Set_Value(self->term_stepper, lex_index_term);
+    TermStepper_Set_Value(ivars->term_stepper, lex_index_term);
     DECREF(lex_index_term);
-    InStream_Seek(self->instream, TInfo_Get_Lex_FilePos(target_tinfo));
-    self->term_num = LexIndex_Get_Term_Num(lex_index);
+    InStream_Seek(ivars->instream, TInfo_Get_Lex_FilePos(target_tinfo));
+    ivars->term_num = LexIndex_Get_Term_Num(lex_index);
 
     // Scan to the precise location.
     S_scan_to(self, target);
@@ -140,59 +143,67 @@ SegLex_seek(SegLexicon *self, Obj *target) {
 
 void
 SegLex_reset(SegLexicon* self) {
-    self->term_num = -1;
-    InStream_Seek(self->instream, 0);
-    TermStepper_Reset(self->term_stepper);
-    TermStepper_Reset(self->tinfo_stepper);
+    SegLexiconIVARS *const ivars = SegLex_IVARS(self);
+    ivars->term_num = -1;
+    InStream_Seek(ivars->instream, 0);
+    TermStepper_Reset(ivars->term_stepper);
+    TermStepper_Reset(ivars->tinfo_stepper);
 }
 
 int32_t
 SegLex_get_field_num(SegLexicon *self) {
-    return self->field_num;
+    return SegLex_IVARS(self)->field_num;
 }
 
 Obj*
 SegLex_get_term(SegLexicon *self) {
-    return TermStepper_Get_Value(self->term_stepper);
+    SegLexiconIVARS *const ivars = SegLex_IVARS(self);
+    return TermStepper_Get_Value(ivars->term_stepper);
 }
 
 int32_t
 SegLex_doc_freq(SegLexicon *self) {
-    TermInfo *tinfo = (TermInfo*)TermStepper_Get_Value(self->tinfo_stepper);
+    SegLexiconIVARS *const ivars = SegLex_IVARS(self);
+    TermInfo *tinfo = (TermInfo*)TermStepper_Get_Value(ivars->tinfo_stepper);
     return tinfo ? TInfo_Get_Doc_Freq(tinfo) : 0;
 }
 
 TermInfo*
 SegLex_get_term_info(SegLexicon *self) {
-    return (TermInfo*)TermStepper_Get_Value(self->tinfo_stepper);
+    SegLexiconIVARS *const ivars = SegLex_IVARS(self);
+    return (TermInfo*)TermStepper_Get_Value(ivars->tinfo_stepper);
 }
 
 Segment*
 SegLex_get_segment(SegLexicon *self) {
-    return self->segment;
+    return SegLex_IVARS(self)->segment;
 }
 
 bool
 SegLex_next(SegLexicon *self) {
+    SegLexiconIVARS *const ivars = SegLex_IVARS(self);
+
     // If we've run out of terms, null out and return.
-    if (++self->term_num >= self->size) {
-        self->term_num = self->size; // don't keep growing
-        TermStepper_Reset(self->term_stepper);
-        TermStepper_Reset(self->tinfo_stepper);
+    if (++ivars->term_num >= ivars->size) {
+        ivars->term_num = ivars->size; // don't keep growing
+        TermStepper_Reset(ivars->term_stepper);
+        TermStepper_Reset(ivars->tinfo_stepper);
         return false;
     }
 
     // Read next term/terminfo.
-    TermStepper_Read_Delta(self->term_stepper, self->instream);
-    TermStepper_Read_Delta(self->tinfo_stepper, self->instream);
+    TermStepper_Read_Delta(ivars->term_stepper, ivars->instream);
+    TermStepper_Read_Delta(ivars->tinfo_stepper, ivars->instream);
 
     return true;
 }
 
 static void
 S_scan_to(SegLexicon *self, Obj *target) {
+    SegLexiconIVARS *const ivars = SegLex_IVARS(self);
+
     // (mildly evil encapsulation violation, since value can be null)
-    Obj *current = TermStepper_Get_Value(self->term_stepper);
+    Obj *current = TermStepper_Get_Value(ivars->term_stepper);
     if (!Obj_Is_A(target, Obj_Get_VTable(current))) {
         THROW(ERR, "Target is a %o, and not comparable to a %o",
               Obj_Get_Class_Name(target), Obj_Get_Class_Name(current));
@@ -201,7 +212,7 @@ S_scan_to(SegLexicon *self, Obj *target) {
     // Keep looping until the term text is ge target.
     do {
         const int32_t comparison = Obj_Compare_To(current, target);
-        if (comparison >= 0 &&  self->term_num != -1) { break; }
+        if (comparison >= 0 && ivars->term_num != -1) { break; }
     } while (SegLex_Next(self));
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/SegPostingList.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/SegPostingList.c b/core/Lucy/Index/SegPostingList.c
index ae9122e..bebd52d 100644
--- a/core/Lucy/Index/SegPostingList.c
+++ b/core/Lucy/Index/SegPostingList.c
@@ -51,6 +51,7 @@ SegPList_new(PostingListReader *plist_reader, const CharBuf *field) {
 SegPostingList*
 SegPList_init(SegPostingList *self, PostingListReader *plist_reader,
               const CharBuf *field) {
+    SegPostingListIVARS *const ivars = SegPList_IVARS(self);
     Schema       *const schema   = PListReader_Get_Schema(plist_reader);
     Folder       *const folder   = PListReader_Get_Folder(plist_reader);
     Segment      *const segment  = PListReader_Get_Segment(plist_reader);
@@ -62,36 +63,36 @@ SegPList_init(SegPostingList *self, PostingListReader *plist_reader,
     CharBuf      *skip_file      = CB_newf("%o/postings.skip", seg_name);
 
     // Init.
-    self->doc_freq        = 0;
-    self->count           = 0;
+    ivars->doc_freq        = 0;
+    ivars->count           = 0;
 
     // Init skipping vars.
-    self->skip_stepper    = SkipStepper_new();
-    self->skip_count      = 0;
-    self->num_skips       = 0;
+    ivars->skip_stepper    = SkipStepper_new();
+    ivars->skip_count      = 0;
+    ivars->num_skips       = 0;
 
     // Assign.
-    self->plist_reader    = (PostingListReader*)INCREF(plist_reader);
-    self->field           = CB_Clone(field);
-    self->skip_interval   = Arch_Skip_Interval(arch);
+    ivars->plist_reader    = (PostingListReader*)INCREF(plist_reader);
+    ivars->field           = CB_Clone(field);
+    ivars->skip_interval   = Arch_Skip_Interval(arch);
 
     // Derive.
-    Similarity *sim = Schema_Fetch_Sim(schema, field);
-    self->posting   = Sim_Make_Posting(sim);
-    self->field_num = field_num;
+    Similarity *sim  = Schema_Fetch_Sim(schema, field);
+    ivars->posting   = Sim_Make_Posting(sim);
+    ivars->field_num = field_num;
 
     // Open both a main stream and a skip stream if the field exists.
     if (Folder_Exists(folder, post_file)) {
-        self->post_stream = Folder_Open_In(folder, post_file);
-        if (!self->post_stream) {
+        ivars->post_stream = Folder_Open_In(folder, post_file);
+        if (!ivars->post_stream) {
             Err *error = (Err*)INCREF(Err_get_error());
             DECREF(post_file);
             DECREF(skip_file);
             DECREF(self);
             RETHROW(error);
         }
-        self->skip_stream = Folder_Open_In(folder, skip_file);
-        if (!self->skip_stream) {
+        ivars->skip_stream = Folder_Open_In(folder, skip_file);
+        if (!ivars->skip_stream) {
             Err *error = (Err*)INCREF(Err_get_error());
             DECREF(post_file);
             DECREF(skip_file);
@@ -101,8 +102,8 @@ SegPList_init(SegPostingList *self, PostingListReader *plist_reader,
     }
     else {
         //  Empty, so don't bother with these.
-        self->post_stream = NULL;
-        self->skip_stream = NULL;
+        ivars->post_stream = NULL;
+        ivars->skip_stream = NULL;
     }
     DECREF(post_file);
     DECREF(skip_file);
@@ -112,16 +113,17 @@ SegPList_init(SegPostingList *self, PostingListReader *plist_reader,
 
 void
 SegPList_destroy(SegPostingList *self) {
-    DECREF(self->plist_reader);
-    DECREF(self->posting);
-    DECREF(self->skip_stepper);
-    DECREF(self->field);
-
-    if (self->post_stream != NULL) {
-        InStream_Close(self->post_stream);
-        InStream_Close(self->skip_stream);
-        DECREF(self->post_stream);
-        DECREF(self->skip_stream);
+    SegPostingListIVARS *const ivars = SegPList_IVARS(self);
+    DECREF(ivars->plist_reader);
+    DECREF(ivars->posting);
+    DECREF(ivars->skip_stepper);
+    DECREF(ivars->field);
+
+    if (ivars->post_stream != NULL) {
+        InStream_Close(ivars->post_stream);
+        InStream_Close(ivars->skip_stream);
+        DECREF(ivars->post_stream);
+        DECREF(ivars->skip_stream);
     }
 
     SUPER_DESTROY(self, SEGPOSTINGLIST);
@@ -129,56 +131,61 @@ SegPList_destroy(SegPostingList *self) {
 
 Posting*
 SegPList_get_posting(SegPostingList *self) {
-    return self->posting;
+    return SegPList_IVARS(self)->posting;
 }
 
 uint32_t
 SegPList_get_doc_freq(SegPostingList *self) {
-    return self->doc_freq;
+    return SegPList_IVARS(self)->doc_freq;
 }
 
 int32_t
 SegPList_get_doc_id(SegPostingList *self) {
-    return self->posting->doc_id;
+    SegPostingListIVARS *const ivars = SegPList_IVARS(self);
+    return Post_IVARS(ivars->posting)->doc_id;
 }
 
 uint32_t
 SegPList_get_count(SegPostingList *self) {
-    return self->count;
+    return SegPList_IVARS(self)->count;
 }
 
 InStream*
 SegPList_get_post_stream(SegPostingList *self) {
-    return self->post_stream;
+    return SegPList_IVARS(self)->post_stream;
 }
 
 int32_t
 SegPList_next(SegPostingList *self) {
-    InStream *const post_stream = self->post_stream;
-    Posting  *const posting     = self->posting;
+    SegPostingListIVARS *const ivars = SegPList_IVARS(self);
+    InStream *const post_stream = ivars->post_stream;
+    Posting  *const posting     = ivars->posting;
 
     // Bail if we're out of docs.
-    if (self->count >= self->doc_freq) {
+    if (ivars->count >= ivars->doc_freq) {
         Post_Reset(posting);
         return 0;
     }
-    self->count++;
+    ivars->count++;
 
     Post_Read_Record(posting, post_stream);
 
-    return posting->doc_id;
+    return Post_IVARS(posting)->doc_id;
 }
 
 int32_t
 SegPList_advance(SegPostingList *self, int32_t target) {
-    Posting *posting          = self->posting;
-    const uint32_t skip_interval = self->skip_interval;
-
-    if (self->doc_freq >= skip_interval) {
-        InStream *post_stream           = self->post_stream;
-        InStream *skip_stream           = self->skip_stream;
-        SkipStepper *const skip_stepper = self->skip_stepper;
-        uint32_t new_doc_id             = skip_stepper->doc_id;
+    SegPostingListIVARS *const ivars = SegPList_IVARS(self);
+    PostingIVARS *const posting_ivars = Post_IVARS(ivars->posting);
+    const uint32_t skip_interval = ivars->skip_interval;
+
+    if (ivars->doc_freq >= skip_interval) {
+        InStream *post_stream           = ivars->post_stream;
+        InStream *skip_stream           = ivars->skip_stream;
+        SkipStepper *const skip_stepper = ivars->skip_stepper;
+        SkipStepperIVARS *const skip_stepper_ivars
+            = SkipStepper_IVARS(skip_stepper);
+        uint32_t new_doc_id             = skip_stepper_ivars->doc_id;
         int64_t new_filepos             = InStream_Tell(post_stream);
 
         /* Assuming the default skip_interval of 16...
@@ -188,28 +195,28 @@ SegPList_advance(SegPostingList *self, int32_t target) {
          * yet, but we'll have already gone past 5 of the 16 skip docs --
          * ergo, the modulus in the following formula.
          */
-        int32_t num_skipped = 0 - (self->count % skip_interval);
-        if (num_skipped == 0 && self->count != 0) {
+        int32_t num_skipped = 0 - (ivars->count % skip_interval);
+        if (num_skipped == 0 && ivars->count != 0) {
             num_skipped = 0 - skip_interval;
         }
 
         // See if there's anything to skip.
-        while (target > skip_stepper->doc_id) {
-            new_doc_id  = skip_stepper->doc_id;
-            new_filepos = skip_stepper->filepos;
+        while (target > skip_stepper_ivars->doc_id) {
+            new_doc_id  = skip_stepper_ivars->doc_id;
+            new_filepos = skip_stepper_ivars->filepos;
 
-            if (skip_stepper->doc_id != 0
-                && skip_stepper->doc_id >= posting->doc_id
+            if (skip_stepper_ivars->doc_id != 0
+                && skip_stepper_ivars->doc_id >= posting_ivars->doc_id
                ) {
                 num_skipped += skip_interval;
             }
 
-            if (self->skip_count >= self->num_skips) {
+            if (ivars->skip_count >= ivars->num_skips) {
                 break;
             }
 
             SkipStepper_Read_Record(skip_stepper, skip_stream);
-            self->skip_count++;
+            ivars->skip_count++;
         }
 
         // If we found something to skip, skip it.
@@ -219,10 +226,10 @@ SegPList_advance(SegPostingList *self, int32_t target) {
             InStream_Seek(post_stream, new_filepos);
 
             // Jump to the new doc id.
-            posting->doc_id = new_doc_id;
+            posting_ivars->doc_id = new_doc_id;
 
             // Increase count by the number of docs we skipped over.
-            self->count += num_skipped;
+            ivars->count += num_skipped;
         }
     }
 
@@ -237,22 +244,25 @@ SegPList_advance(SegPostingList *self, int32_t target) {
 
 void
 SegPList_seek(SegPostingList *self, Obj *target) {
-    LexiconReader *lex_reader = PListReader_Get_Lex_Reader(self->plist_reader);
+    SegPostingListIVARS *const ivars = SegPList_IVARS(self);
+    LexiconReader *lex_reader = PListReader_Get_Lex_Reader(ivars->plist_reader);
     TermInfo      *tinfo      = LexReader_Fetch_Term_Info(lex_reader,
-                                                          self->field, target);
+                                                          ivars->field, target);
     S_seek_tinfo(self, tinfo);
     DECREF(tinfo);
 }
 
 void
 SegPList_seek_lex(SegPostingList *self, Lexicon *lexicon) {
+    SegPostingListIVARS *const ivars = SegPList_IVARS(self);
+
     // Maybe true, maybe not.
     SegLexicon *const seg_lexicon = (SegLexicon*)lexicon;
 
     // Optimized case.
     if (Obj_Is_A((Obj*)lexicon, SEGLEXICON)
         && (SegLex_Get_Segment(seg_lexicon)
-            == PListReader_Get_Segment(self->plist_reader)) // i.e. same segment
+            == PListReader_Get_Segment(ivars->plist_reader)) // i.e. same segment
        ) {
         S_seek_tinfo(self, SegLex_Get_Term_Info(seg_lexicon));
     }
@@ -266,40 +276,43 @@ SegPList_seek_lex(SegPostingList *self, Lexicon *lexicon) {
 
 static void
 S_seek_tinfo(SegPostingList *self, TermInfo *tinfo) {
-    self->count = 0;
+    SegPostingListIVARS *const ivars = SegPList_IVARS(self);
+    ivars->count = 0;
 
     if (tinfo == NULL) {
         // Next will return false; other methods invalid now.
-        self->doc_freq = 0;
+        ivars->doc_freq = 0;
     }
     else {
         // Transfer doc_freq, seek main stream.
         int64_t post_filepos = TInfo_Get_Post_FilePos(tinfo);
-        self->doc_freq       = TInfo_Get_Doc_Freq(tinfo);
-        InStream_Seek(self->post_stream, post_filepos);
+        ivars->doc_freq      = TInfo_Get_Doc_Freq(tinfo);
+        InStream_Seek(ivars->post_stream, post_filepos);
 
         // Prepare posting.
-        Post_Reset(self->posting);
+        Post_Reset(ivars->posting);
 
         // Prepare to skip.
-        self->skip_count = 0;
-        self->num_skips  = self->doc_freq / self->skip_interval;
-        SkipStepper_Set_ID_And_Filepos(self->skip_stepper, 0, post_filepos);
-        InStream_Seek(self->skip_stream, TInfo_Get_Skip_FilePos(tinfo));
+        ivars->skip_count = 0;
+        ivars->num_skips  = ivars->doc_freq / ivars->skip_interval;
+        SkipStepper_Set_ID_And_Filepos(ivars->skip_stepper, 0, post_filepos);
+        InStream_Seek(ivars->skip_stream, TInfo_Get_Skip_FilePos(tinfo));
     }
 }
 
 Matcher*
 SegPList_make_matcher(SegPostingList *self, Similarity *sim,
                       Compiler *compiler, bool need_score) {
-    return Post_Make_Matcher(self->posting, sim, (PostingList*)self, compiler,
+    SegPostingListIVARS *const ivars = SegPList_IVARS(self);
+    return Post_Make_Matcher(ivars->posting, sim, (PostingList*)self, compiler,
                              need_score);
 }
 
 RawPosting*
 SegPList_read_raw(SegPostingList *self, int32_t last_doc_id, CharBuf *term_text,
                   MemoryPool *mem_pool) {
-    return Post_Read_Raw(self->posting, self->post_stream,
+    SegPostingListIVARS *const ivars = SegPList_IVARS(self);
+    return Post_Read_Raw(ivars->posting, ivars->post_stream,
                          last_doc_id, term_text, mem_pool);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/SegReader.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/SegReader.c b/core/Lucy/Index/SegReader.c
index ad803b2..e9a1ba6 100644
--- a/core/Lucy/Index/SegReader.c
+++ b/core/Lucy/Index/SegReader.c
@@ -47,11 +47,12 @@ SegReader_init(SegReader *self, Schema *schema, Folder *folder,
 
     IxReader_init((IndexReader*)self, schema, folder, snapshot, segments,
                   seg_tick, NULL);
+    SegReaderIVARS *const ivars = SegReader_IVARS(self);
     segment = SegReader_Get_Segment(self);
 
-    self->doc_max    = (int32_t)Seg_Get_Count(segment);
-    self->seg_name   = (CharBuf*)INCREF(Seg_Get_Name(segment));
-    self->seg_num    = Seg_Get_Number(segment);
+    ivars->doc_max    = (int32_t)Seg_Get_Count(segment);
+    ivars->seg_name   = (CharBuf*)INCREF(Seg_Get_Name(segment));
+    ivars->seg_num    = Seg_Get_Number(segment);
     Err *error = Err_trap(S_try_init_components, self);
     if (error) {
         // An error occurred, so clean up self and rethrow the exception.
@@ -61,8 +62,8 @@ SegReader_init(SegReader *self, Schema *schema, Folder *folder,
 
     DeletionsReader *del_reader
         = (DeletionsReader*)Hash_Fetch(
-              self->components, (Obj*)VTable_Get_Name(DELETIONSREADER));
-    self->del_count = del_reader ? DelReader_Del_Count(del_reader) : 0;
+              ivars->components, (Obj*)VTable_Get_Name(DELETIONSREADER));
+    ivars->del_count = del_reader ? DelReader_Del_Count(del_reader) : 0;
 
     return self;
 }
@@ -77,43 +78,46 @@ S_try_init_components(void *context) {
 
 void
 SegReader_destroy(SegReader *self) {
-    DECREF(self->seg_name);
+    SegReaderIVARS *const ivars = SegReader_IVARS(self);
+    DECREF(ivars->seg_name);
     SUPER_DESTROY(self, SEGREADER);
 }
 
 void
 SegReader_register(SegReader *self, const CharBuf *api,
                    DataReader *component) {
-    if (Hash_Fetch(self->components, (Obj*)api)) {
+    SegReaderIVARS *const ivars = SegReader_IVARS(self);
+    if (Hash_Fetch(ivars->components, (Obj*)api)) {
         THROW(ERR, "Interface '%o' already registered");
     }
     CERTIFY(component, DATAREADER);
-    Hash_Store(self->components, (Obj*)api, (Obj*)component);
+    Hash_Store(ivars->components, (Obj*)api, (Obj*)component);
 }
 
 CharBuf*
 SegReader_get_seg_name(SegReader *self) {
-    return self->seg_name;
+    return SegReader_IVARS(self)->seg_name;
 }
 
 int64_t
 SegReader_get_seg_num(SegReader *self) {
-    return self->seg_num;
+    return SegReader_IVARS(self)->seg_num;
 }
 
 int32_t
 SegReader_del_count(SegReader *self) {
-    return self->del_count;
+    return SegReader_IVARS(self)->del_count;
 }
 
 int32_t
 SegReader_doc_max(SegReader *self) {
-    return self->doc_max;
+    return SegReader_IVARS(self)->doc_max;
 }
 
 int32_t
 SegReader_doc_count(SegReader *self) {
-    return self->doc_max - self->del_count;
+    SegReaderIVARS *const ivars = SegReader_IVARS(self);
+    return ivars->doc_max - ivars->del_count;
 }
 
 I32Array*

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/SegWriter.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/SegWriter.c b/core/Lucy/Index/SegWriter.c
index 02fe391..6280664 100644
--- a/core/Lucy/Index/SegWriter.c
+++ b/core/Lucy/Index/SegWriter.c
@@ -42,46 +42,52 @@ SegWriter_init(SegWriter *self, Schema *schema, Snapshot *snapshot,
                Segment *segment, PolyReader *polyreader) {
     Architecture *arch   = Schema_Get_Architecture(schema);
     DataWriter_init((DataWriter*)self, schema, snapshot, segment, polyreader);
-    self->by_api   = Hash_new(0);
-    self->inverter = Inverter_new(schema, segment);
-    self->writers  = VA_new(16);
+    SegWriterIVARS *const ivars = SegWriter_IVARS(self);
+    ivars->by_api   = Hash_new(0);
+    ivars->inverter = Inverter_new(schema, segment);
+    ivars->writers  = VA_new(16);
     Arch_Init_Seg_Writer(arch, self);
     return self;
 }
 
 void
 SegWriter_destroy(SegWriter *self) {
-    DECREF(self->inverter);
-    DECREF(self->writers);
-    DECREF(self->by_api);
-    DECREF(self->del_writer);
+    SegWriterIVARS *const ivars = SegWriter_IVARS(self);
+    DECREF(ivars->inverter);
+    DECREF(ivars->writers);
+    DECREF(ivars->by_api);
+    DECREF(ivars->del_writer);
     SUPER_DESTROY(self, SEGWRITER);
 }
 
 void
 SegWriter_register(SegWriter *self, const CharBuf *api,
                    DataWriter *component) {
+    SegWriterIVARS *const ivars = SegWriter_IVARS(self);
     CERTIFY(component, DATAWRITER);
-    if (Hash_Fetch(self->by_api, (Obj*)api)) {
+    if (Hash_Fetch(ivars->by_api, (Obj*)api)) {
         THROW(ERR, "API %o already registered", api);
     }
-    Hash_Store(self->by_api, (Obj*)api, (Obj*)component);
+    Hash_Store(ivars->by_api, (Obj*)api, (Obj*)component);
 }
 
 Obj*
 SegWriter_fetch(SegWriter *self, const CharBuf *api) {
-    return Hash_Fetch(self->by_api, (Obj*)api);
+    SegWriterIVARS *const ivars = SegWriter_IVARS(self);
+    return Hash_Fetch(ivars->by_api, (Obj*)api);
 }
 
 void
 SegWriter_add_writer(SegWriter *self, DataWriter *writer) {
-    VA_Push(self->writers, (Obj*)writer);
+    SegWriterIVARS *const ivars = SegWriter_IVARS(self);
+    VA_Push(ivars->writers, (Obj*)writer);
 }
 
 void
 SegWriter_prep_seg_dir(SegWriter *self) {
+    SegWriterIVARS *const ivars = SegWriter_IVARS(self);
     Folder  *folder   = SegWriter_Get_Folder(self);
-    CharBuf *seg_name = Seg_Get_Name(self->segment);
+    CharBuf *seg_name = Seg_Get_Name(ivars->segment);
 
     // Clear stale segment files from crashed indexing sessions.
     if (Folder_Exists(folder, seg_name)) {
@@ -98,17 +104,19 @@ SegWriter_prep_seg_dir(SegWriter *self) {
 
 void
 SegWriter_add_doc(SegWriter *self, Doc *doc, float boost) {
-    int32_t doc_id = (int32_t)Seg_Increment_Count(self->segment, 1);
-    Inverter_Invert_Doc(self->inverter, doc);
-    Inverter_Set_Boost(self->inverter, boost);
-    SegWriter_Add_Inverted_Doc(self, self->inverter, doc_id);
+    SegWriterIVARS *const ivars = SegWriter_IVARS(self);
+    int32_t doc_id = (int32_t)Seg_Increment_Count(ivars->segment, 1);
+    Inverter_Invert_Doc(ivars->inverter, doc);
+    Inverter_Set_Boost(ivars->inverter, boost);
+    SegWriter_Add_Inverted_Doc(self, ivars->inverter, doc_id);
 }
 
 void
 SegWriter_add_inverted_doc(SegWriter *self, Inverter *inverter,
                            int32_t doc_id) {
-    for (uint32_t i = 0, max = VA_Get_Size(self->writers); i < max; i++) {
-        DataWriter *writer = (DataWriter*)VA_Fetch(self->writers, i);
+    SegWriterIVARS *const ivars = SegWriter_IVARS(self);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->writers); i < max; i++) {
+        DataWriter *writer = (DataWriter*)VA_Fetch(ivars->writers, i);
         DataWriter_Add_Inverted_Doc(writer, inverter, doc_id);
     }
 }
@@ -118,24 +126,27 @@ SegWriter_add_inverted_doc(SegWriter *self, Inverter *inverter,
 // probably out of sync.
 static void
 S_adjust_doc_id(SegWriter *self, SegReader *reader, I32Array *doc_map) {
+    SegWriterIVARS *const ivars = SegWriter_IVARS(self);
     uint32_t doc_count = SegReader_Doc_Max(reader);
     for (uint32_t i = 1, max = I32Arr_Get_Size(doc_map); i < max; i++) {
         if (I32Arr_Get(doc_map, i) == 0) { doc_count--; }
     }
-    Seg_Increment_Count(self->segment, doc_count);
+    Seg_Increment_Count(ivars->segment, doc_count);
 }
 
 void
 SegWriter_add_segment(SegWriter *self, SegReader *reader, I32Array *doc_map) {
+    SegWriterIVARS *const ivars = SegWriter_IVARS(self);
+
     // Bulk add the slab of documents to the various writers.
-    for (uint32_t i = 0, max = VA_Get_Size(self->writers); i < max; i++) {
-        DataWriter *writer = (DataWriter*)VA_Fetch(self->writers, i);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->writers); i < max; i++) {
+        DataWriter *writer = (DataWriter*)VA_Fetch(ivars->writers, i);
         DataWriter_Add_Segment(writer, reader, doc_map);
     }
 
     // Bulk add the segment to the DeletionsWriter, so that it can merge
     // previous segment files as necessary.
-    DelWriter_Add_Segment(self->del_writer, reader, doc_map);
+    DelWriter_Add_Segment(ivars->del_writer, reader, doc_map);
 
     // Adust the document id.
     S_adjust_doc_id(self, reader, doc_map);
@@ -144,15 +155,16 @@ SegWriter_add_segment(SegWriter *self, SegReader *reader, I32Array *doc_map) {
 void
 SegWriter_merge_segment(SegWriter *self, SegReader *reader,
                         I32Array *doc_map) {
+    SegWriterIVARS *const ivars = SegWriter_IVARS(self);
     Snapshot *snapshot = SegWriter_Get_Snapshot(self);
     CharBuf  *seg_name = Seg_Get_Name(SegReader_Get_Segment(reader));
 
     // Have all the sub-writers merge the segment.
-    for (uint32_t i = 0, max = VA_Get_Size(self->writers); i < max; i++) {
-        DataWriter *writer = (DataWriter*)VA_Fetch(self->writers, i);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->writers); i < max; i++) {
+        DataWriter *writer = (DataWriter*)VA_Fetch(ivars->writers, i);
         DataWriter_Merge_Segment(writer, reader, doc_map);
     }
-    DelWriter_Merge_Segment(self->del_writer, reader, doc_map);
+    DelWriter_Merge_Segment(ivars->del_writer, reader, doc_map);
 
     // Remove seg directory from snapshot.
     Snapshot_Delete_Entry(snapshot, seg_name);
@@ -163,15 +175,16 @@ SegWriter_merge_segment(SegWriter *self, SegReader *reader,
 
 void
 SegWriter_delete_segment(SegWriter *self, SegReader *reader) {
+    SegWriterIVARS *const ivars = SegWriter_IVARS(self);
     Snapshot *snapshot = SegWriter_Get_Snapshot(self);
     CharBuf  *seg_name = Seg_Get_Name(SegReader_Get_Segment(reader));
 
     // Have all the sub-writers delete the segment.
-    for (uint32_t i = 0, max = VA_Get_Size(self->writers); i < max; i++) {
-        DataWriter *writer = (DataWriter*)VA_Fetch(self->writers, i);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->writers); i < max; i++) {
+        DataWriter *writer = (DataWriter*)VA_Fetch(ivars->writers, i);
         DataWriter_Delete_Segment(writer, reader);
     }
-    DelWriter_Delete_Segment(self->del_writer, reader);
+    DelWriter_Delete_Segment(ivars->del_writer, reader);
 
     // Remove seg directory from snapshot.
     Snapshot_Delete_Entry(snapshot, seg_name);
@@ -179,39 +192,42 @@ SegWriter_delete_segment(SegWriter *self, SegReader *reader) {
 
 void
 SegWriter_finish(SegWriter *self) {
-    CharBuf *seg_name = Seg_Get_Name(self->segment);
+    SegWriterIVARS *const ivars = SegWriter_IVARS(self);
+    CharBuf *seg_name = Seg_Get_Name(ivars->segment);
 
     // Finish off children.
-    for (uint32_t i = 0, max = VA_Get_Size(self->writers); i < max; i++) {
-        DataWriter *writer = (DataWriter*)VA_Fetch(self->writers, i);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->writers); i < max; i++) {
+        DataWriter *writer = (DataWriter*)VA_Fetch(ivars->writers, i);
         DataWriter_Finish(writer);
     }
 
     // Write segment metadata and add the segment directory to the snapshot.
     Snapshot *snapshot = SegWriter_Get_Snapshot(self);
     CharBuf *segmeta_filename = CB_newf("%o/segmeta.json", seg_name);
-    Seg_Write_File(self->segment, self->folder);
+    Seg_Write_File(ivars->segment, ivars->folder);
     Snapshot_Add_Entry(snapshot, seg_name);
     DECREF(segmeta_filename);
 
     // Collapse segment files into compound file.
-    Folder_Consolidate(self->folder, seg_name);
+    Folder_Consolidate(ivars->folder, seg_name);
 }
 
 void
 SegWriter_add_data_writer(SegWriter *self, DataWriter *writer) {
-    VA_Push(self->writers, (Obj*)writer);
+    SegWriterIVARS *const ivars = SegWriter_IVARS(self);
+    VA_Push(ivars->writers, (Obj*)writer);
 }
 
 void
 SegWriter_set_del_writer(SegWriter *self, DeletionsWriter *del_writer) {
-    DECREF(self->del_writer);
-    self->del_writer = (DeletionsWriter*)INCREF(del_writer);
+    SegWriterIVARS *const ivars = SegWriter_IVARS(self);
+    DECREF(ivars->del_writer);
+    ivars->del_writer = (DeletionsWriter*)INCREF(del_writer);
 }
 
 DeletionsWriter*
 SegWriter_get_del_writer(SegWriter *self) {
-    return self->del_writer;
+    return SegWriter_IVARS(self)->del_writer;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/Segment.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/Segment.c b/core/Lucy/Index/Segment.c
index 69365ed..ddcebee 100644
--- a/core/Lucy/Index/Segment.c
+++ b/core/Lucy/Index/Segment.c
@@ -33,23 +33,25 @@ Seg_new(int64_t number) {
 
 Segment*
 Seg_init(Segment *self, int64_t number) {
+    SegmentIVARS *const ivars = Seg_IVARS(self);
+
     // Validate.
     if (number < 0) { THROW(ERR, "Segment number %i64 less than 0", number); }
 
     // Init.
-    self->metadata  = Hash_new(0);
-    self->count     = 0;
-    self->by_num    = VA_new(2);
-    self->by_name   = Hash_new(0);
+    ivars->metadata  = Hash_new(0);
+    ivars->count     = 0;
+    ivars->by_num    = VA_new(2);
+    ivars->by_name   = Hash_new(0);
 
     // Start field numbers at 1, not 0.
-    VA_Push(self->by_num, (Obj*)CB_newf(""));
+    VA_Push(ivars->by_num, (Obj*)CB_newf(""));
 
     // Assign.
-    self->number = number;
+    ivars->number = number;
 
     // Derive.
-    self->name = Seg_num_to_name(number);
+    ivars->name = Seg_num_to_name(number);
 
     return self;
 }
@@ -77,16 +79,18 @@ Seg_valid_seg_name(const CharBuf *name) {
 
 void
 Seg_destroy(Segment *self) {
-    DECREF(self->name);
-    DECREF(self->metadata);
-    DECREF(self->by_name);
-    DECREF(self->by_num);
+    SegmentIVARS *const ivars = Seg_IVARS(self);
+    DECREF(ivars->name);
+    DECREF(ivars->metadata);
+    DECREF(ivars->by_name);
+    DECREF(ivars->by_num);
     SUPER_DESTROY(self, SEGMENT);
 }
 
 bool
 Seg_read_file(Segment *self, Folder *folder) {
-    CharBuf *filename = CB_newf("%o/segmeta.json", self->name);
+    SegmentIVARS *const ivars = Seg_IVARS(self);
+    CharBuf *filename = CB_newf("%o/segmeta.json", ivars->name);
     Hash    *metadata = (Hash*)Json_slurp_json(folder, filename);
     Hash    *my_metadata;
 
@@ -96,16 +100,16 @@ Seg_read_file(Segment *self, Folder *folder) {
     CERTIFY(metadata, HASH);
 
     // Grab metadata for the Segment object itself.
-    DECREF(self->metadata);
-    self->metadata = metadata;
+    DECREF(ivars->metadata);
+    ivars->metadata = metadata;
     my_metadata
-        = (Hash*)CERTIFY(Hash_Fetch_Str(self->metadata, "segmeta", 7), HASH);
+        = (Hash*)CERTIFY(Hash_Fetch_Str(ivars->metadata, "segmeta", 7), HASH);
 
     // Assign.
     Obj *count = Hash_Fetch_Str(my_metadata, "count", 5);
     if (!count) { count = Hash_Fetch_Str(my_metadata, "doc_count", 9); }
     if (!count) { THROW(ERR, "Missing 'count'"); }
-    else { self->count = Obj_To_I64(count); }
+    else { ivars->count = Obj_To_I64(count); }
 
     // Get list of field nums.
     VArray *source_by_num = (VArray*)Hash_Fetch_Str(my_metadata,
@@ -116,10 +120,10 @@ Seg_read_file(Segment *self, Folder *folder) {
     }
 
     // Init.
-    DECREF(self->by_num);
-    DECREF(self->by_name);
-    self->by_num  = VA_new(num_fields);
-    self->by_name = Hash_new(num_fields);
+    DECREF(ivars->by_num);
+    DECREF(ivars->by_name);
+    ivars->by_num  = VA_new(num_fields);
+    ivars->by_name = Hash_new(num_fields);
 
     // Copy the list of fields from the source.
     for (uint32_t i = 0; i < num_fields; i++) {
@@ -132,68 +136,72 @@ Seg_read_file(Segment *self, Folder *folder) {
 
 void
 Seg_write_file(Segment *self, Folder *folder) {
+    SegmentIVARS *const ivars = Seg_IVARS(self);
     Hash *my_metadata = Hash_new(16);
 
     // Store metadata specific to this Segment object.
     Hash_Store_Str(my_metadata, "count", 5,
-                   (Obj*)CB_newf("%i64", self->count));
-    Hash_Store_Str(my_metadata, "name", 4, (Obj*)CB_Clone(self->name));
-    Hash_Store_Str(my_metadata, "field_names", 11, INCREF(self->by_num));
+                   (Obj*)CB_newf("%i64", ivars->count));
+    Hash_Store_Str(my_metadata, "name", 4, (Obj*)CB_Clone(ivars->name));
+    Hash_Store_Str(my_metadata, "field_names", 11, INCREF(ivars->by_num));
     Hash_Store_Str(my_metadata, "format", 6, (Obj*)CB_newf("%i32", 1));
-    Hash_Store_Str(self->metadata, "segmeta", 7, (Obj*)my_metadata);
+    Hash_Store_Str(ivars->metadata, "segmeta", 7, (Obj*)my_metadata);
 
-    CharBuf *filename = CB_newf("%o/segmeta.json", self->name);
-    bool result = Json_spew_json((Obj*)self->metadata, folder, filename);
+    CharBuf *filename = CB_newf("%o/segmeta.json", ivars->name);
+    bool result = Json_spew_json((Obj*)ivars->metadata, folder, filename);
     DECREF(filename);
     if (!result) { RETHROW(INCREF(Err_get_error())); }
 }
 
 int32_t
 Seg_add_field(Segment *self, const CharBuf *field) {
-    Integer32 *num = (Integer32*)Hash_Fetch(self->by_name, (Obj*)field);
+    SegmentIVARS *const ivars = Seg_IVARS(self);
+    Integer32 *num = (Integer32*)Hash_Fetch(ivars->by_name, (Obj*)field);
     if (num) {
         return Int32_Get_Value(num);
     }
     else {
-        int32_t field_num = VA_Get_Size(self->by_num);
-        Hash_Store(self->by_name, (Obj*)field, (Obj*)Int32_new(field_num));
-        VA_Push(self->by_num, (Obj*)CB_Clone(field));
+        int32_t field_num = VA_Get_Size(ivars->by_num);
+        Hash_Store(ivars->by_name, (Obj*)field, (Obj*)Int32_new(field_num));
+        VA_Push(ivars->by_num, (Obj*)CB_Clone(field));
         return field_num;
     }
 }
 
 CharBuf*
 Seg_get_name(Segment *self) {
-    return self->name;
+    return Seg_IVARS(self)->name;
 }
 
 int64_t
 Seg_get_number(Segment *self) {
-    return self->number;
+    return Seg_IVARS(self)->number;
 }
 
 void
 Seg_set_count(Segment *self, int64_t count) {
-    self->count = count;
+    Seg_IVARS(self)->count = count;
 }
 
 int64_t
 Seg_get_count(Segment *self) {
-    return self->count;
+    return Seg_IVARS(self)->count;
 }
 
 int64_t
 Seg_increment_count(Segment *self, int64_t increment) {
-    self->count += increment;
-    return self->count;
+    SegmentIVARS *const ivars = Seg_IVARS(self);
+    ivars->count += increment;
+    return ivars->count;
 }
 
 void
 Seg_store_metadata(Segment *self, const CharBuf *key, Obj *value) {
-    if (Hash_Fetch(self->metadata, (Obj*)key)) {
+    SegmentIVARS *const ivars = Seg_IVARS(self);
+    if (Hash_Fetch(ivars->metadata, (Obj*)key)) {
         THROW(ERR, "Metadata key '%o' already registered", key);
     }
-    Hash_Store(self->metadata, (Obj*)key, value);
+    Hash_Store(ivars->metadata, (Obj*)key, value);
 }
 
 void
@@ -205,31 +213,36 @@ Seg_store_metadata_str(Segment *self, const char *key, size_t key_len,
 
 Obj*
 Seg_fetch_metadata(Segment *self, const CharBuf *key) {
-    return Hash_Fetch(self->metadata, (Obj*)key);
+    SegmentIVARS *const ivars = Seg_IVARS(self);
+    return Hash_Fetch(ivars->metadata, (Obj*)key);
 }
 
 Obj*
 Seg_fetch_metadata_str(Segment *self, const char *key, size_t len) {
-    return Hash_Fetch_Str(self->metadata, key, len);
+    SegmentIVARS *const ivars = Seg_IVARS(self);
+    return Hash_Fetch_Str(ivars->metadata, key, len);
 }
 
 Hash*
 Seg_get_metadata(Segment *self) {
-    return self->metadata;
+    return Seg_IVARS(self)->metadata;
 }
 
 int32_t
 Seg_compare_to(Segment *self, Obj *other) {
     Segment *other_seg = (Segment*)CERTIFY(other, SEGMENT);
-    if (self->number <  other_seg->number)      { return -1; }
-    else if (self->number == other_seg->number) { return 0;  }
-    else                                        { return 1;  }
+    SegmentIVARS *const ivars = Seg_IVARS(self);
+    SegmentIVARS *const ovars = Seg_IVARS(other_seg);
+    if (ivars->number < ovars->number)       { return -1; }
+    else if (ivars->number == ovars->number) { return 0;  }
+    else                                     { return 1;  }
 }
 
 CharBuf*
 Seg_field_name(Segment *self, int32_t field_num) {
+    SegmentIVARS *const ivars = Seg_IVARS(self);
     return field_num
-           ? (CharBuf*)VA_Fetch(self->by_num, field_num)
+           ? (CharBuf*)VA_Fetch(ivars->by_num, field_num)
            : NULL;
 }
 
@@ -239,7 +252,8 @@ Seg_field_num(Segment *self, const CharBuf *field) {
         return 0;
     }
     else {
-        Integer32 *num = (Integer32*)Hash_Fetch(self->by_name, (Obj*)field);
+        SegmentIVARS *const ivars = Seg_IVARS(self);
+        Integer32 *num = (Integer32*)Hash_Fetch(ivars->by_name, (Obj*)field);
         return num ? Int32_Get_Value(num) : 0;
     }
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/Similarity.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/Similarity.c b/core/Lucy/Index/Similarity.c
index 2118cdc..a583ef1 100644
--- a/core/Lucy/Index/Similarity.c
+++ b/core/Lucy/Index/Similarity.c
@@ -39,14 +39,16 @@ Sim_new() {
 
 Similarity*
 Sim_init(Similarity *self) {
-    self->norm_decoder = NULL;
+    SimilarityIVARS *const ivars = Sim_IVARS(self);
+    ivars->norm_decoder = NULL;
     return self;
 }
 
 void
 Sim_destroy(Similarity *self) {
-    if (self->norm_decoder) {
-        FREEMEM(self->norm_decoder);
+    SimilarityIVARS *const ivars = Sim_IVARS(self);
+    if (ivars->norm_decoder) {
+        FREEMEM(ivars->norm_decoder);
     }
     SUPER_DESTROY(self, SIMILARITY);
 }
@@ -67,14 +69,15 @@ Sim_make_posting_writer(Similarity *self, Schema *schema, Snapshot *snapshot,
 
 float*
 Sim_get_norm_decoder(Similarity *self) {
-    if (!self->norm_decoder) {
+    SimilarityIVARS *const ivars = Sim_IVARS(self);
+    if (!ivars->norm_decoder) {
         // Cache decoded boost bytes.
-        self->norm_decoder = (float*)MALLOCATE(256 * sizeof(float));
+        ivars->norm_decoder = (float*)MALLOCATE(256 * sizeof(float));
         for (uint32_t i = 0; i < 256; i++) {
-            self->norm_decoder[i] = Sim_Decode_Norm(self, i);
+            ivars->norm_decoder[i] = Sim_Decode_Norm(self, i);
         }
     }
-    return self->norm_decoder;
+    return ivars->norm_decoder;
 }
 
 Obj*

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/SkipStepper.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/SkipStepper.c b/core/Lucy/Index/SkipStepper.c
index f07b9f3..33ce450 100644
--- a/core/Lucy/Index/SkipStepper.c
+++ b/core/Lucy/Index/SkipStepper.c
@@ -27,10 +27,11 @@
 SkipStepper*
 SkipStepper_new() {
     SkipStepper *self = (SkipStepper*)VTable_Make_Obj(SKIPSTEPPER);
+    SkipStepperIVARS *const ivars = SkipStepper_IVARS(self);
 
     // Init.
-    self->doc_id   = 0;
-    self->filepos  = 0;
+    ivars->doc_id   = 0;
+    ivars->filepos  = 0;
 
     return self;
 }
@@ -38,29 +39,33 @@ SkipStepper_new() {
 void
 SkipStepper_set_id_and_filepos(SkipStepper *self, int32_t doc_id,
                                int64_t filepos) {
-    self->doc_id  = doc_id;
-    self->filepos = filepos;
+    SkipStepperIVARS *const ivars = SkipStepper_IVARS(self);
+    ivars->doc_id  = doc_id;
+    ivars->filepos = filepos;
 }
 
 void
 SkipStepper_read_record(SkipStepper *self, InStream *instream) {
-    self->doc_id   += InStream_Read_C32(instream);
-    self->filepos  += InStream_Read_C64(instream);
+    SkipStepperIVARS *const ivars = SkipStepper_IVARS(self);
+    ivars->doc_id   += InStream_Read_C32(instream);
+    ivars->filepos  += InStream_Read_C64(instream);
 }
 
 CharBuf*
 SkipStepper_to_string(SkipStepper *self) {
+    SkipStepperIVARS *const ivars = SkipStepper_IVARS(self);
     char *ptr = (char*)MALLOCATE(60);
     size_t len = sprintf(ptr, "skip doc: %u file pointer: %" PRId64,
-                         self->doc_id, self->filepos);
+                         ivars->doc_id, ivars->filepos);
     return CB_new_steal_from_trusted_str(ptr, len, 60);
 }
 
 void
 SkipStepper_write_record(SkipStepper *self, OutStream *outstream,
                          int32_t last_doc_id, int64_t last_filepos) {
-    const int32_t delta_doc_id = self->doc_id - last_doc_id;
-    const int64_t delta_filepos = self->filepos - last_filepos;
+    SkipStepperIVARS *const ivars = SkipStepper_IVARS(self);
+    const int32_t delta_doc_id = ivars->doc_id - last_doc_id;
+    const int64_t delta_filepos = ivars->filepos - last_filepos;
 
     // Write delta doc id.
     OutStream_Write_C32(outstream, delta_doc_id);


[lucy-commits] [02/34] git commit: refs/heads/master - Migrate Lucy's document classes to IVARS.

Posted by ma...@apache.org.
Migrate Lucy's document classes to IVARS.

Change all Lucy's document classes to access instance vars via an IVARS
struct rather than via `self`.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/9645b2e6
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/9645b2e6
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/9645b2e6

Branch: refs/heads/master
Commit: 9645b2e6c42169cdccdc138e01a5e1690666b205
Parents: 6835217
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Thu Jun 27 20:30:14 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 15:50:06 2013 -0700

----------------------------------------------------------------------
 core/Lucy/Document/Doc.c    |  6 +++---
 core/Lucy/Document/HitDoc.c | 26 ++++++++++++++++----------
 2 files changed, 19 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/9645b2e6/core/Lucy/Document/Doc.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Document/Doc.c b/core/Lucy/Document/Doc.c
index 9c6e6e5..6ad9996 100644
--- a/core/Lucy/Document/Doc.c
+++ b/core/Lucy/Document/Doc.c
@@ -27,17 +27,17 @@ Doc_new(void *fields, int32_t doc_id) {
 
 void
 Doc_set_doc_id(Doc *self, int32_t doc_id) {
-    self->doc_id = doc_id;
+    Doc_IVARS(self)->doc_id = doc_id;
 }
 
 int32_t
 Doc_get_doc_id(Doc *self) {
-    return self->doc_id;
+    return Doc_IVARS(self)->doc_id;
 }
 
 void*
 Doc_get_fields(Doc *self) {
-    return self->fields;
+    return Doc_IVARS(self)->fields;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/9645b2e6/core/Lucy/Document/HitDoc.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Document/HitDoc.c b/core/Lucy/Document/HitDoc.c
index edffe16..45c64e5 100644
--- a/core/Lucy/Document/HitDoc.c
+++ b/core/Lucy/Document/HitDoc.c
@@ -30,26 +30,28 @@ HitDoc_new(void *fields, int32_t doc_id, float score) {
 HitDoc*
 HitDoc_init(HitDoc *self, void *fields, int32_t doc_id, float score) {
     Doc_init((Doc*)self, fields, doc_id);
-    self->score = score;
+    HitDocIVARS *const ivars = HitDoc_IVARS(self);
+    ivars->score = score;
     return self;
 }
 
 void
 HitDoc_set_score(HitDoc *self, float score) {
-    self->score = score;
+    HitDoc_IVARS(self)->score = score;
 }
 
 float
 HitDoc_get_score(HitDoc *self) {
-    return self->score;
+    return HitDoc_IVARS(self)->score;
 }
 
 void
 HitDoc_serialize(HitDoc *self, OutStream *outstream) {
+    HitDocIVARS *const ivars = HitDoc_IVARS(self);
     HitDoc_Serialize_t super_serialize
         = SUPER_METHOD_PTR(HITDOC, Lucy_HitDoc_Serialize);
     super_serialize(self, outstream);
-    OutStream_Write_F32(outstream, self->score);
+    OutStream_Write_F32(outstream, ivars->score);
 }
 
 HitDoc*
@@ -57,16 +59,18 @@ HitDoc_deserialize(HitDoc *self, InStream *instream) {
     HitDoc_Deserialize_t super_deserialize
         = SUPER_METHOD_PTR(HITDOC, Lucy_HitDoc_Deserialize);
     self = super_deserialize(self, instream);
-    self->score = InStream_Read_F32(instream);
+    HitDocIVARS *const ivars = HitDoc_IVARS(self);
+    ivars->score = InStream_Read_F32(instream);
     return self;
 }
 
 Hash*
 HitDoc_dump(HitDoc *self) {
+    HitDocIVARS *const ivars = HitDoc_IVARS(self);
     HitDoc_Dump_t super_dump
         = SUPER_METHOD_PTR(HITDOC, Lucy_HitDoc_Dump);
     Hash *dump = super_dump(self);
-    Hash_Store_Str(dump, "score", 5, (Obj*)CB_newf("%f64", self->score));
+    Hash_Store_Str(dump, "score", 5, (Obj*)CB_newf("%f64", ivars->score));
     return dump;
 }
 
@@ -76,18 +80,20 @@ HitDoc_load(HitDoc *self, Obj *dump) {
     HitDoc_Load_t super_load
         = SUPER_METHOD_PTR(HITDOC, Lucy_HitDoc_Load);
     HitDoc *loaded = super_load(self, dump);
+    HitDocIVARS *const loaded_ivars = HitDoc_IVARS(loaded);
     Obj *score = CERTIFY(Hash_Fetch_Str(source, "score", 5), OBJ);
-    loaded->score = (float)Obj_To_F64(score);
+    loaded_ivars->score = (float)Obj_To_F64(score);
     return loaded;
 }
 
 bool
 HitDoc_equals(HitDoc *self, Obj *other) {
-    HitDoc *twin = (HitDoc*)other;
-    if (twin == self)                     { return true;  }
+    if ((HitDoc*)other == self)           { return true;  }
     if (!Obj_Is_A(other, HITDOC))         { return false; }
     if (!Doc_equals((Doc*)self, other))   { return false; }
-    if (self->score != twin->score)       { return false; }
+    HitDocIVARS *const ivars = HitDoc_IVARS(self);
+    HitDocIVARS *const ovars = HitDoc_IVARS((HitDoc*)other);
+    if (ivars->score != ovars->score)     { return false; }
     return true;
 }
 


[lucy-commits] [31/34] git commit: refs/heads/master - Use TermInfo accessors in LexIndex.

Posted by ma...@apache.org.
Use TermInfo accessors in LexIndex.

Avoid direct struct access for TermInfo instance vars in LexIndex.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/0fc7b134
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/0fc7b134
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/0fc7b134

Branch: refs/heads/master
Commit: 0fc7b134b58839fd997db7cc43a61720b873cc39
Parents: 6346d10
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Sun Jun 30 10:29:01 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 16:08:44 2013 -0700

----------------------------------------------------------------------
 core/Lucy/Index/LexIndex.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/0fc7b134/core/Lucy/Index/LexIndex.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/LexIndex.c b/core/Lucy/Index/LexIndex.c
index 3d3200e..923e925 100644
--- a/core/Lucy/Index/LexIndex.c
+++ b/core/Lucy/Index/LexIndex.c
@@ -15,7 +15,6 @@
  */
 
 #define C_LUCY_LEXINDEX
-#define C_LUCY_TERMINFO
 #include "Lucy/Util/ToolSet.h"
 
 #include "Lucy/Index/LexIndex.h"
@@ -125,16 +124,18 @@ static void
 S_read_entry(LexIndex *self) {
     LexIndexIVARS *const ivars = LexIndex_IVARS(self);
     InStream *ix_in  = ivars->ix_in;
-    TermInfoIVARS *const tinfo_ivars = TInfo_IVARS(ivars->tinfo);
+    TermInfo *const tinfo = ivars->tinfo;
     int64_t offset = (int64_t)NumUtil_decode_bigend_u64(ivars->offsets + ivars->tick);
     InStream_Seek(ix_in, offset);
     TermStepper_Read_Key_Frame(ivars->term_stepper, ix_in);
-    tinfo_ivars->doc_freq     = InStream_Read_C32(ix_in);
-    tinfo_ivars->post_filepos = InStream_Read_C64(ix_in);
-    tinfo_ivars->skip_filepos = tinfo_ivars->doc_freq >= ivars->skip_interval
-                          ? InStream_Read_C64(ix_in)
-                          : 0;
-    tinfo_ivars->lex_filepos  = InStream_Read_C64(ix_in);
+    int32_t doc_freq = InStream_Read_C32(ix_in);
+    TInfo_Set_Doc_Freq(tinfo, doc_freq);
+    TInfo_Set_Post_FilePos(tinfo, InStream_Read_C64(ix_in));
+    int64_t skip_filepos = doc_freq >= ivars->skip_interval
+                           ? InStream_Read_C64(ix_in)
+                           : 0;
+    TInfo_Set_Skip_FilePos(tinfo, skip_filepos);
+    TInfo_Set_Lex_FilePos(tinfo, InStream_Read_C64(ix_in));
 }
 
 void


[lucy-commits] [18/34] git commit: refs/heads/master - Migrate C host code to IVARS.

Posted by ma...@apache.org.
Migrate C host code to IVARS.

Migrate host-specific code for C to use IVARS rather than access struct
members through `self`.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/25f4f658
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/25f4f658
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/25f4f658

Branch: refs/heads/master
Commit: 25f4f6586011eaa3e6de258723a83f0222d3de2c
Parents: 7ba2ba6
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Mon Jul 1 08:10:57 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 16:08:43 2013 -0700

----------------------------------------------------------------------
 c/src/Lucy/Analysis/RegexTokenizer.c | 17 +++++++------
 c/src/Lucy/Document/Doc.c            | 40 +++++++++++++++++--------------
 c/src/Lucy/Index/DocReader.c         |  7 +++---
 c/src/Lucy/Index/Inverter.c          | 32 +++++++++++++------------
 4 files changed, 53 insertions(+), 43 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/25f4f658/c/src/Lucy/Analysis/RegexTokenizer.c
----------------------------------------------------------------------
diff --git a/c/src/Lucy/Analysis/RegexTokenizer.c b/c/src/Lucy/Analysis/RegexTokenizer.c
index e2e5277..4b2bfe6 100644
--- a/c/src/Lucy/Analysis/RegexTokenizer.c
+++ b/c/src/Lucy/Analysis/RegexTokenizer.c
@@ -46,15 +46,16 @@ RegexTokenizer_is_available(void) {
 RegexTokenizer*
 RegexTokenizer_init(RegexTokenizer *self, const CharBuf *pattern) {
     Analyzer_init((Analyzer*)self);
+    RegexTokenizerIVARS *const ivars = RegexTokenizer_IVARS(self);
 
     const char *pattern_ptr;
     if (pattern) {
-        self->pattern = CB_Clone(pattern);
-        pattern_ptr = (char*)CB_Get_Ptr8(self->pattern);
+        ivars->pattern = CB_Clone(pattern);
+        pattern_ptr = (char*)CB_Get_Ptr8(ivars->pattern);
     }
     else {
         pattern_ptr = "\\w+(?:['\\x{2019}]\\w+)*";
-        self->pattern
+        ivars->pattern
             = CB_new_from_trusted_utf8(pattern_ptr, strlen(pattern_ptr));
     }
 
@@ -76,7 +77,7 @@ RegexTokenizer_init(RegexTokenizer *self, const CharBuf *pattern) {
 
     // TODO: Check whether pcre_study improves performance
 
-    self->token_re = re;
+    ivars->token_re = re;
 
     return self;
 }
@@ -90,8 +91,9 @@ RegexTokenizer_set_token_re(RegexTokenizer *self, void *token_re) {
 
 void
 RegexTokenizer_destroy(RegexTokenizer *self) {
-    DECREF(self->pattern);
-    pcre *re = (pcre*)self->token_re;
+    RegexTokenizerIVARS *const ivars = RegexTokenizer_IVARS(self);
+    DECREF(ivars->pattern);
+    pcre *re = (pcre*)ivars->token_re;
     if (re) {
         pcre_free(re);
     }
@@ -102,7 +104,8 @@ void
 RegexTokenizer_tokenize_str(RegexTokenizer *self,
                                  const char *string, size_t string_len,
                                  Inversion *inversion) {
-    pcre      *re          = (pcre*)self->token_re;
+    RegexTokenizerIVARS *const ivars = RegexTokenizer_IVARS(self);
+    pcre      *re          = (pcre*)ivars->token_re;
     int        byte_offset = 0;
     uint32_t   cp_offset   = 0; // Code points
     int        options     = PCRE_NO_UTF8_CHECK;

http://git-wip-us.apache.org/repos/asf/lucy/blob/25f4f658/c/src/Lucy/Document/Doc.c
----------------------------------------------------------------------
diff --git a/c/src/Lucy/Document/Doc.c b/c/src/Lucy/Document/Doc.c
index f0fb2d4..74cfef8 100644
--- a/c/src/Lucy/Document/Doc.c
+++ b/c/src/Lucy/Document/Doc.c
@@ -30,6 +30,7 @@
 
 Doc*
 Doc_init(Doc *self, void *fields, int32_t doc_id) {
+    DocIVARS *const ivars = Doc_IVARS(self);
     Hash *hash;
 
     if (fields) {
@@ -39,49 +40,52 @@ Doc_init(Doc *self, void *fields, int32_t doc_id) {
     else {
         hash = Hash_new(0);
     }
-    self->fields = hash;
-    self->doc_id = doc_id;
+    ivars->fields = hash;
+    ivars->doc_id = doc_id;
 
     return self;
 }
 
 void
 Doc_set_fields(Doc *self, void *fields) {
-    DECREF(self->fields);
-    self->fields = CERTIFY(fields, HASH);
+    DocIVARS *const ivars = Doc_IVARS(self);
+    DECREF(ivars->fields);
+    ivars->fields = CERTIFY(fields, HASH);
 }
 
 uint32_t
 Doc_get_size(Doc *self) {
-    Hash *hash = (Hash *)self->fields;
+    Hash *hash = (Hash*)Doc_IVARS(self)->fields;
     return Hash_Get_Size(hash);
 }
 
 void
 Doc_store(Doc *self, const CharBuf *field, Obj *value) {
-    Hash *hash = (Hash *)self->fields;
+    Hash *hash = (Hash*)Doc_IVARS(self)->fields;
     Hash_Store(hash, (Obj *)field, value);
     INCREF(value);
 }
 
 void
 Doc_serialize(Doc *self, OutStream *outstream) {
-    Hash *hash = (Hash *)self->fields;
+    DocIVARS *const ivars = Doc_IVARS(self);
+    Hash *hash = (Hash*)ivars->fields;
     Freezer_serialize_hash(hash, outstream);
-    OutStream_Write_C32(outstream, self->doc_id);
+    OutStream_Write_C32(outstream, ivars->doc_id);
 }
 
 Doc*
 Doc_deserialize(Doc *self, InStream *instream) {
-     self->fields = Freezer_read_hash(instream);
-     self->doc_id = InStream_Read_C32(instream);
-     return self;
+    DocIVARS *const ivars = Doc_IVARS(self);
+    ivars->fields = Freezer_read_hash(instream);
+    ivars->doc_id = InStream_Read_C32(instream);
+    return self;
 }
 
 Obj*
 Doc_extract(Doc *self, CharBuf *field,
                  ViewCharBuf *target) {
-    Hash *hash = (Hash *)self->fields;
+    Hash *hash = (Hash*)Doc_IVARS(self)->fields;
     Obj  *obj  = Hash_Fetch(hash, (Obj *)field);
 
     if (target && obj && Obj_Is_A(obj, CHARBUF)) {
@@ -115,17 +119,17 @@ Doc_load(Doc *self, Obj *dump) {
 
 bool
 Doc_equals(Doc *self, Obj *other) {
-    Doc *twin = (Doc*)other;
-
-    if (twin == self)                    { return true;  }
+    if ((Doc*)other == self)   { return true;  }
     if (!Obj_Is_A(other, DOC)) { return false; }
-
-    return Hash_Equals((Hash*)self->fields, (Obj*)twin->fields);
+    DocIVARS *const ivars = Doc_IVARS(self);
+    DocIVARS *const ovars = Doc_IVARS((Doc*)other);
+    return Hash_Equals((Hash*)ivars->fields, (Obj*)ovars->fields);
 }
 
 void
 Doc_destroy(Doc *self) {
-    DECREF(self->fields);
+    DocIVARS *const ivars = Doc_IVARS(self);
+    DECREF(ivars->fields);
     SUPER_DESTROY(self, DOC);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/25f4f658/c/src/Lucy/Index/DocReader.c
----------------------------------------------------------------------
diff --git a/c/src/Lucy/Index/DocReader.c b/c/src/Lucy/Index/DocReader.c
index 79fcd4f..ee56bd1 100644
--- a/c/src/Lucy/Index/DocReader.c
+++ b/c/src/Lucy/Index/DocReader.c
@@ -34,9 +34,10 @@
 
 HitDoc*
 DefDocReader_fetch_doc(DefaultDocReader *self, int32_t doc_id) {
-    Schema   *const schema = self->schema;
-    InStream *const dat_in = self->dat_in;
-    InStream *const ix_in  = self->ix_in;
+    DefaultDocReaderIVARS *const ivars = DefDocReader_IVARS(self);
+    Schema   *const schema = ivars->schema;
+    InStream *const dat_in = ivars->dat_in;
+    InStream *const ix_in  = ivars->ix_in;
     Hash     *const fields = Hash_new(1);
     int64_t   start;
     uint32_t  num_fields;

http://git-wip-us.apache.org/repos/asf/lucy/blob/25f4f658/c/src/Lucy/Index/Inverter.c
----------------------------------------------------------------------
diff --git a/c/src/Lucy/Index/Inverter.c b/c/src/Lucy/Index/Inverter.c
index 0700075..22c78a1 100644
--- a/c/src/Lucy/Index/Inverter.c
+++ b/c/src/Lucy/Index/Inverter.c
@@ -33,15 +33,15 @@
 #include "Lucy/Plan/Schema.h"
 
 static InverterEntry*
-S_fetch_entry(Inverter *self, CharBuf *field) {
-    Schema *const schema = self->schema;
-    int32_t field_num = Seg_Field_Num(self->segment, field);
+S_fetch_entry(InverterIVARS *ivars, CharBuf *field) {
+    Schema *const schema = ivars->schema;
+    int32_t field_num = Seg_Field_Num(ivars->segment, field);
     if (!field_num) {
         // This field seems not to be in the segment yet.  Try to find it in
         // the Schema.
         if (Schema_Fetch_Type(schema, field)) {
             // The field is in the Schema.  Get a field num from the Segment.
-            field_num = Seg_Add_Field(self->segment, field);
+            field_num = Seg_Add_Field(ivars->segment, field);
         }
         else {
             // We've truly failed to find the field.  The user must
@@ -51,16 +51,17 @@ S_fetch_entry(Inverter *self, CharBuf *field) {
     }
 
     InverterEntry *entry
-        = (InverterEntry*)VA_Fetch(self->entry_pool, field_num);
+        = (InverterEntry*)VA_Fetch(ivars->entry_pool, field_num);
     if (!entry) {
         entry = InvEntry_new(schema, (CharBuf*)field, field_num);
-        VA_Store(self->entry_pool, field_num, (Obj*)entry);
+        VA_Store(ivars->entry_pool, field_num, (Obj*)entry);
     }
     return entry;
 }
 
 void
 Inverter_invert_doc(Inverter *self, Doc *doc) {
+    InverterIVARS *const ivars = Inverter_IVARS(self);
     Hash *const fields = (Hash*)Doc_Get_Fields(doc);
     uint32_t   num_keys     = Hash_Iterate(fields);
 
@@ -72,8 +73,9 @@ Inverter_invert_doc(Inverter *self, Doc *doc) {
         Obj *key, *obj;
         Hash_Next(fields, &key, &obj);
         CharBuf *field = (CharBuf*)CERTIFY(key, CHARBUF);
-        InverterEntry *inv_entry = S_fetch_entry(self, field);
-        FieldType *type = inv_entry->type;
+        InverterEntry *inventry = S_fetch_entry(ivars, field);
+        InverterEntryIVARS *inventry_ivars = InvEntry_IVARS(inventry);
+        FieldType *type = inventry_ivars->type;
 
         // Get the field value.
         switch (FType_Primitive_ID(type) & FType_PRIMITIVE_ID_MASK) {
@@ -81,7 +83,7 @@ Inverter_invert_doc(Inverter *self, Doc *doc) {
                     CharBuf *char_buf
                         = (CharBuf*)CERTIFY(obj, CHARBUF);
                     ViewCharBuf *value
-                        = (ViewCharBuf*)inv_entry->value;
+                        = (ViewCharBuf*)inventry_ivars->value;
                     ViewCB_Assign(value, char_buf);
                     break;
                 }
@@ -89,31 +91,31 @@ Inverter_invert_doc(Inverter *self, Doc *doc) {
                     ByteBuf *byte_buf
                         = (ByteBuf*)CERTIFY(obj, BYTEBUF);
                     ViewByteBuf *value
-                        = (ViewByteBuf*)inv_entry->value;
+                        = (ViewByteBuf*)inventry_ivars->value;
                     ViewBB_Assign(value, byte_buf);
                     break;
                 }
             case FType_INT32: {
                     int32_t int_val = (int32_t)Obj_To_I64(obj);
-                    Integer32* value = (Integer32*)inv_entry->value;
+                    Integer32* value = (Integer32*)inventry_ivars->value;
                     Int32_Set_Value(value, int_val);
                     break;
                 }
             case FType_INT64: {
                     int64_t int_val = Obj_To_I64(obj);
-                    Integer64* value = (Integer64*)inv_entry->value;
+                    Integer64* value = (Integer64*)inventry_ivars->value;
                     Int64_Set_Value(value, int_val);
                     break;
                 }
             case FType_FLOAT32: {
                     float float_val = (float)Obj_To_F64(obj);
-                    Float32* value = (Float32*)inv_entry->value;
+                    Float32* value = (Float32*)inventry_ivars->value;
                     Float32_Set_Value(value, float_val);
                     break;
                 }
             case FType_FLOAT64: {
                     double float_val = Obj_To_F64(obj);
-                    Float64* value = (Float64*)inv_entry->value;
+                    Float64* value = (Float64*)inventry_ivars->value;
                     Float64_Set_Value(value, float_val);
                     break;
                 }
@@ -121,7 +123,7 @@ Inverter_invert_doc(Inverter *self, Doc *doc) {
                 THROW(ERR, "Unrecognized type: %o", type);
         }
 
-        Inverter_Add_Field(self, inv_entry);
+        Inverter_Add_Field(self, inventry);
     }
 }
 


[lucy-commits] [04/34] Update Lucy search classes with IVARS.

Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/PhraseQuery.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/PhraseQuery.c b/core/Lucy/Search/PhraseQuery.c
index e388773..2c62e2f 100644
--- a/core/Lucy/Search/PhraseQuery.c
+++ b/core/Lucy/Search/PhraseQuery.c
@@ -56,27 +56,30 @@ PhraseQuery_init(PhraseQuery *self, const CharBuf *field, VArray *terms) {
 
 void
 PhraseQuery_destroy(PhraseQuery *self) {
-    DECREF(self->terms);
-    DECREF(self->field);
+    PhraseQueryIVARS *const ivars = PhraseQuery_IVARS(self);
+    DECREF(ivars->terms);
+    DECREF(ivars->field);
     SUPER_DESTROY(self, PHRASEQUERY);
 }
 
 static PhraseQuery*
 S_do_init(PhraseQuery *self, CharBuf *field, VArray *terms, float boost) {
     Query_init((Query*)self, boost);
+    PhraseQueryIVARS *const ivars = PhraseQuery_IVARS(self);
     for (uint32_t i = 0, max = VA_Get_Size(terms); i < max; i++) {
         CERTIFY(VA_Fetch(terms, i), OBJ);
     }
-    self->field = field;
-    self->terms = terms;
+    ivars->field = field;
+    ivars->terms = terms;
     return self;
 }
 
 void
 PhraseQuery_serialize(PhraseQuery *self, OutStream *outstream) {
-    OutStream_Write_F32(outstream, self->boost);
-    Freezer_serialize_charbuf(self->field, outstream);
-    Freezer_serialize_varray(self->terms, outstream);
+    PhraseQueryIVARS *const ivars = PhraseQuery_IVARS(self);
+    OutStream_Write_F32(outstream, ivars->boost);
+    Freezer_serialize_charbuf(ivars->field, outstream);
+    Freezer_serialize_varray(ivars->terms, outstream);
 }
 
 PhraseQuery*
@@ -89,26 +92,28 @@ PhraseQuery_deserialize(PhraseQuery *self, InStream *instream) {
 
 bool
 PhraseQuery_equals(PhraseQuery *self, Obj *other) {
-    PhraseQuery *twin = (PhraseQuery*)other;
-    if (twin == self)                  { return true; }
+    if ((PhraseQuery*)other == self)   { return true; }
     if (!Obj_Is_A(other, PHRASEQUERY)) { return false; }
-    if (self->boost != twin->boost)    { return false; }
-    if (self->field && !twin->field)   { return false; }
-    if (!self->field && twin->field)   { return false; }
-    if (self->field && !CB_Equals(self->field, (Obj*)twin->field)) {
+    PhraseQueryIVARS *const ivars = PhraseQuery_IVARS(self);
+    PhraseQueryIVARS *const ovars = PhraseQuery_IVARS((PhraseQuery*)other);
+    if (ivars->boost != ovars->boost)  { return false; }
+    if (ivars->field && !ovars->field) { return false; }
+    if (!ivars->field && ovars->field) { return false; }
+    if (ivars->field && !CB_Equals(ivars->field, (Obj*)ovars->field)) {
         return false;
     }
-    if (!VA_Equals(twin->terms, (Obj*)self->terms)) { return false; }
+    if (!VA_Equals(ovars->terms, (Obj*)ivars->terms)) { return false; }
     return true;
 }
 
 CharBuf*
 PhraseQuery_to_string(PhraseQuery *self) {
-    uint32_t  num_terms = VA_Get_Size(self->terms);
-    CharBuf  *retval    = CB_Clone(self->field);
+    PhraseQueryIVARS *const ivars = PhraseQuery_IVARS(self);
+    uint32_t  num_terms = VA_Get_Size(ivars->terms);
+    CharBuf  *retval    = CB_Clone(ivars->field);
     CB_Cat_Trusted_Str(retval, ":\"", 2);
     for (uint32_t i = 0; i < num_terms; i++) {
-        Obj     *term        = VA_Fetch(self->terms, i);
+        Obj     *term        = VA_Fetch(ivars->terms, i);
         CharBuf *term_string = Obj_To_String(term);
         CB_Cat(retval, term_string);
         DECREF(term_string);
@@ -123,12 +128,13 @@ PhraseQuery_to_string(PhraseQuery *self) {
 Compiler*
 PhraseQuery_make_compiler(PhraseQuery *self, Searcher *searcher,
                           float boost, bool subordinate) {
-    if (VA_Get_Size(self->terms) == 1) {
+    PhraseQueryIVARS *const ivars = PhraseQuery_IVARS(self);
+    if (VA_Get_Size(ivars->terms) == 1) {
         // Optimize for one-term "phrases".
-        Obj *term = VA_Fetch(self->terms, 0);
-        TermQuery *term_query = TermQuery_new(self->field, term);
+        Obj *term = VA_Fetch(ivars->terms, 0);
+        TermQuery *term_query = TermQuery_new(ivars->field, term);
         TermCompiler *term_compiler;
-        TermQuery_Set_Boost(term_query, self->boost);
+        TermQuery_Set_Boost(term_query, ivars->boost);
         term_compiler
             = (TermCompiler*)TermQuery_Make_Compiler(term_query, searcher,
                                                      boost, subordinate);
@@ -147,12 +153,12 @@ PhraseQuery_make_compiler(PhraseQuery *self, Searcher *searcher,
 
 CharBuf*
 PhraseQuery_get_field(PhraseQuery *self) {
-    return self->field;
+    return PhraseQuery_IVARS(self)->field;
 }
 
 VArray*
 PhraseQuery_get_terms(PhraseQuery *self) {
-    return self->terms;
+    return PhraseQuery_IVARS(self)->terms;
 }
 
 /*********************************************************************/
@@ -166,9 +172,11 @@ PhraseCompiler_new(PhraseQuery *parent, Searcher *searcher, float boost) {
 PhraseCompiler*
 PhraseCompiler_init(PhraseCompiler *self, PhraseQuery *parent,
                     Searcher *searcher, float boost) {
+    PhraseCompilerIVARS *const ivars = PhraseCompiler_IVARS(self);
+    PhraseQueryIVARS *const parent_ivars = PhraseQuery_IVARS(parent);
     Schema     *schema = Searcher_Get_Schema(searcher);
-    Similarity *sim    = Schema_Fetch_Sim(schema, parent->field);
-    VArray     *terms  = parent->terms;
+    Similarity *sim    = Schema_Fetch_Sim(schema, parent_ivars->field);
+    VArray     *terms  = parent_ivars->terms;
 
     // Try harder to find a Similarity if necessary.
     if (!sim) { sim = Schema_Get_Similarity(schema); }
@@ -177,27 +185,28 @@ PhraseCompiler_init(PhraseCompiler *self, PhraseQuery *parent,
     Compiler_init((Compiler*)self, (Query*)parent, searcher, sim, boost);
 
     // Store IDF for the phrase.
-    self->idf = 0;
+    ivars->idf = 0;
     for (uint32_t i = 0, max = VA_Get_Size(terms); i < max; i++) {
         Obj     *term     = VA_Fetch(terms, i);
         int32_t  doc_max  = Searcher_Doc_Max(searcher);
-        int32_t  doc_freq = Searcher_Doc_Freq(searcher, parent->field, term);
-        self->idf += Sim_IDF(sim, doc_freq, doc_max);
+        int32_t  doc_freq = Searcher_Doc_Freq(searcher, parent_ivars->field, term);
+        ivars->idf += Sim_IDF(sim, doc_freq, doc_max);
     }
 
     // Calculate raw weight.
-    self->raw_weight = self->idf * self->boost;
+    ivars->raw_weight = ivars->idf * ivars->boost;
 
     return self;
 }
 
 void
 PhraseCompiler_serialize(PhraseCompiler *self, OutStream *outstream) {
+    PhraseCompilerIVARS *const ivars = PhraseCompiler_IVARS(self);
     Compiler_serialize((Compiler*)self, outstream);
-    OutStream_Write_F32(outstream, self->idf);
-    OutStream_Write_F32(outstream, self->raw_weight);
-    OutStream_Write_F32(outstream, self->query_norm_factor);
-    OutStream_Write_F32(outstream, self->normalized_weight);
+    OutStream_Write_F32(outstream, ivars->idf);
+    OutStream_Write_F32(outstream, ivars->raw_weight);
+    OutStream_Write_F32(outstream, ivars->query_norm_factor);
+    OutStream_Write_F32(outstream, ivars->normalized_weight);
 }
 
 PhraseCompiler*
@@ -205,47 +214,54 @@ PhraseCompiler_deserialize(PhraseCompiler *self, InStream *instream) {
     PhraseCompiler_Deserialize_t super_deserialize
         = SUPER_METHOD_PTR(PHRASECOMPILER, Lucy_PhraseCompiler_Deserialize);
     self = super_deserialize(self, instream);
-    self->idf               = InStream_Read_F32(instream);
-    self->raw_weight        = InStream_Read_F32(instream);
-    self->query_norm_factor = InStream_Read_F32(instream);
-    self->normalized_weight = InStream_Read_F32(instream);
+    PhraseCompilerIVARS *const ivars = PhraseCompiler_IVARS(self);
+    ivars->idf               = InStream_Read_F32(instream);
+    ivars->raw_weight        = InStream_Read_F32(instream);
+    ivars->query_norm_factor = InStream_Read_F32(instream);
+    ivars->normalized_weight = InStream_Read_F32(instream);
     return self;
 }
 
 bool
 PhraseCompiler_equals(PhraseCompiler *self, Obj *other) {
-    PhraseCompiler *twin = (PhraseCompiler*)other;
-    if (!Obj_Is_A(other, PHRASECOMPILER))                   { return false; }
-    if (!Compiler_equals((Compiler*)self, other))           { return false; }
-    if (self->idf != twin->idf)                             { return false; }
-    if (self->raw_weight != twin->raw_weight)               { return false; }
-    if (self->query_norm_factor != twin->query_norm_factor) { return false; }
-    if (self->normalized_weight != twin->normalized_weight) { return false; }
+    if (!Obj_Is_A(other, PHRASECOMPILER))                     { return false; }
+    if (!Compiler_equals((Compiler*)self, other))             { return false; }
+    PhraseCompilerIVARS *const ivars = PhraseCompiler_IVARS(self);
+    PhraseCompilerIVARS *const ovars
+        = PhraseCompiler_IVARS((PhraseCompiler*)other);
+    if (ivars->idf != ovars->idf)                             { return false; }
+    if (ivars->raw_weight != ovars->raw_weight)               { return false; }
+    if (ivars->query_norm_factor != ovars->query_norm_factor) { return false; }
+    if (ivars->normalized_weight != ovars->normalized_weight) { return false; }
     return true;
 }
 
 float
 PhraseCompiler_get_weight(PhraseCompiler *self) {
-    return self->normalized_weight;
+    return PhraseCompiler_IVARS(self)->normalized_weight;
 }
 
 float
 PhraseCompiler_sum_of_squared_weights(PhraseCompiler *self) {
-    return self->raw_weight * self->raw_weight;
+    PhraseCompilerIVARS *const ivars = PhraseCompiler_IVARS(self);
+    return ivars->raw_weight * ivars->raw_weight;
 }
 
 void
 PhraseCompiler_apply_norm_factor(PhraseCompiler *self, float factor) {
-    self->query_norm_factor = factor;
-    self->normalized_weight = self->raw_weight * self->idf * factor;
+    PhraseCompilerIVARS *const ivars = PhraseCompiler_IVARS(self);
+    ivars->query_norm_factor = factor;
+    ivars->normalized_weight = ivars->raw_weight * ivars->idf * factor;
 }
 
 Matcher*
 PhraseCompiler_make_matcher(PhraseCompiler *self, SegReader *reader,
                             bool need_score) {
     UNUSED_VAR(need_score);
-    PhraseQuery *const parent    = (PhraseQuery*)self->parent;
-    VArray *const      terms     = parent->terms;
+    PhraseCompilerIVARS *const ivars = PhraseCompiler_IVARS(self);
+    PhraseQueryIVARS *const parent_ivars
+        = PhraseQuery_IVARS((PhraseQuery*)ivars->parent);
+    VArray *const      terms     = parent_ivars->terms;
     uint32_t           num_terms = VA_Get_Size(terms);
 
     // Bail if there are no terms.
@@ -271,7 +287,7 @@ PhraseCompiler_make_matcher(PhraseCompiler *self, SegReader *reader,
     for (uint32_t i = 0; i < num_terms; i++) {
         Obj *term = VA_Fetch(terms, i);
         PostingList *plist
-            = PListReader_Posting_List(plist_reader, parent->field, term);
+            = PListReader_Posting_List(plist_reader, parent_ivars->field, term);
 
         // Bail if any one of the terms isn't in the index.
         if (!plist || !PList_Get_Doc_Freq(plist)) {
@@ -291,15 +307,17 @@ PhraseCompiler_make_matcher(PhraseCompiler *self, SegReader *reader,
 VArray*
 PhraseCompiler_highlight_spans(PhraseCompiler *self, Searcher *searcher,
                                DocVector *doc_vec, const CharBuf *field) {
-    PhraseQuery *const parent    = (PhraseQuery*)self->parent;
-    VArray *const      terms     = parent->terms;
+    PhraseCompilerIVARS *const ivars = PhraseCompiler_IVARS(self);
+    PhraseQueryIVARS *const parent_ivars
+        = PhraseQuery_IVARS((PhraseQuery*)ivars->parent);
+    VArray *const      terms     = parent_ivars->terms;
     VArray *const      spans     = VA_new(0);
     const uint32_t     num_terms = VA_Get_Size(terms);
     UNUSED_VAR(searcher);
 
     // Bail if no terms or field doesn't match.
     if (!num_terms) { return spans; }
-    if (!CB_Equals(field, (Obj*)parent->field)) { return spans; }
+    if (!CB_Equals(field, (Obj*)parent_ivars->field)) { return spans; }
 
     VArray *term_vectors    = VA_new(num_terms);
     BitVector *posit_vec       = BitVec_new(0);

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/PolyMatcher.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/PolyMatcher.c b/core/Lucy/Search/PolyMatcher.c
index 4e1b38c..8c91be0 100644
--- a/core/Lucy/Search/PolyMatcher.c
+++ b/core/Lucy/Search/PolyMatcher.c
@@ -29,13 +29,14 @@ PolyMatcher_new(VArray *children, Similarity *sim) {
 PolyMatcher*
 PolyMatcher_init(PolyMatcher *self, VArray *children, Similarity *similarity) {
     Matcher_init((Matcher*)self);
-    self->num_kids = VA_Get_Size(children);
-    self->sim      = (Similarity*)INCREF(similarity);
-    self->children = (VArray*)INCREF(children);
-    self->coord_factors = (float*)MALLOCATE((self->num_kids + 1) * sizeof(float));
-    for (uint32_t i = 0; i <= self->num_kids; i++) {
-        self->coord_factors[i] = similarity
-                                 ? Sim_Coord(similarity, i, self->num_kids)
+    PolyMatcherIVARS *const ivars = PolyMatcher_IVARS(self);
+    ivars->num_kids = VA_Get_Size(children);
+    ivars->sim      = (Similarity*)INCREF(similarity);
+    ivars->children = (VArray*)INCREF(children);
+    ivars->coord_factors = (float*)MALLOCATE((ivars->num_kids + 1) * sizeof(float));
+    for (uint32_t i = 0; i <= ivars->num_kids; i++) {
+        ivars->coord_factors[i] = similarity
+                                 ? Sim_Coord(similarity, i, ivars->num_kids)
                                  : 1.0f;
     }
     return self;
@@ -43,9 +44,10 @@ PolyMatcher_init(PolyMatcher *self, VArray *children, Similarity *similarity) {
 
 void
 PolyMatcher_destroy(PolyMatcher *self) {
-    DECREF(self->children);
-    DECREF(self->sim);
-    FREEMEM(self->coord_factors);
+    PolyMatcherIVARS *const ivars = PolyMatcher_IVARS(self);
+    DECREF(ivars->children);
+    DECREF(ivars->sim);
+    FREEMEM(ivars->coord_factors);
     SUPER_DESTROY(self, POLYMATCHER);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/PolyQuery.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/PolyQuery.c b/core/Lucy/Search/PolyQuery.c
index e116aaf..da87dc1 100644
--- a/core/Lucy/Search/PolyQuery.c
+++ b/core/Lucy/Search/PolyQuery.c
@@ -32,7 +32,8 @@ PolyQuery*
 PolyQuery_init(PolyQuery *self, VArray *children) {
     const uint32_t num_kids = children ? VA_Get_Size(children) : 0;
     Query_init((Query*)self, 1.0f);
-    self->children = VA_new(num_kids);
+    PolyQueryIVARS *const ivars = PolyQuery_IVARS(self);
+    ivars->children = VA_new(num_kids);
     for (uint32_t i = 0; i < num_kids; i++) {
         PolyQuery_Add_Child(self, (Query*)VA_Fetch(children, i));
     }
@@ -41,34 +42,38 @@ PolyQuery_init(PolyQuery *self, VArray *children) {
 
 void
 PolyQuery_destroy(PolyQuery *self) {
-    DECREF(self->children);
+    PolyQueryIVARS *const ivars = PolyQuery_IVARS(self);
+    DECREF(ivars->children);
     SUPER_DESTROY(self, POLYQUERY);
 }
 
 void
 PolyQuery_add_child(PolyQuery *self, Query *query) {
     CERTIFY(query, QUERY);
-    VA_Push(self->children, INCREF(query));
+    PolyQueryIVARS *const ivars = PolyQuery_IVARS(self);
+    VA_Push(ivars->children, INCREF(query));
 }
 
 void
 PolyQuery_set_children(PolyQuery *self, VArray *children) {
-    DECREF(self->children);
-    self->children = (VArray*)INCREF(children);
+    PolyQueryIVARS *const ivars = PolyQuery_IVARS(self);
+    DECREF(ivars->children);
+    ivars->children = (VArray*)INCREF(children);
 }
 
 VArray*
 PolyQuery_get_children(PolyQuery *self) {
-    return self->children;
+    return PolyQuery_IVARS(self)->children;
 }
 
 void
 PolyQuery_serialize(PolyQuery *self, OutStream *outstream) {
-    const uint32_t num_kids = VA_Get_Size(self->children);
-    OutStream_Write_F32(outstream, self->boost);
+    PolyQueryIVARS *const ivars = PolyQuery_IVARS(self);
+    const uint32_t num_kids = VA_Get_Size(ivars->children);
+    OutStream_Write_F32(outstream, ivars->boost);
     OutStream_Write_U32(outstream, num_kids);
     for (uint32_t i = 0; i < num_kids; i++) {
-        Query *child = (Query*)VA_Fetch(self->children, i);
+        Query *child = (Query*)VA_Fetch(ivars->children, i);
         FREEZE(child, outstream);
     }
 }
@@ -78,21 +83,23 @@ PolyQuery_deserialize(PolyQuery *self, InStream *instream) {
     float    boost        = InStream_Read_F32(instream);
     uint32_t num_children = InStream_Read_U32(instream);
     PolyQuery_init(self, NULL);
+    PolyQueryIVARS *const ivars = PolyQuery_IVARS(self);
     PolyQuery_Set_Boost(self, boost);
-    VA_Grow(self->children, num_children);
+    VA_Grow(ivars->children, num_children);
     while (num_children--) {
-        VA_Push(self->children, THAW(instream));
+        VA_Push(ivars->children, THAW(instream));
     }
     return self;
 }
 
 bool
 PolyQuery_equals(PolyQuery *self, Obj *other) {
-    PolyQuery *twin = (PolyQuery*)other;
-    if (twin == self)                                     { return true; }
-    if (!Obj_Is_A(other, POLYQUERY))                      { return false; }
-    if (self->boost != twin->boost)                       { return false; }
-    if (!VA_Equals(twin->children, (Obj*)self->children)) { return false; }
+    if ((PolyQuery*)other == self)                          { return true; }
+    if (!Obj_Is_A(other, POLYQUERY))                        { return false; }
+    PolyQueryIVARS *const ivars = PolyQuery_IVARS(self);
+    PolyQueryIVARS *const ovars = PolyQuery_IVARS((PolyQuery*)other);
+    if (ivars->boost != ovars->boost)                       { return false; }
+    if (!VA_Equals(ovars->children, (Obj*)ivars->children)) { return false; }
     return true;
 }
 
@@ -102,18 +109,20 @@ PolyQuery_equals(PolyQuery *self, Obj *other) {
 PolyCompiler*
 PolyCompiler_init(PolyCompiler *self, PolyQuery *parent,
                   Searcher *searcher, float boost) {
-    const uint32_t num_kids = VA_Get_Size(parent->children);
+    PolyCompilerIVARS *const ivars = PolyCompiler_IVARS(self);
+    PolyQueryIVARS *const parent_ivars = PolyQuery_IVARS(parent);
+    const uint32_t num_kids = VA_Get_Size(parent_ivars->children);
 
     Compiler_init((Compiler*)self, (Query*)parent, searcher, NULL, boost);
-    self->children = VA_new(num_kids);
+    ivars->children = VA_new(num_kids);
 
     // Iterate over the children, creating a Compiler for each one.
     for (uint32_t i = 0; i < num_kids; i++) {
-        Query *child_query = (Query*)VA_Fetch(parent->children, i);
+        Query *child_query = (Query*)VA_Fetch(parent_ivars->children, i);
         float sub_boost = boost * Query_Get_Boost(child_query);
         Compiler *child_compiler
             = Query_Make_Compiler(child_query, searcher, sub_boost, true);
-        VA_Push(self->children, (Obj*)child_compiler);
+        VA_Push(ivars->children, (Obj*)child_compiler);
     }
 
     return self;
@@ -121,17 +130,19 @@ PolyCompiler_init(PolyCompiler *self, PolyQuery *parent,
 
 void
 PolyCompiler_destroy(PolyCompiler *self) {
-    DECREF(self->children);
+    PolyCompilerIVARS *const ivars = PolyCompiler_IVARS(self);
+    DECREF(ivars->children);
     SUPER_DESTROY(self, POLYCOMPILER);
 }
 
 float
 PolyCompiler_sum_of_squared_weights(PolyCompiler *self) {
+    PolyCompilerIVARS *const ivars = PolyCompiler_IVARS(self);
     float sum      = 0;
     float my_boost = PolyCompiler_Get_Boost(self);
 
-    for (uint32_t i = 0, max = VA_Get_Size(self->children); i < max; i++) {
-        Compiler *child = (Compiler*)VA_Fetch(self->children, i);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->children); i < max; i++) {
+        Compiler *child = (Compiler*)VA_Fetch(ivars->children, i);
         sum += Compiler_Sum_Of_Squared_Weights(child);
     }
 
@@ -143,8 +154,9 @@ PolyCompiler_sum_of_squared_weights(PolyCompiler *self) {
 
 void
 PolyCompiler_apply_norm_factor(PolyCompiler *self, float factor) {
-    for (uint32_t i = 0, max = VA_Get_Size(self->children); i < max; i++) {
-        Compiler *child = (Compiler*)VA_Fetch(self->children, i);
+    PolyCompilerIVARS *const ivars = PolyCompiler_IVARS(self);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->children); i < max; i++) {
+        Compiler *child = (Compiler*)VA_Fetch(ivars->children, i);
         Compiler_Apply_Norm_Factor(child, factor);
     }
 }
@@ -152,9 +164,10 @@ PolyCompiler_apply_norm_factor(PolyCompiler *self, float factor) {
 VArray*
 PolyCompiler_highlight_spans(PolyCompiler *self, Searcher *searcher,
                              DocVector *doc_vec, const CharBuf *field) {
+    PolyCompilerIVARS *const ivars = PolyCompiler_IVARS(self);
     VArray *spans = VA_new(0);
-    for (uint32_t i = 0, max = VA_Get_Size(self->children); i < max; i++) {
-        Compiler *child = (Compiler*)VA_Fetch(self->children, i);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->children); i < max; i++) {
+        Compiler *child = (Compiler*)VA_Fetch(ivars->children, i);
         VArray *child_spans = Compiler_Highlight_Spans(child, searcher,
                                                        doc_vec, field);
         if (child_spans) {
@@ -167,8 +180,9 @@ PolyCompiler_highlight_spans(PolyCompiler *self, Searcher *searcher,
 
 void
 PolyCompiler_serialize(PolyCompiler *self, OutStream *outstream) {
+    PolyCompilerIVARS *const ivars = PolyCompiler_IVARS(self);
     Freezer_serialize_charbuf(PolyCompiler_Get_Class_Name(self), outstream);
-    Freezer_serialize_varray(self->children, outstream);
+    Freezer_serialize_varray(ivars->children, outstream);
     PolyCompiler_Serialize_t super_serialize
         = SUPER_METHOD_PTR(POLYCOMPILER, Lucy_PolyCompiler_Serialize);
     super_serialize(self, outstream);
@@ -176,9 +190,10 @@ PolyCompiler_serialize(PolyCompiler *self, OutStream *outstream) {
 
 PolyCompiler*
 PolyCompiler_deserialize(PolyCompiler *self, InStream *instream) {
+    PolyCompilerIVARS *const ivars = PolyCompiler_IVARS(self);
     CharBuf *class_name = Freezer_read_charbuf(instream);
     DECREF(class_name); // TODO Don't serialize class name.
-    self->children = Freezer_read_varray(instream);
+    ivars->children = Freezer_read_varray(instream);
     PolyCompiler_Deserialize_t super_deserialize
         = SUPER_METHOD_PTR(POLYCOMPILER, Lucy_PolyCompiler_Deserialize);
     return super_deserialize(self, instream);

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/PolySearcher.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/PolySearcher.c b/core/Lucy/Search/PolySearcher.c
index 6789f4c..a7fea42 100644
--- a/core/Lucy/Search/PolySearcher.c
+++ b/core/Lucy/Search/PolySearcher.c
@@ -40,8 +40,9 @@ PolySearcher_init(PolySearcher *self, Schema *schema, VArray *searchers) {
     int32_t  doc_max      = 0;
 
     Searcher_init((Searcher*)self, schema);
-    self->searchers = (VArray*)INCREF(searchers);
-    self->starts = NULL; // Safe cleanup.
+    PolySearcherIVARS *const ivars = PolySearcher_IVARS(self);
+    ivars->searchers = (VArray*)INCREF(searchers);
+    ivars->starts = NULL; // Safe cleanup.
 
     for (uint32_t i = 0; i < num_searchers; i++) {
         Searcher *searcher
@@ -62,24 +63,26 @@ PolySearcher_init(PolySearcher *self, Schema *schema, VArray *searchers) {
         doc_max += Searcher_Doc_Max(searcher);
     }
 
-    self->doc_max = doc_max;
-    self->starts  = I32Arr_new_steal(starts_array, num_searchers);
+    ivars->doc_max = doc_max;
+    ivars->starts  = I32Arr_new_steal(starts_array, num_searchers);
 
     return self;
 }
 
 void
 PolySearcher_destroy(PolySearcher *self) {
-    DECREF(self->searchers);
-    DECREF(self->starts);
+    PolySearcherIVARS *const ivars = PolySearcher_IVARS(self);
+    DECREF(ivars->searchers);
+    DECREF(ivars->starts);
     SUPER_DESTROY(self, POLYSEARCHER);
 }
 
 HitDoc*
 PolySearcher_fetch_doc(PolySearcher *self, int32_t doc_id) {
-    uint32_t  tick     = PolyReader_sub_tick(self->starts, doc_id);
-    Searcher *searcher = (Searcher*)VA_Fetch(self->searchers, tick);
-    int32_t   offset   = I32Arr_Get(self->starts, tick);
+    PolySearcherIVARS *const ivars = PolySearcher_IVARS(self);
+    uint32_t  tick     = PolyReader_sub_tick(ivars->starts, doc_id);
+    Searcher *searcher = (Searcher*)VA_Fetch(ivars->searchers, tick);
+    int32_t   offset   = I32Arr_Get(ivars->starts, tick);
     if (!searcher) { THROW(ERR, "Invalid doc id: %i32", doc_id); }
     HitDoc *hit_doc = Searcher_Fetch_Doc(searcher, doc_id - offset);
     HitDoc_Set_Doc_ID(hit_doc, doc_id);
@@ -88,23 +91,25 @@ PolySearcher_fetch_doc(PolySearcher *self, int32_t doc_id) {
 
 DocVector*
 PolySearcher_fetch_doc_vec(PolySearcher *self, int32_t doc_id) {
-    uint32_t  tick     = PolyReader_sub_tick(self->starts, doc_id);
-    Searcher *searcher = (Searcher*)VA_Fetch(self->searchers, tick);
-    int32_t   start    = I32Arr_Get(self->starts, tick);
+    PolySearcherIVARS *const ivars = PolySearcher_IVARS(self);
+    uint32_t  tick     = PolyReader_sub_tick(ivars->starts, doc_id);
+    Searcher *searcher = (Searcher*)VA_Fetch(ivars->searchers, tick);
+    int32_t   start    = I32Arr_Get(ivars->starts, tick);
     if (!searcher) { THROW(ERR, "Invalid doc id: %i32", doc_id); }
     return Searcher_Fetch_Doc_Vec(searcher, doc_id - start);
 }
 
 int32_t
 PolySearcher_doc_max(PolySearcher *self) {
-    return self->doc_max;
+    return PolySearcher_IVARS(self)->doc_max;
 }
 
 uint32_t
 PolySearcher_doc_freq(PolySearcher *self, const CharBuf *field, Obj *term) {
+    PolySearcherIVARS *const ivars = PolySearcher_IVARS(self);
     uint32_t doc_freq = 0;
-    for (uint32_t i = 0, max = VA_Get_Size(self->searchers); i < max; i++) {
-        Searcher *searcher = (Searcher*)VA_Fetch(self->searchers, i);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->searchers); i < max; i++) {
+        Searcher *searcher = (Searcher*)VA_Fetch(ivars->searchers, i);
         doc_freq += Searcher_Doc_Freq(searcher, field, term);
     }
     return doc_freq;
@@ -122,9 +127,10 @@ S_modify_doc_ids(VArray *match_docs, int32_t base) {
 TopDocs*
 PolySearcher_top_docs(PolySearcher *self, Query *query, uint32_t num_wanted,
                       SortSpec *sort_spec) {
+    PolySearcherIVARS *const ivars = PolySearcher_IVARS(self);
     Schema   *schema      = PolySearcher_Get_Schema(self);
-    VArray   *searchers   = self->searchers;
-    I32Array *starts      = self->starts;
+    VArray   *searchers   = ivars->searchers;
+    I32Array *starts      = ivars->starts;
     HitQueue *hit_q       = sort_spec
                             ? HitQ_new(schema, sort_spec, num_wanted)
                             : HitQ_new(NULL, NULL, num_wanted);
@@ -166,8 +172,9 @@ PolySearcher_top_docs(PolySearcher *self, Query *query, uint32_t num_wanted,
 void
 PolySearcher_collect(PolySearcher *self, Query *query,
                      Collector *collector) {
-    VArray *const searchers = self->searchers;
-    I32Array *starts = self->starts;
+    PolySearcherIVARS *const ivars = PolySearcher_IVARS(self);
+    VArray *const searchers = ivars->searchers;
+    I32Array *starts = ivars->starts;
 
     for (uint32_t i = 0, max = VA_Get_Size(searchers); i < max; i++) {
         int32_t start = I32Arr_Get(starts, i);

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/Query.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/Query.c b/core/Lucy/Search/Query.c
index 05a9106..20243ed 100644
--- a/core/Lucy/Search/Query.c
+++ b/core/Lucy/Search/Query.c
@@ -25,24 +25,24 @@
 
 Query*
 Query_init(Query *self, float boost) {
-    self->boost = boost;
+    Query_IVARS(self)->boost = boost;
     ABSTRACT_CLASS_CHECK(self, QUERY);
     return self;
 }
 
 void
 Query_set_boost(Query *self, float boost) {
-    self->boost = boost;
+    Query_IVARS(self)->boost = boost;
 }
 
 float
 Query_get_boost(Query *self) {
-    return self->boost;
+    return Query_IVARS(self)->boost;
 }
 
 void
 Query_serialize(Query *self, OutStream *outstream) {
-    OutStream_Write_F32(outstream, self->boost);
+    OutStream_Write_F32(outstream, Query_IVARS(self)->boost);
 }
 
 Query*

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/QueryParser.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/QueryParser.c b/core/Lucy/Search/QueryParser.c
index 5a0119b..5c99ce7 100644
--- a/core/Lucy/Search/QueryParser.c
+++ b/core/Lucy/Search/QueryParser.c
@@ -104,48 +104,49 @@ QParser_new(Schema *schema, Analyzer *analyzer, const CharBuf *default_boolop,
 QueryParser*
 QParser_init(QueryParser *self, Schema *schema, Analyzer *analyzer,
              const CharBuf *default_boolop, VArray *fields) {
+    QueryParserIVARS *const ivars = QParser_IVARS(self);
     // Init.
-    self->heed_colons = false;
-    self->lexer       = QueryLexer_new();
+    ivars->heed_colons = false;
+    ivars->lexer       = QueryLexer_new();
 
     // Assign.
-    self->schema         = (Schema*)INCREF(schema);
-    self->analyzer       = (Analyzer*)INCREF(analyzer);
-    self->default_boolop = default_boolop
+    ivars->schema         = (Schema*)INCREF(schema);
+    ivars->analyzer       = (Analyzer*)INCREF(analyzer);
+    ivars->default_boolop = default_boolop
                            ? CB_Clone(default_boolop)
                            : CB_new_from_trusted_utf8("OR", 2);
 
     if (fields) {
-        self->fields = VA_Shallow_Copy(fields);
+        ivars->fields = VA_Shallow_Copy(fields);
         for (uint32_t i = 0, max = VA_Get_Size(fields); i < max; i++) {
             CERTIFY(VA_Fetch(fields, i), CHARBUF);
         }
-        VA_Sort(self->fields, NULL, NULL);
+        VA_Sort(ivars->fields, NULL, NULL);
     }
     else {
         VArray *all_fields = Schema_All_Fields(schema);
         uint32_t num_fields = VA_Get_Size(all_fields);
-        self->fields = VA_new(num_fields);
+        ivars->fields = VA_new(num_fields);
         for (uint32_t i = 0; i < num_fields; i++) {
             CharBuf *field = (CharBuf*)VA_Fetch(all_fields, i);
             FieldType *type = Schema_Fetch_Type(schema, field);
             if (type && FType_Indexed(type)) {
-                VA_Push(self->fields, INCREF(field));
+                VA_Push(ivars->fields, INCREF(field));
             }
         }
         DECREF(all_fields);
     }
-    VA_Sort(self->fields, NULL, NULL);
+    VA_Sort(ivars->fields, NULL, NULL);
 
     // Derive default "occur" from default boolean operator.
-    if (CB_Equals_Str(self->default_boolop, "OR", 2)) {
-        self->default_occur = SHOULD;
+    if (CB_Equals_Str(ivars->default_boolop, "OR", 2)) {
+        ivars->default_occur = SHOULD;
     }
-    else if (CB_Equals_Str(self->default_boolop, "AND", 3)) {
-        self->default_occur = MUST;
+    else if (CB_Equals_Str(ivars->default_boolop, "AND", 3)) {
+        ivars->default_occur = MUST;
     }
     else {
-        THROW(ERR, "Invalid value for default_boolop: %o", self->default_boolop);
+        THROW(ERR, "Invalid value for default_boolop: %o", ivars->default_boolop);
     }
 
     return self;
@@ -153,43 +154,45 @@ QParser_init(QueryParser *self, Schema *schema, Analyzer *analyzer,
 
 void
 QParser_destroy(QueryParser *self) {
-    DECREF(self->schema);
-    DECREF(self->analyzer);
-    DECREF(self->default_boolop);
-    DECREF(self->fields);
-    DECREF(self->lexer);
+    QueryParserIVARS *const ivars = QParser_IVARS(self);
+    DECREF(ivars->schema);
+    DECREF(ivars->analyzer);
+    DECREF(ivars->default_boolop);
+    DECREF(ivars->fields);
+    DECREF(ivars->lexer);
     SUPER_DESTROY(self, QUERYPARSER);
 }
 
 Analyzer*
 QParser_get_analyzer(QueryParser *self) {
-    return self->analyzer;
+    return QParser_IVARS(self)->analyzer;
 }
 
 Schema*
 QParser_get_schema(QueryParser *self) {
-    return self->schema;
+    return QParser_IVARS(self)->schema;
 }
 
 CharBuf*
 QParser_get_default_boolop(QueryParser *self) {
-    return self->default_boolop;
+    return QParser_IVARS(self)->default_boolop;
 }
 
 VArray*
 QParser_get_fields(QueryParser *self) {
-    return self->fields;
+    return QParser_IVARS(self)->fields;
 }
 
 bool
 QParser_heed_colons(QueryParser *self) {
-    return self->heed_colons;
+    return QParser_IVARS(self)->heed_colons;
 }
 
 void
 QParser_set_heed_colons(QueryParser *self, bool heed_colons) {
-    self->heed_colons = heed_colons;
-    QueryLexer_Set_Heed_Colons(self->lexer, heed_colons);
+    QueryParserIVARS *const ivars = QParser_IVARS(self);
+    ivars->heed_colons = heed_colons;
+    QueryLexer_Set_Heed_Colons(ivars->lexer, heed_colons);
 }
 
 
@@ -209,7 +212,8 @@ QParser_parse(QueryParser *self, const CharBuf *query_string) {
 
 Query*
 QParser_tree(QueryParser *self, const CharBuf *query_string) {
-    VArray *elems = QueryLexer_Tokenize(self->lexer, query_string);
+    QueryParserIVARS *const ivars = QParser_IVARS(self);
+    VArray *elems = QueryLexer_Tokenize(ivars->lexer, query_string);
     S_balance_parens(self, elems);
     S_parse_subqueries(self, elems);
     Query *query = S_parse_subquery(self, elems, NULL, false);
@@ -219,6 +223,7 @@ QParser_tree(QueryParser *self, const CharBuf *query_string) {
 
 static void
 S_parse_subqueries(QueryParser *self, VArray *elems) {
+    const int32_t default_occur = QParser_IVARS(self)->default_occur;
     while (1) {
         // Work from the inside out, starting with the leftmost innermost
         // paren group.
@@ -254,7 +259,7 @@ S_parse_subqueries(QueryParser *self, VArray *elems) {
         VArray *sub_elems = VA_Slice(elems, left + 1, right - left - 1);
         Query *subquery = S_parse_subquery(self, sub_elems, field, true);
         ParserElem *new_elem = ParserElem_new(TOKEN_QUERY, (Obj*)subquery);
-        if (self->default_occur == MUST) {
+        if (default_occur == MUST) {
             ParserElem_Require(new_elem);
         }
         DECREF(sub_elems);
@@ -351,6 +356,8 @@ S_balance_parens(QueryParser *self, VArray *elems) {
 static void
 S_compose_inner_queries(QueryParser *self, VArray *elems,
                         CharBuf *default_field) {
+    const int32_t default_occur = QParser_IVARS(self)->default_occur;
+
     // Generate all queries.  Apply any fields.
     for (uint32_t i = VA_Get_Size(elems); i--;) {
         CharBuf *field = default_field;
@@ -371,7 +378,7 @@ S_compose_inner_queries(QueryParser *self, VArray *elems,
             LeafQuery *query = LeafQuery_new(field, text);
             ParserElem *new_elem
                 = ParserElem_new(TOKEN_QUERY, (Obj*)query);
-            if (self->default_occur == MUST) {
+            if (default_occur == MUST) {
                 ParserElem_Require(new_elem);
             }
             VA_Store(elems, i, (Obj*)new_elem);
@@ -445,6 +452,8 @@ S_winnow_boolops(QueryParser *self, VArray *elems) {
 // Apply AND.
 static void
 S_compose_and_queries(QueryParser *self, VArray *elems) {
+    const int32_t default_occur = QParser_IVARS(self)->default_occur;
+
     for (uint32_t i = 0; i + 2 < VA_Get_Size(elems); i++) {
         ParserElem *elem = (ParserElem*)VA_Fetch(elems, i + 1);
         if (ParserElem_Get_Type(elem) == TOKEN_AND) {
@@ -477,7 +486,7 @@ S_compose_and_queries(QueryParser *self, VArray *elems) {
             }
             Query *and_query = QParser_Make_AND_Query(self, children);
             ParserElem_Set_Value(preceding, (Obj*)and_query);
-            if (self->default_occur == MUST) {
+            if (default_occur == MUST) {
                 ParserElem_Require(preceding);
             }
             DECREF(and_query);
@@ -490,6 +499,8 @@ S_compose_and_queries(QueryParser *self, VArray *elems) {
 
 static void
 S_compose_or_queries(QueryParser *self, VArray *elems) {
+    const int32_t default_occur = QParser_IVARS(self)->default_occur;
+
     for (uint32_t i = 0; i + 2 < VA_Get_Size(elems); i++) {
         ParserElem *elem = (ParserElem*)VA_Fetch(elems, i + 1);
         if (ParserElem_Get_Type(elem) == TOKEN_OR) {
@@ -522,7 +533,7 @@ S_compose_or_queries(QueryParser *self, VArray *elems) {
             }
             Query *or_query = QParser_Make_OR_Query(self, children);
             ParserElem_Set_Value(preceding, (Obj*)or_query);
-            if (self->default_occur == MUST) {
+            if (default_occur == MUST) {
                 ParserElem_Require(preceding);
             }
             DECREF(or_query);
@@ -535,13 +546,14 @@ S_compose_or_queries(QueryParser *self, VArray *elems) {
 
 static Query*
 S_compose_subquery(QueryParser *self, VArray *elems, bool enclosed) {
+    const int32_t default_occur = QParser_IVARS(self)->default_occur;
     Query *retval;
 
     if (VA_Get_Size(elems) == 0) {
         // No elems means no query. Maybe the search string was something
         // like 'NOT AND'
         if (enclosed) {
-            retval = self->default_occur == SHOULD
+            retval = default_occur == SHOULD
                      ? QParser_Make_OR_Query(self, NULL)
                      : QParser_Make_AND_Query(self, NULL);
         }
@@ -843,8 +855,9 @@ S_unescape(QueryParser *self, CharBuf *orig, CharBuf *target) {
 
 Query*
 QParser_expand_leaf(QueryParser *self, Query *query) {
+    QueryParserIVARS *const ivars = QParser_IVARS(self);
     LeafQuery     *leaf_query  = (LeafQuery*)query;
-    Schema        *schema      = self->schema;
+    Schema        *schema      = ivars->schema;
     ZombieCharBuf *source_text = ZCB_BLANK();
     bool           is_phrase   = false;
     bool           ambiguous   = false;
@@ -873,15 +886,15 @@ QParser_expand_leaf(QueryParser *self, Query *query) {
         VA_Push(fields, INCREF(LeafQuery_Get_Field(leaf_query)));
     }
     else {
-        fields = (VArray*)INCREF(self->fields);
+        fields = (VArray*)INCREF(ivars->fields);
     }
 
     CharBuf *unescaped = CB_new(ZCB_Get_Size(source_text));
     VArray  *queries   = VA_new(VA_Get_Size(fields));
     for (uint32_t i = 0, max = VA_Get_Size(fields); i < max; i++) {
         CharBuf  *field    = (CharBuf*)VA_Fetch(fields, i);
-        Analyzer *analyzer = self->analyzer
-                             ? self->analyzer
+        Analyzer *analyzer = ivars->analyzer
+                             ? ivars->analyzer
                              : Schema_Fetch_Analyzer(schema, field);
 
         if (!analyzer) {

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/RangeMatcher.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/RangeMatcher.c b/core/Lucy/Search/RangeMatcher.c
index 811a19b..7e1c094 100644
--- a/core/Lucy/Search/RangeMatcher.c
+++ b/core/Lucy/Search/RangeMatcher.c
@@ -32,15 +32,16 @@ RangeMatcher*
 RangeMatcher_init(RangeMatcher *self, int32_t lower_bound, int32_t upper_bound,
                   SortCache *sort_cache, int32_t doc_max) {
     Matcher_init((Matcher*)self);
+    RangeMatcherIVARS *const ivars = RangeMatcher_IVARS(self);
 
     // Init.
-    self->doc_id       = 0;
+    ivars->doc_id       = 0;
 
     // Assign.
-    self->lower_bound  = lower_bound;
-    self->upper_bound  = upper_bound;
-    self->sort_cache   = (SortCache*)INCREF(sort_cache);
-    self->doc_max      = doc_max;
+    ivars->lower_bound  = lower_bound;
+    ivars->upper_bound  = upper_bound;
+    ivars->sort_cache   = (SortCache*)INCREF(sort_cache);
+    ivars->doc_max      = doc_max;
 
     // Derive.
 
@@ -49,15 +50,17 @@ RangeMatcher_init(RangeMatcher *self, int32_t lower_bound, int32_t upper_bound,
 
 void
 RangeMatcher_destroy(RangeMatcher *self) {
-    DECREF(self->sort_cache);
+    RangeMatcherIVARS *const ivars = RangeMatcher_IVARS(self);
+    DECREF(ivars->sort_cache);
     SUPER_DESTROY(self, RANGEMATCHER);
 }
 
 int32_t
 RangeMatcher_next(RangeMatcher* self) {
+    RangeMatcherIVARS *const ivars = RangeMatcher_IVARS(self);
     while (1) {
-        if (++self->doc_id > self->doc_max) {
-            self->doc_id--;
+        if (++ivars->doc_id > ivars->doc_max) {
+            ivars->doc_id--;
             return 0;
         }
         else {
@@ -65,18 +68,18 @@ RangeMatcher_next(RangeMatcher* self) {
             // TODO: Unroll? i.e. use SortCache_Get_Ords at constructor time
             // and save ourselves some method call overhead.
             const int32_t ord
-                = SortCache_Ordinal(self->sort_cache, self->doc_id);
-            if (ord >= self->lower_bound && ord <= self->upper_bound) {
+                = SortCache_Ordinal(ivars->sort_cache, ivars->doc_id);
+            if (ord >= ivars->lower_bound && ord <= ivars->upper_bound) {
                 break;
             }
         }
     }
-    return self->doc_id;
+    return ivars->doc_id;
 }
 
 int32_t
 RangeMatcher_advance(RangeMatcher* self, int32_t target) {
-    self->doc_id = target - 1;
+    RangeMatcher_IVARS(self)->doc_id = target - 1;
     return RangeMatcher_next(self);
 }
 
@@ -88,7 +91,7 @@ RangeMatcher_score(RangeMatcher* self) {
 
 int32_t
 RangeMatcher_get_doc_id(RangeMatcher* self) {
-    return self->doc_id;
+    return RangeMatcher_IVARS(self)->doc_id;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/RangeQuery.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/RangeQuery.c b/core/Lucy/Search/RangeQuery.c
index 4349daf..3f7ff15 100644
--- a/core/Lucy/Search/RangeQuery.c
+++ b/core/Lucy/Search/RangeQuery.c
@@ -52,11 +52,12 @@ RangeQuery*
 RangeQuery_init(RangeQuery *self, const CharBuf *field, Obj *lower_term,
                 Obj *upper_term, bool include_lower, bool include_upper) {
     Query_init((Query*)self, 0.0f);
-    self->field          = CB_Clone(field);
-    self->lower_term     = lower_term ? Obj_Clone(lower_term) : NULL;
-    self->upper_term     = upper_term ? Obj_Clone(upper_term) : NULL;
-    self->include_lower  = include_lower;
-    self->include_upper  = include_upper;
+    RangeQueryIVARS *const ivars = RangeQuery_IVARS(self);
+    ivars->field          = CB_Clone(field);
+    ivars->lower_term     = lower_term ? Obj_Clone(lower_term) : NULL;
+    ivars->upper_term     = upper_term ? Obj_Clone(upper_term) : NULL;
+    ivars->include_lower  = include_lower;
+    ivars->include_upper  = include_upper;
     if (!upper_term && !lower_term) {
         DECREF(self);
         self = NULL;
@@ -67,45 +68,48 @@ RangeQuery_init(RangeQuery *self, const CharBuf *field, Obj *lower_term,
 
 void
 RangeQuery_destroy(RangeQuery *self) {
-    DECREF(self->field);
-    DECREF(self->lower_term);
-    DECREF(self->upper_term);
+    RangeQueryIVARS *const ivars = RangeQuery_IVARS(self);
+    DECREF(ivars->field);
+    DECREF(ivars->lower_term);
+    DECREF(ivars->upper_term);
     SUPER_DESTROY(self, RANGEQUERY);
 }
 
 bool
 RangeQuery_equals(RangeQuery *self, Obj *other) {
-    RangeQuery *twin = (RangeQuery*)other;
-    if (twin == self)                               { return true; }
-    if (!Obj_Is_A(other, RANGEQUERY))               { return false; }
-    if (self->boost != twin->boost)                 { return false; }
-    if (!CB_Equals(self->field, (Obj*)twin->field)) { return false; }
-    if (self->lower_term && !twin->lower_term)      { return false; }
-    if (self->upper_term && !twin->upper_term)      { return false; }
-    if (!self->lower_term && twin->lower_term)      { return false; }
-    if (!self->upper_term && twin->upper_term)      { return false; }
-    if (self->lower_term
-        && !Obj_Equals(self->lower_term, twin->lower_term)) { return false; }
-    if (self->upper_term
-        && !Obj_Equals(self->upper_term, twin->upper_term)) { return false; }
-    if (self->include_lower != twin->include_lower)         { return false; }
-    if (self->include_upper != twin->include_upper)         { return false; }
+    if ((RangeQuery*)other == self)                   { return true; }
+    if (!Obj_Is_A(other, RANGEQUERY))                 { return false; }
+    RangeQueryIVARS *const ivars = RangeQuery_IVARS(self);
+    RangeQueryIVARS *const ovars = RangeQuery_IVARS((RangeQuery*)other);
+    if (ivars->boost != ovars->boost)                 { return false; }
+    if (!CB_Equals(ivars->field, (Obj*)ovars->field)) { return false; }
+    if (ivars->lower_term && !ovars->lower_term)      { return false; }
+    if (ivars->upper_term && !ovars->upper_term)      { return false; }
+    if (!ivars->lower_term && ovars->lower_term)      { return false; }
+    if (!ivars->upper_term && ovars->upper_term)      { return false; }
+    if (ivars->lower_term
+        && !Obj_Equals(ivars->lower_term, ovars->lower_term)) { return false; }
+    if (ivars->upper_term
+        && !Obj_Equals(ivars->upper_term, ovars->upper_term)) { return false; }
+    if (ivars->include_lower != ovars->include_lower)         { return false; }
+    if (ivars->include_upper != ovars->include_upper)         { return false; }
     return true;
 }
 
 CharBuf*
 RangeQuery_to_string(RangeQuery *self) {
-    CharBuf *lower_term_str = self->lower_term
-                              ? Obj_To_String(self->lower_term)
+    RangeQueryIVARS *const ivars = RangeQuery_IVARS(self);
+    CharBuf *lower_term_str = ivars->lower_term
+                              ? Obj_To_String(ivars->lower_term)
                               : CB_new_from_trusted_utf8("*", 1);
-    CharBuf *upper_term_str = self->upper_term
-                              ? Obj_To_String(self->upper_term)
+    CharBuf *upper_term_str = ivars->upper_term
+                              ? Obj_To_String(ivars->upper_term)
                               : CB_new_from_trusted_utf8("*", 1);
-    CharBuf *retval = CB_newf("%o:%s%o TO %o%s", self->field,
-                              self->include_lower ? "[" : "{",
+    CharBuf *retval = CB_newf("%o:%s%o TO %o%s", ivars->field,
+                              ivars->include_lower ? "[" : "{",
                               lower_term_str,
                               upper_term_str,
-                              self->include_upper ? "]" : "}"
+                              ivars->include_upper ? "]" : "}"
                              );
     DECREF(upper_term_str);
     DECREF(lower_term_str);
@@ -114,24 +118,25 @@ RangeQuery_to_string(RangeQuery *self) {
 
 void
 RangeQuery_serialize(RangeQuery *self, OutStream *outstream) {
-    OutStream_Write_F32(outstream, self->boost);
-    Freezer_serialize_charbuf(self->field, outstream);
-    if (self->lower_term) {
+    RangeQueryIVARS *const ivars = RangeQuery_IVARS(self);
+    OutStream_Write_F32(outstream, ivars->boost);
+    Freezer_serialize_charbuf(ivars->field, outstream);
+    if (ivars->lower_term) {
         OutStream_Write_U8(outstream, true);
-        FREEZE(self->lower_term, outstream);
+        FREEZE(ivars->lower_term, outstream);
     }
     else {
         OutStream_Write_U8(outstream, false);
     }
-    if (self->upper_term) {
+    if (ivars->upper_term) {
         OutStream_Write_U8(outstream, true);
-        FREEZE(self->upper_term, outstream);
+        FREEZE(ivars->upper_term, outstream);
     }
     else {
         OutStream_Write_U8(outstream, false);
     }
-    OutStream_Write_U8(outstream, self->include_lower);
-    OutStream_Write_U8(outstream, self->include_upper);
+    OutStream_Write_U8(outstream, ivars->include_lower);
+    OutStream_Write_U8(outstream, ivars->include_upper);
 }
 
 RangeQuery*
@@ -184,11 +189,12 @@ RangeCompiler_init(RangeCompiler *self, RangeQuery *parent,
 Matcher*
 RangeCompiler_make_matcher(RangeCompiler *self, SegReader *reader,
                            bool need_score) {
-    RangeQuery *parent = (RangeQuery*)self->parent;
+    RangeQuery *parent = (RangeQuery*)RangeCompiler_IVARS(self)->parent;
+    const CharBuf *field = RangeQuery_IVARS(parent)->field;
     SortReader *sort_reader
         = (SortReader*)SegReader_Fetch(reader, VTable_Get_Name(SORTREADER));
     SortCache *sort_cache = sort_reader
-                            ? SortReader_Fetch_Sort_Cache(sort_reader, parent->field)
+                            ? SortReader_Fetch_Sort_Cache(sort_reader, field)
                             : NULL;
     UNUSED_VAR(need_score);
 
@@ -212,8 +218,8 @@ RangeCompiler_make_matcher(RangeCompiler *self, SegReader *reader,
 
 static int32_t
 S_find_lower_bound(RangeCompiler *self, SortCache *sort_cache) {
-    RangeQuery *parent      = (RangeQuery*)self->parent;
-    Obj        *lower_term  = parent->lower_term;
+    RangeQuery *parent      = (RangeQuery*)RangeCompiler_IVARS(self)->parent;
+    Obj        *lower_term  = RangeQuery_IVARS(parent)->lower_term;
     int32_t     lower_bound = 0;
 
     if (lower_term) {
@@ -230,7 +236,7 @@ S_find_lower_bound(RangeCompiler *self, SortCache *sort_cache) {
                                  : Obj_Equals(lower_term, low_found);
 
             lower_bound = low_ord;
-            if (!exact_match || !parent->include_lower) {
+            if (!exact_match || !RangeQuery_IVARS(parent)->include_lower) {
                 lower_bound++;
             }
             DECREF(value);
@@ -242,8 +248,8 @@ S_find_lower_bound(RangeCompiler *self, SortCache *sort_cache) {
 
 static int32_t
 S_find_upper_bound(RangeCompiler *self, SortCache *sort_cache) {
-    RangeQuery *parent     = (RangeQuery*)self->parent;
-    Obj        *upper_term = parent->upper_term;
+    RangeQuery *parent     = (RangeQuery*)RangeCompiler_IVARS(self)->parent;
+    Obj        *upper_term = RangeQuery_IVARS(parent)->upper_term;
     int32_t     retval     = INT32_MAX;
 
     if (upper_term) {
@@ -260,7 +266,7 @@ S_find_upper_bound(RangeCompiler *self, SortCache *sort_cache) {
                                  : Obj_Equals(upper_term, (Obj*)hi_found);
 
             retval = hi_ord;
-            if (exact_match && !parent->include_upper) {
+            if (exact_match && !RangeQuery_IVARS(parent)->include_upper) {
                 retval--;
             }
             DECREF(value);

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/RequiredOptionalMatcher.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/RequiredOptionalMatcher.c b/core/Lucy/Search/RequiredOptionalMatcher.c
index bf38f19..c419aa3 100644
--- a/core/Lucy/Search/RequiredOptionalMatcher.c
+++ b/core/Lucy/Search/RequiredOptionalMatcher.c
@@ -36,13 +36,14 @@ ReqOptMatcher_init(RequiredOptionalMatcher *self, Similarity *similarity,
     VA_Push(children, INCREF(required_matcher));
     VA_Push(children, INCREF(optional_matcher));
     PolyMatcher_init((PolyMatcher*)self, children, similarity);
+    RequiredOptionalMatcherIVARS *const ivars = ReqOptMatcher_IVARS(self);
 
     // Assign.
-    self->req_matcher       = (Matcher*)INCREF(required_matcher);
-    self->opt_matcher       = (Matcher*)INCREF(optional_matcher);
+    ivars->req_matcher      = (Matcher*)INCREF(required_matcher);
+    ivars->opt_matcher      = (Matcher*)INCREF(optional_matcher);
 
     // Init.
-    self->opt_matcher_first_time = true;
+    ivars->opt_matcher_first_time = true;
 
     DECREF(children);
     return self;
@@ -50,63 +51,68 @@ ReqOptMatcher_init(RequiredOptionalMatcher *self, Similarity *similarity,
 
 void
 ReqOptMatcher_destroy(RequiredOptionalMatcher *self) {
-    DECREF(self->req_matcher);
-    DECREF(self->opt_matcher);
+    RequiredOptionalMatcherIVARS *const ivars = ReqOptMatcher_IVARS(self);
+    DECREF(ivars->req_matcher);
+    DECREF(ivars->opt_matcher);
     SUPER_DESTROY(self, REQUIREDOPTIONALMATCHER);
 }
 
 int32_t
 ReqOptMatcher_next(RequiredOptionalMatcher *self) {
-    return Matcher_Next(self->req_matcher);
+    RequiredOptionalMatcherIVARS *const ivars = ReqOptMatcher_IVARS(self);
+    return Matcher_Next(ivars->req_matcher);
 }
 
 int32_t
 ReqOptMatcher_advance(RequiredOptionalMatcher *self, int32_t target) {
-    return Matcher_Advance(self->req_matcher, target);
+    RequiredOptionalMatcherIVARS *const ivars = ReqOptMatcher_IVARS(self);
+    return Matcher_Advance(ivars->req_matcher, target);
 }
 
 int32_t
 ReqOptMatcher_get_doc_id(RequiredOptionalMatcher *self) {
-    return Matcher_Get_Doc_ID(self->req_matcher);
+    RequiredOptionalMatcherIVARS *const ivars = ReqOptMatcher_IVARS(self);
+    return Matcher_Get_Doc_ID(ivars->req_matcher);
 }
 
 float
 ReqOptMatcher_score(RequiredOptionalMatcher *self) {
-    int32_t const current_doc = Matcher_Get_Doc_ID(self->req_matcher);
-
-    if (self->opt_matcher_first_time) {
-        self->opt_matcher_first_time = false;
-        if (self->opt_matcher != NULL
-            && !Matcher_Advance(self->opt_matcher, current_doc)) {
-            DECREF(self->opt_matcher);
-            self->opt_matcher = NULL;
+    RequiredOptionalMatcherIVARS *const ivars = ReqOptMatcher_IVARS(self);
+    int32_t const current_doc = Matcher_Get_Doc_ID(ivars->req_matcher);
+
+    if (ivars->opt_matcher_first_time) {
+        ivars->opt_matcher_first_time = false;
+        if (ivars->opt_matcher != NULL
+            && !Matcher_Advance(ivars->opt_matcher, current_doc)) {
+            DECREF(ivars->opt_matcher);
+            ivars->opt_matcher = NULL;
         }
     }
 
-    if (self->opt_matcher == NULL) {
-        return Matcher_Score(self->req_matcher) * self->coord_factors[1];
+    if (ivars->opt_matcher == NULL) {
+        return Matcher_Score(ivars->req_matcher) * ivars->coord_factors[1];
     }
     else {
-        int32_t opt_matcher_doc = Matcher_Get_Doc_ID(self->opt_matcher);
+        int32_t opt_matcher_doc = Matcher_Get_Doc_ID(ivars->opt_matcher);
 
         if (opt_matcher_doc < current_doc) {
-            opt_matcher_doc = Matcher_Advance(self->opt_matcher, current_doc);
+            opt_matcher_doc = Matcher_Advance(ivars->opt_matcher, current_doc);
             if (!opt_matcher_doc) {
-                DECREF(self->opt_matcher);
-                self->opt_matcher = NULL;
-                float req_score = Matcher_Score(self->req_matcher);
-                return req_score * self->coord_factors[1];
+                DECREF(ivars->opt_matcher);
+                ivars->opt_matcher = NULL;
+                float req_score = Matcher_Score(ivars->req_matcher);
+                return req_score * ivars->coord_factors[1];
             }
         }
 
         if (opt_matcher_doc == current_doc) {
-            float score = Matcher_Score(self->req_matcher)
-                          + Matcher_Score(self->opt_matcher);
-            score *= self->coord_factors[2];
+            float score = Matcher_Score(ivars->req_matcher)
+                          + Matcher_Score(ivars->opt_matcher);
+            score *= ivars->coord_factors[2];
             return score;
         }
         else {
-            return Matcher_Score(self->req_matcher) * self->coord_factors[1];
+            return Matcher_Score(ivars->req_matcher) * ivars->coord_factors[1];
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/RequiredOptionalQuery.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/RequiredOptionalQuery.c b/core/Lucy/Search/RequiredOptionalQuery.c
index 9a03123..2103755 100644
--- a/core/Lucy/Search/RequiredOptionalQuery.c
+++ b/core/Lucy/Search/RequiredOptionalQuery.c
@@ -36,37 +36,43 @@ RequiredOptionalQuery*
 ReqOptQuery_init(RequiredOptionalQuery *self, Query *required_query,
                  Query *optional_query) {
     PolyQuery_init((PolyQuery*)self, NULL);
-    VA_Push(self->children, INCREF(required_query));
-    VA_Push(self->children, INCREF(optional_query));
+    RequiredOptionalQueryIVARS *const ivars = ReqOptQuery_IVARS(self);
+    VA_Push(ivars->children, INCREF(required_query));
+    VA_Push(ivars->children, INCREF(optional_query));
     return self;
 }
 
 Query*
 ReqOptQuery_get_required_query(RequiredOptionalQuery *self) {
-    return (Query*)VA_Fetch(self->children, 0);
+    RequiredOptionalQueryIVARS *const ivars = ReqOptQuery_IVARS(self);
+    return (Query*)VA_Fetch(ivars->children, 0);
 }
 
 void
 ReqOptQuery_set_required_query(RequiredOptionalQuery *self,
                                Query *required_query) {
-    VA_Store(self->children, 0, INCREF(required_query));
+    RequiredOptionalQueryIVARS *const ivars = ReqOptQuery_IVARS(self);
+    VA_Store(ivars->children, 0, INCREF(required_query));
 }
 
 Query*
 ReqOptQuery_get_optional_query(RequiredOptionalQuery *self) {
-    return (Query*)VA_Fetch(self->children, 1);
+    RequiredOptionalQueryIVARS *const ivars = ReqOptQuery_IVARS(self);
+    return (Query*)VA_Fetch(ivars->children, 1);
 }
 
 void
 ReqOptQuery_set_optional_query(RequiredOptionalQuery *self,
                                Query *optional_query) {
-    VA_Store(self->children, 1, INCREF(optional_query));
+    RequiredOptionalQueryIVARS *const ivars = ReqOptQuery_IVARS(self);
+    VA_Store(ivars->children, 1, INCREF(optional_query));
 }
 
 CharBuf*
 ReqOptQuery_to_string(RequiredOptionalQuery *self) {
-    CharBuf *req_string = Obj_To_String(VA_Fetch(self->children, 0));
-    CharBuf *opt_string = Obj_To_String(VA_Fetch(self->children, 1));
+    RequiredOptionalQueryIVARS *const ivars = ReqOptQuery_IVARS(self);
+    CharBuf *req_string = Obj_To_String(VA_Fetch(ivars->children, 0));
+    CharBuf *opt_string = Obj_To_String(VA_Fetch(ivars->children, 1));
     CharBuf *retval = CB_newf("(+%o %o)", req_string, opt_string);
     DECREF(opt_string);
     DECREF(req_string);
@@ -114,10 +120,11 @@ ReqOptCompiler_init(RequiredOptionalCompiler *self,
 Matcher*
 ReqOptCompiler_make_matcher(RequiredOptionalCompiler *self, SegReader *reader,
                             bool need_score) {
+    RequiredOptionalCompilerIVARS *const ivars = ReqOptCompiler_IVARS(self);
     Schema     *schema       = SegReader_Get_Schema(reader);
     Similarity *sim          = Schema_Get_Similarity(schema);
-    Compiler   *req_compiler = (Compiler*)VA_Fetch(self->children, 0);
-    Compiler   *opt_compiler = (Compiler*)VA_Fetch(self->children, 1);
+    Compiler   *req_compiler = (Compiler*)VA_Fetch(ivars->children, 0);
+    Compiler   *opt_compiler = (Compiler*)VA_Fetch(ivars->children, 1);
     Matcher *req_matcher
         = Compiler_Make_Matcher(req_compiler, reader, need_score);
     Matcher *opt_matcher

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/Searcher.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/Searcher.c b/core/Lucy/Search/Searcher.c
index 11089b6..8d71631 100644
--- a/core/Lucy/Search/Searcher.c
+++ b/core/Lucy/Search/Searcher.c
@@ -32,16 +32,18 @@
 
 Searcher*
 Searcher_init(Searcher *self, Schema *schema) {
-    self->schema  = (Schema*)INCREF(schema);
-    self->qparser = NULL;
+    SearcherIVARS *const ivars = Searcher_IVARS(self);
+    ivars->schema  = (Schema*)INCREF(schema);
+    ivars->qparser = NULL;
     ABSTRACT_CLASS_CHECK(self, SEARCHER);
     return self;
 }
 
 void
 Searcher_destroy(Searcher *self) {
-    DECREF(self->schema);
-    DECREF(self->qparser);
+    SearcherIVARS *const ivars = Searcher_IVARS(self);
+    DECREF(ivars->schema);
+    DECREF(ivars->qparser);
     SUPER_DESTROY(self, SEARCHER);
 }
 
@@ -63,6 +65,7 @@ Searcher_hits(Searcher *self, Obj *query, uint32_t offset, uint32_t num_wanted,
 
 Query*
 Searcher_glean_query(Searcher *self, Obj *query) {
+    SearcherIVARS *const ivars = Searcher_IVARS(self);
     Query *real_query = NULL;
 
     if (!query) {
@@ -72,10 +75,10 @@ Searcher_glean_query(Searcher *self, Obj *query) {
         real_query = (Query*)INCREF(query);
     }
     else if (Obj_Is_A(query, CHARBUF)) {
-        if (!self->qparser) {
-            self->qparser = QParser_new(self->schema, NULL, NULL, NULL);
+        if (!ivars->qparser) {
+            ivars->qparser = QParser_new(ivars->schema, NULL, NULL, NULL);
         }
-        real_query = QParser_Parse(self->qparser, (CharBuf*)query);
+        real_query = QParser_Parse(ivars->qparser, (CharBuf*)query);
     }
     else {
         THROW(ERR, "Invalid type for 'query' param: %o",
@@ -87,7 +90,7 @@ Searcher_glean_query(Searcher *self, Obj *query) {
 
 Schema*
 Searcher_get_schema(Searcher *self) {
-    return self->schema;
+    return Searcher_IVARS(self)->schema;
 }
 
 void

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/SeriesMatcher.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/SeriesMatcher.c b/core/Lucy/Search/SeriesMatcher.c
index b1d7e52..d255811 100644
--- a/core/Lucy/Search/SeriesMatcher.c
+++ b/core/Lucy/Search/SeriesMatcher.c
@@ -28,54 +28,58 @@ SeriesMatcher_new(VArray *matchers, I32Array *offsets) {
 SeriesMatcher*
 SeriesMatcher_init(SeriesMatcher *self, VArray *matchers, I32Array *offsets) {
     Matcher_init((Matcher*)self);
+    SeriesMatcherIVARS *const ivars = SeriesMatcher_IVARS(self);
 
     // Init.
-    self->current_matcher = NULL;
-    self->current_offset  = 0;
-    self->next_offset     = 0;
-    self->doc_id          = 0;
-    self->tick            = 0;
+    ivars->current_matcher = NULL;
+    ivars->current_offset  = 0;
+    ivars->next_offset     = 0;
+    ivars->doc_id          = 0;
+    ivars->tick            = 0;
 
     // Assign.
-    self->matchers        = (VArray*)INCREF(matchers);
-    self->offsets         = (I32Array*)INCREF(offsets);
+    ivars->matchers        = (VArray*)INCREF(matchers);
+    ivars->offsets         = (I32Array*)INCREF(offsets);
 
     // Derive.
-    self->num_matchers    = (int32_t)I32Arr_Get_Size(offsets);
+    ivars->num_matchers    = (int32_t)I32Arr_Get_Size(offsets);
 
     return self;
 }
 
 void
 SeriesMatcher_destroy(SeriesMatcher *self) {
-    DECREF(self->matchers);
-    DECREF(self->offsets);
+    SeriesMatcherIVARS *const ivars = SeriesMatcher_IVARS(self);
+    DECREF(ivars->matchers);
+    DECREF(ivars->offsets);
     SUPER_DESTROY(self, SERIESMATCHER);
 }
 
 int32_t
 SeriesMatcher_next(SeriesMatcher *self) {
-    return SeriesMatcher_advance(self, self->doc_id + 1);
+    SeriesMatcherIVARS *const ivars = SeriesMatcher_IVARS(self);
+    return SeriesMatcher_advance(self, ivars->doc_id + 1);
 }
 
 int32_t
 SeriesMatcher_advance(SeriesMatcher *self, int32_t target) {
-    if (target >= self->next_offset) {
+    SeriesMatcherIVARS *const ivars = SeriesMatcher_IVARS(self);
+    if (target >= ivars->next_offset) {
         // Proceed to next matcher or bail.
-        if (self->tick < self->num_matchers) {
+        if (ivars->tick < ivars->num_matchers) {
             while (1) {
                 uint32_t next_offset
-                    = self->tick + 1 == self->num_matchers
+                    = ivars->tick + 1 == ivars->num_matchers
                       ? INT32_MAX
-                      : I32Arr_Get(self->offsets, self->tick + 1);
-                self->current_matcher = (Matcher*)VA_Fetch(self->matchers,
-                                                           self->tick);
-                self->current_offset = self->next_offset;
-                self->next_offset = next_offset;
-                self->doc_id = next_offset - 1;
-                self->tick++;
-                if (self->current_matcher != NULL
-                    || self->tick >= self->num_matchers
+                      : I32Arr_Get(ivars->offsets, ivars->tick + 1);
+                ivars->current_matcher = (Matcher*)VA_Fetch(ivars->matchers,
+                                                           ivars->tick);
+                ivars->current_offset = ivars->next_offset;
+                ivars->next_offset = next_offset;
+                ivars->doc_id = next_offset - 1;
+                ivars->tick++;
+                if (ivars->current_matcher != NULL
+                    || ivars->tick >= ivars->num_matchers
                    ) {
                     break;
                 }
@@ -84,28 +88,28 @@ SeriesMatcher_advance(SeriesMatcher *self, int32_t target) {
         }
         else {
             // We're done.
-            self->doc_id = 0;
+            ivars->doc_id = 0;
             return 0;
         }
     }
     else {
-        int32_t target_minus_offset = target - self->current_offset;
+        int32_t target_minus_offset = target - ivars->current_offset;
         int32_t found
-            = Matcher_Advance(self->current_matcher, target_minus_offset);
+            = Matcher_Advance(ivars->current_matcher, target_minus_offset);
         if (found) {
-            self->doc_id = found + self->current_offset;
-            return self->doc_id;
+            ivars->doc_id = found + ivars->current_offset;
+            return ivars->doc_id;
         }
         else {
             // Recurse.
-            return SeriesMatcher_advance(self, self->next_offset);
+            return SeriesMatcher_advance(self, ivars->next_offset);
         }
     }
 }
 
 int32_t
 SeriesMatcher_get_doc_id(SeriesMatcher *self) {
-    return self->doc_id;
+    return SeriesMatcher_IVARS(self)->doc_id;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/SortRule.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/SortRule.c b/core/Lucy/Search/SortRule.c
index ee8f2fd..a5758e5 100644
--- a/core/Lucy/Search/SortRule.c
+++ b/core/Lucy/Search/SortRule.c
@@ -35,9 +35,10 @@ SortRule_new(int32_t type, const CharBuf *field, bool reverse) {
 SortRule*
 SortRule_init(SortRule *self, int32_t type, const CharBuf *field,
               bool reverse) {
-    self->field    = field ? CB_Clone(field) : NULL;
-    self->type     = type;
-    self->reverse  = reverse;
+    SortRuleIVARS *ivars = SortRule_IVARS(self);
+    ivars->field    = field ? CB_Clone(field) : NULL;
+    ivars->type     = type;
+    ivars->reverse  = reverse;
 
     // Validate.
     if (type == SortRule_FIELD) {
@@ -54,42 +55,45 @@ SortRule_init(SortRule *self, int32_t type, const CharBuf *field,
 
 void
 SortRule_destroy(SortRule *self) {
-    DECREF(self->field);
+    SortRuleIVARS *ivars = SortRule_IVARS(self);
+    DECREF(ivars->field);
     SUPER_DESTROY(self, SORTRULE);
 }
 
 SortRule*
 SortRule_deserialize(SortRule *self, InStream *instream) {
-    self->type = InStream_Read_C32(instream);
-    if (self->type == SortRule_FIELD) {
-        self->field = Freezer_read_charbuf(instream);
+    SortRuleIVARS *ivars = SortRule_IVARS(self);
+    ivars->type = InStream_Read_C32(instream);
+    if (ivars->type == SortRule_FIELD) {
+        ivars->field = Freezer_read_charbuf(instream);
     }
-    self->reverse = InStream_Read_C32(instream);
+    ivars->reverse = InStream_Read_C32(instream);
     return self;
 }
 
 void
 SortRule_serialize(SortRule *self, OutStream *target) {
-    OutStream_Write_C32(target, self->type);
-    if (self->type == SortRule_FIELD) {
-        Freezer_serialize_charbuf(self->field, target);
+    SortRuleIVARS *ivars = SortRule_IVARS(self);
+    OutStream_Write_C32(target, ivars->type);
+    if (ivars->type == SortRule_FIELD) {
+        Freezer_serialize_charbuf(ivars->field, target);
     }
-    OutStream_Write_C32(target, !!self->reverse);
+    OutStream_Write_C32(target, !!ivars->reverse);
 }
 
 CharBuf*
 SortRule_get_field(SortRule *self) {
-    return self->field;
+    return SortRule_IVARS(self)->field;
 }
 
 int32_t
 SortRule_get_type(SortRule *self) {
-    return self->type;
+    return SortRule_IVARS(self)->type;
 }
 
 bool
 SortRule_get_reverse(SortRule *self) {
-    return self->reverse;
+    return SortRule_IVARS(self)->reverse;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/SortSpec.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/SortSpec.c b/core/Lucy/Search/SortSpec.c
index 9165a27..7d5f523 100644
--- a/core/Lucy/Search/SortSpec.c
+++ b/core/Lucy/Search/SortSpec.c
@@ -35,7 +35,8 @@ SortSpec_new(VArray *rules) {
 
 SortSpec*
 SortSpec_init(SortSpec *self, VArray *rules) {
-    self->rules = VA_Shallow_Copy(rules);
+    SortSpecIVARS *const ivars = SortSpec_IVARS(self);
+    ivars->rules = VA_Shallow_Copy(rules);
     for (int32_t i = 0, max = VA_Get_Size(rules); i < max; i++) {
         SortRule *rule = (SortRule*)VA_Fetch(rules, i);
         CERTIFY(rule, SORTRULE);
@@ -45,7 +46,8 @@ SortSpec_init(SortSpec *self, VArray *rules) {
 
 void
 SortSpec_destroy(SortSpec *self) {
-    DECREF(self->rules);
+    SortSpecIVARS *const ivars = SortSpec_IVARS(self);
+    DECREF(ivars->rules);
     SUPER_DESTROY(self, SORTSPEC);
 }
 
@@ -67,15 +69,16 @@ SortSpec_deserialize(SortSpec *self, InStream *instream) {
 
 VArray*
 SortSpec_get_rules(SortSpec *self) {
-    return self->rules;
+    return SortSpec_IVARS(self)->rules;
 }
 
 void
 SortSpec_serialize(SortSpec *self, OutStream *target) {
-    uint32_t num_rules = VA_Get_Size(self->rules);
+    SortSpecIVARS *const ivars = SortSpec_IVARS(self);
+    uint32_t num_rules = VA_Get_Size(ivars->rules);
     OutStream_Write_C32(target, num_rules);
     for (uint32_t i = 0; i < num_rules; i++) {
-        SortRule *rule = (SortRule*)VA_Fetch(self->rules, i);
+        SortRule *rule = (SortRule*)VA_Fetch(ivars->rules, i);
         SortRule_Serialize(rule, target);
     }
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/Span.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/Span.c b/core/Lucy/Search/Span.c
index f4d65f9..a7b06d9 100644
--- a/core/Lucy/Search/Span.c
+++ b/core/Lucy/Search/Span.c
@@ -28,58 +28,62 @@ Span_new(int32_t offset, int32_t length, float weight) {
 Span*
 Span_init(Span *self, int32_t offset, int32_t length,
           float weight) {
-    self->offset   = offset;
-    self->length   = length;
-    self->weight   = weight;
+    SpanIVARS *const ivars = Span_IVARS(self);
+    ivars->offset   = offset;
+    ivars->length   = length;
+    ivars->weight   = weight;
     return self;
 }
 
 int32_t
 Span_get_offset(Span *self) {
-    return self->offset;
+    return Span_IVARS(self)->offset;
 }
 
 int32_t
 Span_get_length(Span *self) {
-    return self->length;
+    return Span_IVARS(self)->length;
 }
 
 float
 Span_get_weight(Span *self) {
-    return self->weight;
+    return Span_IVARS(self)->weight;
 }
 
 void
 Span_set_offset(Span *self, int32_t offset) {
-    self->offset = offset;
+    Span_IVARS(self)->offset = offset;
 }
 
 void
 Span_set_length(Span *self, int32_t length) {
-    self->length = length;
+    Span_IVARS(self)->length = length;
 }
 
 void
 Span_set_weight(Span *self, float weight) {
-    self->weight = weight;
+    Span_IVARS(self)->weight = weight;
 }
 
 bool
 Span_equals(Span *self, Obj *other) {
-    Span *twin = (Span*)other;
-    if (self == twin)                 { return true; }
+    if (self == (Span*)other)         { return true; }
     if (!Obj_Is_A(other, SPAN))       { return false; }
-    if (self->offset != twin->offset) { return false; }
-    if (self->length != twin->length) { return false; }
-    if (self->weight != twin->weight) { return false; }
+    SpanIVARS *const ivars = Span_IVARS(self);
+    SpanIVARS *const ovars = Span_IVARS((Span*)other);
+    if (ivars->offset != ovars->offset) { return false; }
+    if (ivars->length != ovars->length) { return false; }
+    if (ivars->weight != ovars->weight) { return false; }
     return true;
 }
 
 int32_t
 Span_compare_to(Span *self, Obj *other) {
-    Span *competitor = (Span*)CERTIFY(other, SPAN);
-    int32_t comparison = self->offset - competitor->offset;
-    if (comparison == 0) { comparison = self->length - competitor->length; }
+    CERTIFY(other, SPAN);
+    SpanIVARS *const ivars = Span_IVARS(self);
+    SpanIVARS *const ovars = Span_IVARS((Span*)other);
+    int32_t comparison = ivars->offset - ovars->offset;
+    if (comparison == 0) { comparison = ivars->length - ovars->length; }
     return comparison;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/TermMatcher.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/TermMatcher.c b/core/Lucy/Search/TermMatcher.c
index e5fc865..0d30fd6 100644
--- a/core/Lucy/Search/TermMatcher.c
+++ b/core/Lucy/Search/TermMatcher.c
@@ -27,40 +27,43 @@ TermMatcher*
 TermMatcher_init(TermMatcher *self, Similarity *similarity, PostingList *plist,
                  Compiler *compiler) {
     Matcher_init((Matcher*)self);
+    TermMatcherIVARS *const ivars = TermMatcher_IVARS(self);
 
     // Assign.
-    self->sim           = (Similarity*)INCREF(similarity);
-    self->plist         = (PostingList*)INCREF(plist);
-    self->compiler      = (Compiler*)INCREF(compiler);
-    self->weight        = Compiler_Get_Weight(compiler);
+    ivars->sim           = (Similarity*)INCREF(similarity);
+    ivars->plist         = (PostingList*)INCREF(plist);
+    ivars->compiler      = (Compiler*)INCREF(compiler);
+    ivars->weight        = Compiler_Get_Weight(compiler);
 
     // Init.
-    self->posting        = NULL;
+    ivars->posting        = NULL;
 
     return self;
 }
 
 void
 TermMatcher_destroy(TermMatcher *self) {
-    DECREF(self->sim);
-    DECREF(self->plist);
-    DECREF(self->compiler);
+    TermMatcherIVARS *const ivars = TermMatcher_IVARS(self);
+    DECREF(ivars->sim);
+    DECREF(ivars->plist);
+    DECREF(ivars->compiler);
     SUPER_DESTROY(self, TERMMATCHER);
 }
 
 int32_t
 TermMatcher_next(TermMatcher* self) {
-    PostingList *const plist = self->plist;
+    TermMatcherIVARS *const ivars = TermMatcher_IVARS(self);
+    PostingList *const plist = ivars->plist;
     if (plist) {
         int32_t doc_id = PList_Next(plist);
         if (doc_id) {
-            self->posting = PList_Get_Posting(plist);
+            ivars->posting = PList_Get_Posting(plist);
             return doc_id;
         }
         else {
             // Reclaim resources a little early.
             DECREF(plist);
-            self->plist = NULL;
+            ivars->plist = NULL;
             return 0;
         }
     }
@@ -69,17 +72,18 @@ TermMatcher_next(TermMatcher* self) {
 
 int32_t
 TermMatcher_advance(TermMatcher *self, int32_t target) {
-    PostingList *const plist = self->plist;
+    TermMatcherIVARS *const ivars = TermMatcher_IVARS(self);
+    PostingList *const plist = ivars->plist;
     if (plist) {
         int32_t doc_id = PList_Advance(plist, target);
         if (doc_id) {
-            self->posting = PList_Get_Posting(plist);
+            ivars->posting = PList_Get_Posting(plist);
             return doc_id;
         }
         else {
             // Reclaim resources a little early.
             DECREF(plist);
-            self->plist = NULL;
+            ivars->plist = NULL;
             return 0;
         }
     }
@@ -88,7 +92,8 @@ TermMatcher_advance(TermMatcher *self, int32_t target) {
 
 int32_t
 TermMatcher_get_doc_id(TermMatcher* self) {
-    return Post_Get_Doc_ID(self->posting);
+    TermMatcherIVARS *const ivars = TermMatcher_IVARS(self);
+    return Post_Get_Doc_ID(ivars->posting);
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/TermQuery.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/TermQuery.c b/core/Lucy/Search/TermQuery.c
index e296080..924e13f 100644
--- a/core/Lucy/Search/TermQuery.c
+++ b/core/Lucy/Search/TermQuery.c
@@ -43,58 +43,64 @@ TermQuery_new(const CharBuf *field, const Obj *term) {
 TermQuery*
 TermQuery_init(TermQuery *self, const CharBuf *field, const Obj *term) {
     Query_init((Query*)self, 1.0f);
-    self->field       = CB_Clone(field);
-    self->term        = Obj_Clone(term);
+    TermQueryIVARS *const ivars = TermQuery_IVARS(self);
+    ivars->field  = CB_Clone(field);
+    ivars->term   = Obj_Clone(term);
     return self;
 }
 
 void
 TermQuery_destroy(TermQuery *self) {
-    DECREF(self->field);
-    DECREF(self->term);
+    TermQueryIVARS *const ivars = TermQuery_IVARS(self);
+    DECREF(ivars->field);
+    DECREF(ivars->term);
     SUPER_DESTROY(self, TERMQUERY);
 }
 
 void
 TermQuery_serialize(TermQuery *self, OutStream *outstream) {
-    Freezer_serialize_charbuf(self->field, outstream);
-    FREEZE(self->term, outstream);
-    OutStream_Write_F32(outstream, self->boost);
+    TermQueryIVARS *const ivars = TermQuery_IVARS(self);
+    Freezer_serialize_charbuf(ivars->field, outstream);
+    FREEZE(ivars->term, outstream);
+    OutStream_Write_F32(outstream, ivars->boost);
 }
 
 TermQuery*
 TermQuery_deserialize(TermQuery *self, InStream *instream) {
-    self->field = Freezer_read_charbuf(instream);
-    self->term  = (Obj*)THAW(instream);
-    self->boost = InStream_Read_F32(instream);
+    TermQueryIVARS *const ivars = TermQuery_IVARS(self);
+    ivars->field = Freezer_read_charbuf(instream);
+    ivars->term  = (Obj*)THAW(instream);
+    ivars->boost = InStream_Read_F32(instream);
     return self;
 }
 
 CharBuf*
 TermQuery_get_field(TermQuery *self) {
-    return self->field;
+    return TermQuery_IVARS(self)->field;
 }
 
 Obj*
 TermQuery_get_term(TermQuery *self) {
-    return self->term;
+    return TermQuery_IVARS(self)->term;
 }
 
 bool
 TermQuery_equals(TermQuery *self, Obj *other) {
-    TermQuery *twin = (TermQuery*)other;
-    if (twin == self)                               { return true; }
-    if (!Obj_Is_A(other, TERMQUERY))                { return false; }
-    if (self->boost != twin->boost)                 { return false; }
-    if (!CB_Equals(self->field, (Obj*)twin->field)) { return false; }
-    if (!Obj_Equals(self->term, twin->term))        { return false; }
+    if ((TermQuery*)other == self)                    { return true; }
+    if (!Obj_Is_A(other, TERMQUERY))                  { return false; }
+    TermQueryIVARS *const ivars = TermQuery_IVARS(self);
+    TermQueryIVARS *const ovars = TermQuery_IVARS((TermQuery*)other);
+    if (ivars->boost != ovars->boost)                 { return false; }
+    if (!CB_Equals(ivars->field, (Obj*)ovars->field)) { return false; }
+    if (!Obj_Equals(ivars->term, ovars->term))        { return false; }
     return true;
 }
 
 CharBuf*
 TermQuery_to_string(TermQuery *self) {
-    CharBuf *term_str = Obj_To_String(self->term);
-    CharBuf *retval = CB_newf("%o:%o", self->field, term_str);
+    TermQueryIVARS *const ivars = TermQuery_IVARS(self);
+    CharBuf *term_str = Obj_To_String(ivars->term);
+    CharBuf *retval = CB_newf("%o:%o", ivars->field, term_str);
     DECREF(term_str);
     return retval;
 }
@@ -121,23 +127,24 @@ TermCompiler_new(Query *parent, Searcher *searcher, float boost) {
 TermCompiler*
 TermCompiler_init(TermCompiler *self, Query *parent, Searcher *searcher,
                   float boost) {
+    TermCompilerIVARS *const ivars = TermCompiler_IVARS(self);
+    TermQueryIVARS *const parent_ivars = TermQuery_IVARS((TermQuery*)parent);
     Schema     *schema  = Searcher_Get_Schema(searcher);
-    TermQuery  *tparent = (TermQuery*)parent;
-    Similarity *sim     = Schema_Fetch_Sim(schema, tparent->field);
+    Similarity *sim     = Schema_Fetch_Sim(schema, parent_ivars->field);
 
     // Try harder to get a Similarity if necessary.
     if (!sim) { sim = Schema_Get_Similarity(schema); }
 
     // Init.
     Compiler_init((Compiler*)self, parent, searcher, sim, boost);
-    self->normalized_weight = 0.0f;
-    self->query_norm_factor = 0.0f;
+    ivars->normalized_weight = 0.0f;
+    ivars->query_norm_factor = 0.0f;
 
     // Derive.
     int32_t doc_max  = Searcher_Doc_Max(searcher);
-    int32_t doc_freq = Searcher_Doc_Freq(searcher, tparent->field,
-                                         tparent->term);
-    self->idf = Sim_IDF(sim, doc_freq, doc_max);
+    int32_t doc_freq = Searcher_Doc_Freq(searcher, parent_ivars->field,
+                                         parent_ivars->term);
+    ivars->idf = Sim_IDF(sim, doc_freq, doc_max);
 
     /* The score of any document is approximately equal to:
      *
@@ -150,32 +157,34 @@ TermCompiler_init(TermCompiler *self, Query *parent, Searcher *searcher,
      * tf_d and norm_d can only be added by the Matcher, since they are
      * per-document.
      */
-    self->raw_weight = self->idf * self->boost;
+    ivars->raw_weight = ivars->idf * ivars->boost;
 
     return self;
 }
 
 bool
 TermCompiler_equals(TermCompiler *self, Obj *other) {
-    TermCompiler *twin = (TermCompiler*)other;
-    if (!Compiler_equals((Compiler*)self, other))           { return false; }
-    if (!Obj_Is_A(other, TERMCOMPILER))                     { return false; }
-    if (self->idf != twin->idf)                             { return false; }
-    if (self->raw_weight != twin->raw_weight)               { return false; }
-    if (self->query_norm_factor != twin->query_norm_factor) { return false; }
-    if (self->normalized_weight != twin->normalized_weight) { return false; }
+    if (!Compiler_equals((Compiler*)self, other))             { return false; }
+    if (!Obj_Is_A(other, TERMCOMPILER))                       { return false; }
+    TermCompilerIVARS *const ivars = TermCompiler_IVARS(self);
+    TermCompilerIVARS *const ovars = TermCompiler_IVARS((TermCompiler*)other);
+    if (ivars->idf != ovars->idf)                             { return false; }
+    if (ivars->raw_weight != ovars->raw_weight)               { return false; }
+    if (ivars->query_norm_factor != ovars->query_norm_factor) { return false; }
+    if (ivars->normalized_weight != ovars->normalized_weight) { return false; }
     return true;
 }
 
 void
 TermCompiler_serialize(TermCompiler *self, OutStream *outstream) {
+    TermCompilerIVARS *const ivars = TermCompiler_IVARS(self);
     TermCompiler_Serialize_t super_serialize
         = SUPER_METHOD_PTR(TERMCOMPILER, Lucy_TermCompiler_Serialize);
     super_serialize(self, outstream);
-    OutStream_Write_F32(outstream, self->idf);
-    OutStream_Write_F32(outstream, self->raw_weight);
-    OutStream_Write_F32(outstream, self->query_norm_factor);
-    OutStream_Write_F32(outstream, self->normalized_weight);
+    OutStream_Write_F32(outstream, ivars->idf);
+    OutStream_Write_F32(outstream, ivars->raw_weight);
+    OutStream_Write_F32(outstream, ivars->query_norm_factor);
+    OutStream_Write_F32(outstream, ivars->normalized_weight);
 }
 
 TermCompiler*
@@ -183,21 +192,24 @@ TermCompiler_deserialize(TermCompiler *self, InStream *instream) {
     TermCompiler_Deserialize_t super_deserialize
         = SUPER_METHOD_PTR(TERMCOMPILER, Lucy_TermCompiler_Deserialize);
     self = super_deserialize(self, instream);
-    self->idf               = InStream_Read_F32(instream);
-    self->raw_weight        = InStream_Read_F32(instream);
-    self->query_norm_factor = InStream_Read_F32(instream);
-    self->normalized_weight = InStream_Read_F32(instream);
+    TermCompilerIVARS *const ivars = TermCompiler_IVARS(self);
+    ivars->idf               = InStream_Read_F32(instream);
+    ivars->raw_weight        = InStream_Read_F32(instream);
+    ivars->query_norm_factor = InStream_Read_F32(instream);
+    ivars->normalized_weight = InStream_Read_F32(instream);
     return self;
 }
 
 float
 TermCompiler_sum_of_squared_weights(TermCompiler *self) {
-    return self->raw_weight * self->raw_weight;
+    TermCompilerIVARS *const ivars = TermCompiler_IVARS(self);
+    return ivars->raw_weight * ivars->raw_weight;
 }
 
 void
 TermCompiler_apply_norm_factor(TermCompiler *self, float query_norm_factor) {
-    self->query_norm_factor = query_norm_factor;
+    TermCompilerIVARS *const ivars = TermCompiler_IVARS(self);
+    ivars->query_norm_factor = query_norm_factor;
 
     /* Multiply raw weight by the idf and norm_q factors in this:
      *
@@ -205,24 +217,28 @@ TermCompiler_apply_norm_factor(TermCompiler *self, float query_norm_factor) {
      *
      * Note: factoring in IDF a second time is correct.  See formula.
      */
-    self->normalized_weight
-        = self->raw_weight * self->idf * query_norm_factor;
+    ivars->normalized_weight
+        = ivars->raw_weight * ivars->idf * query_norm_factor;
 }
 
 float
 TermCompiler_get_weight(TermCompiler *self) {
-    return self->normalized_weight;
+    return TermCompiler_IVARS(self)->normalized_weight;
 }
 
 Matcher*
 TermCompiler_make_matcher(TermCompiler *self, SegReader *reader,
                           bool need_score) {
-    TermQuery *tparent = (TermQuery*)self->parent;
+    TermCompilerIVARS *const ivars = TermCompiler_IVARS(self);
+    TermQueryIVARS *const parent_ivars
+        = TermQuery_IVARS((TermQuery*)ivars->parent);
     PostingListReader *plist_reader
         = (PostingListReader*)SegReader_Fetch(
               reader, VTable_Get_Name(POSTINGLISTREADER));
     PostingList *plist = plist_reader
-                         ? PListReader_Posting_List(plist_reader, tparent->field, tparent->term)
+                         ? PListReader_Posting_List(plist_reader,
+                                                    parent_ivars->field,
+                                                    parent_ivars->term)
                          : NULL;
 
     if (plist == NULL || PList_Get_Doc_Freq(plist) == 0) {
@@ -230,7 +246,7 @@ TermCompiler_make_matcher(TermCompiler *self, SegReader *reader,
         return NULL;
     }
     else {
-        Matcher *retval = PList_Make_Matcher(plist, self->sim,
+        Matcher *retval = PList_Make_Matcher(plist, ivars->sim,
                                              (Compiler*)self, need_score);
         DECREF(plist);
         return retval;
@@ -240,16 +256,20 @@ TermCompiler_make_matcher(TermCompiler *self, SegReader *reader,
 VArray*
 TermCompiler_highlight_spans(TermCompiler *self, Searcher *searcher,
                              DocVector *doc_vec, const CharBuf *field) {
-    TermQuery *const  parent = (TermQuery*)self->parent;
-    VArray          *spans   = VA_new(0);
+
+    TermCompilerIVARS *const ivars = TermCompiler_IVARS(self);
+    TermQueryIVARS *const parent_ivars
+        = TermQuery_IVARS((TermQuery*)ivars->parent);
+    VArray *spans = VA_new(0);
     TermVector *term_vector;
     I32Array *starts, *ends;
     UNUSED_VAR(searcher);
 
-    if (!CB_Equals(parent->field, (Obj*)field)) { return spans; }
+    if (!CB_Equals(parent_ivars->field, (Obj*)field)) { return spans; }
 
     // Add all starts and ends.
-    term_vector = DocVec_Term_Vector(doc_vec, field, (CharBuf*)parent->term);
+    term_vector
+        = DocVec_Term_Vector(doc_vec, field, (CharBuf*)parent_ivars->term);
     if (!term_vector) { return spans; }
 
     starts = TV_Get_Start_Offsets(term_vector);

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/TopDocs.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/TopDocs.c b/core/Lucy/Search/TopDocs.c
index d6c770e..fcc68c5 100644
--- a/core/Lucy/Search/TopDocs.c
+++ b/core/Lucy/Search/TopDocs.c
@@ -34,48 +34,53 @@ TopDocs_new(VArray *match_docs, uint32_t total_hits) {
 
 TopDocs*
 TopDocs_init(TopDocs *self, VArray *match_docs, uint32_t total_hits) {
-    self->match_docs = (VArray*)INCREF(match_docs);
-    self->total_hits = total_hits;
+    TopDocsIVARS *const ivars = TopDocs_IVARS(self);
+    ivars->match_docs = (VArray*)INCREF(match_docs);
+    ivars->total_hits = total_hits;
     return self;
 }
 
 void
 TopDocs_destroy(TopDocs *self) {
-    DECREF(self->match_docs);
+    TopDocsIVARS *const ivars = TopDocs_IVARS(self);
+    DECREF(ivars->match_docs);
     SUPER_DESTROY(self, TOPDOCS);
 }
 
 void
 TopDocs_serialize(TopDocs *self, OutStream *outstream) {
-    Freezer_serialize_varray(self->match_docs, outstream);
-    OutStream_Write_C32(outstream, self->total_hits);
+    TopDocsIVARS *const ivars = TopDocs_IVARS(self);
+    Freezer_serialize_varray(ivars->match_docs, outstream);
+    OutStream_Write_C32(outstream, ivars->total_hits);
 }
 
 TopDocs*
 TopDocs_deserialize(TopDocs *self, InStream *instream) {
-    self->match_docs = Freezer_read_varray(instream);
-    self->total_hits = InStream_Read_C32(instream);
+    TopDocsIVARS *const ivars = TopDocs_IVARS(self);
+    ivars->match_docs = Freezer_read_varray(instream);
+    ivars->total_hits = InStream_Read_C32(instream);
     return self;
 }
 
 VArray*
 TopDocs_get_match_docs(TopDocs *self) {
-    return self->match_docs;
+    return TopDocs_IVARS(self)->match_docs;
 }
 
 uint32_t
 TopDocs_get_total_hits(TopDocs *self) {
-    return self->total_hits;
+    return TopDocs_IVARS(self)->total_hits;
 }
 
 void
 TopDocs_set_match_docs(TopDocs *self, VArray *match_docs) {
-    DECREF(self->match_docs);
-    self->match_docs = (VArray*)INCREF(match_docs);
+    TopDocsIVARS *const ivars = TopDocs_IVARS(self);
+    DECREF(ivars->match_docs);
+    ivars->match_docs = (VArray*)INCREF(match_docs);
 }
 void
 TopDocs_set_total_hits(TopDocs *self, uint32_t total_hits) {
-    self->total_hits = total_hits;
+    TopDocs_IVARS(self)->total_hits = total_hits;
 }
 
 


[lucy-commits] [29/34] git commit: refs/heads/master - Cache some IVARS symbols within CFCClass.

Posted by ma...@apache.org.
Cache some IVARS symbols within CFCClass.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/a266a932
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/a266a932
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/a266a932

Branch: refs/heads/master
Commit: a266a932eff495fb2bab9f96406dca3be04ac339
Parents: bef4852
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Sat Jul 13 16:16:48 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 16:08:44 2013 -0700

----------------------------------------------------------------------
 clownfish/compiler/src/CFCBindClass.c |  6 ++--
 clownfish/compiler/src/CFCClass.c     | 47 +++++++++++++++++++++++-------
 clownfish/compiler/src/CFCClass.h     | 25 ++++++++++++++--
 3 files changed, 62 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/a266a932/clownfish/compiler/src/CFCBindClass.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCBindClass.c b/clownfish/compiler/src/CFCBindClass.c
index 452b58f..e63b9d4 100644
--- a/clownfish/compiler/src/CFCBindClass.c
+++ b/clownfish/compiler/src/CFCBindClass.c
@@ -154,8 +154,8 @@ S_to_c_header_inert(CFCBindClass *self) {
 static char*
 S_ivars_hack(CFCBindClass *self) {
     const char *full_struct = CFCClass_full_struct_sym(self->client);
-    const char *full_ivars  = CFCClass_full_ivars_name(self->client);
-    const char *short_ivars = CFCClass_short_ivars_name(self->client);
+    const char *full_ivars  = CFCClass_full_ivars_struct(self->client);
+    const char *short_ivars = CFCClass_short_ivars_struct(self->client);
     const char *prefix      = CFCClass_get_prefix(self->client);
     const char *PREFIX      = CFCClass_get_PREFIX(self->client);
     const char *class_cnick = CFCClass_get_cnick(self->client);
@@ -367,7 +367,7 @@ S_struct_definition(CFCBindClass *self) {
         struct_sym = CFCClass_full_struct_sym(self->client);
     }
     else {
-        struct_sym = CFCClass_full_ivars_name(self->client);
+        struct_sym = CFCClass_full_ivars_struct(self->client);
     }
 
     CFCVariable **member_vars = CFCClass_member_vars(self->client);

http://git-wip-us.apache.org/repos/asf/lucy/blob/a266a932/clownfish/compiler/src/CFCClass.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCClass.c b/clownfish/compiler/src/CFCClass.c
index 790fd72..ea316cf 100644
--- a/clownfish/compiler/src/CFCClass.c
+++ b/clownfish/compiler/src/CFCClass.c
@@ -77,8 +77,11 @@ struct CFCClass {
     int is_inert;
     char *struct_sym;
     char *full_struct_sym;
-    char *ivars_name;
-    char *full_ivars_name;
+    char *ivars_struct;
+    char *full_ivars_struct;
+    char *ivars_func;
+    char *full_ivars_func;
+    char *full_ivars_offset;
     char *short_vtable_var;
     char *full_vtable_var;
     char *privacy_symbol;
@@ -175,9 +178,13 @@ CFCClass_do_create(CFCClass *self, struct CFCParcel *parcel,
         self->short_vtable_var[i] = toupper(self->struct_sym[i]);
     }
     self->short_vtable_var[struct_sym_len] = '\0';
-    self->full_struct_sym = CFCUtil_sprintf("%s%s", prefix, self->struct_sym);
-    self->ivars_name      = CFCUtil_sprintf("%sIVARS", self->struct_sym);
-    self->full_ivars_name = CFCUtil_sprintf("%sIVARS", self->full_struct_sym);
+    self->full_struct_sym   = CFCUtil_sprintf("%s%s", prefix, self->struct_sym);
+    self->ivars_struct      = CFCUtil_sprintf("%sIVARS", self->struct_sym);
+    self->full_ivars_struct = CFCUtil_sprintf("%sIVARS", self->full_struct_sym);
+    self->ivars_func        = CFCUtil_sprintf("%s_IVARS", CFCClass_get_cnick(self));
+    self->full_ivars_func   = CFCUtil_sprintf("%s%s_IVARS", prefix,
+                                              CFCClass_get_cnick(self));
+    self->full_ivars_offset = CFCUtil_sprintf("%s_OFFSET", self->full_ivars_func);
     size_t full_struct_sym_len = strlen(self->full_struct_sym);
     self->full_vtable_var = (char*)MALLOCATE(full_struct_sym_len + 1);
     for (i = 0; self->full_struct_sym[i] != '\0'; i++) {
@@ -254,8 +261,11 @@ CFCClass_destroy(CFCClass *self) {
     FREEMEM(self->autocode);
     FREEMEM(self->parent_class_name);
     FREEMEM(self->struct_sym);
-    FREEMEM(self->ivars_name);
-    FREEMEM(self->full_ivars_name);
+    FREEMEM(self->ivars_struct);
+    FREEMEM(self->full_ivars_struct);
+    FREEMEM(self->ivars_func);
+    FREEMEM(self->full_ivars_func);
+    FREEMEM(self->full_ivars_offset);
     FREEMEM(self->short_vtable_var);
     FREEMEM(self->full_struct_sym);
     FREEMEM(self->full_vtable_var);
@@ -829,13 +839,28 @@ CFCClass_full_struct_sym(CFCClass *self) {
 }
 
 const char*
-CFCClass_short_ivars_name(CFCClass *self) {
-    return self->ivars_name;
+CFCClass_short_ivars_struct(CFCClass *self) {
+    return self->ivars_struct;
 }
 
 const char*
-CFCClass_full_ivars_name(CFCClass *self) {
-    return self->full_ivars_name;
+CFCClass_full_ivars_struct(CFCClass *self) {
+    return self->full_ivars_struct;
+}
+
+const char*
+CFCClass_short_ivars_func(CFCClass *self) {
+    return self->ivars_func;
+}
+
+const char*
+CFCClass_full_ivars_func(CFCClass *self) {
+    return self->full_ivars_func;
+}
+
+const char*
+CFCClass_full_ivars_offset(CFCClass *self) {
+    return self->full_ivars_offset;
 }
 
 const char*

http://git-wip-us.apache.org/repos/asf/lucy/blob/a266a932/clownfish/compiler/src/CFCClass.h
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCClass.h b/clownfish/compiler/src/CFCClass.h
index d45e883..3d4d680 100644
--- a/clownfish/compiler/src/CFCClass.h
+++ b/clownfish/compiler/src/CFCClass.h
@@ -246,11 +246,32 @@ CFCClass_get_struct_sym(CFCClass *self);
 const char*
 CFCClass_full_struct_sym(CFCClass *self);
 
+/** IVARS struct name, not including parcel prefix.
+ */
+const char*
+CFCClass_short_ivars_struct(CFCClass *self);
+
+/** Fully qualified IVARS struct name including parcel prefix.
+ */
 const char*
-CFCClass_short_ivars_name(CFCClass *self);
+CFCClass_full_ivars_struct(CFCClass *self);
 
+/** Name of the function used to access IVARS, not including parcel prefix.
+ */
+const char*
+CFCClass_short_ivars_func(CFCClass *self);
+
+/** Fully qualified name of the function used to access IVARS including parcel
+ * prefix.
+ */
+const char*
+CFCClass_full_ivars_func(CFCClass *self);
+
+/** Fully qualified name of the offset variable at which the IVARS may be
+ * found, including parcel prefix.
+ */
 const char*
-CFCClass_full_ivars_name(CFCClass *self);
+CFCClass_full_ivars_offset(CFCClass *self);
 
 /** The short name of the global VTable object for this class.
  */


[lucy-commits] [30/34] git commit: refs/heads/master - Limit IVARS structs to members in this parcel.

Posted by ma...@apache.org.
Limit IVARS structs to members in this parcel.

Remove member variables declared in classes from other parcels from the
IVARS structs.  Modify IVARS_OFFSET variables to be non-zero, finishing
the implementation.

Add a dynamically assigned integer parcel_id to VTable which is used to
differentiate which classes belong to different parcels.  At some point
this might be superseded by an actual parcel object of some kind.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/adacb96f
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/adacb96f
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/adacb96f

Branch: refs/heads/master
Commit: adacb96f420fbf2236b1f0b40071d495b46e39ce
Parents: 6450cc0
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Fri Jul 12 17:22:12 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 16:08:44 2013 -0700

----------------------------------------------------------------------
 clownfish/compiler/src/CFCBindClass.c       | 48 ++++++++++++++++--------
 clownfish/compiler/src/CFCBindCore.c        |  3 +-
 clownfish/compiler/src/CFCClass.c           |  5 +++
 clownfish/compiler/src/CFCClass.h           |  3 ++
 clownfish/runtime/core/Clownfish/VTable.c   | 43 ++++++++++++++++++++-
 clownfish/runtime/core/Clownfish/VTable.cfh |  1 +
 6 files changed, 85 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/adacb96f/clownfish/compiler/src/CFCBindClass.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCBindClass.c b/clownfish/compiler/src/CFCBindClass.c
index a431d26..8b72db1 100644
--- a/clownfish/compiler/src/CFCBindClass.c
+++ b/clownfish/compiler/src/CFCBindClass.c
@@ -26,6 +26,7 @@
 #include "CFCFunction.h"
 #include "CFCMethod.h"
 #include "CFCParamList.h"
+#include "CFCParcel.h"
 #include "CFCType.h"
 #include "CFCVariable.h"
 #include "CFCUtil.h"
@@ -378,19 +379,32 @@ CFCBindClass_to_c_data(CFCBindClass *self) {
 // Create the definition for the instantiable object struct.
 static char*
 S_struct_definition(CFCBindClass *self) {
+    CFCClass *const client = self->client;
     const char *struct_sym;
-    const char *prefix = CFCClass_get_prefix(self->client);
+    const char *prefix = CFCClass_get_prefix(client);
     if (strcmp(prefix, "cfish_") == 0) {
-        struct_sym = CFCClass_full_struct_sym(self->client);
+        struct_sym = CFCClass_full_struct_sym(client);
     }
     else {
-        struct_sym = CFCClass_full_ivars_struct(self->client);
+        struct_sym = CFCClass_full_ivars_struct(client);
     }
 
-    CFCVariable **member_vars = CFCClass_member_vars(self->client);
-    char *member_decs = CFCUtil_strdup("");
+    // Count the number of member variables declared in ancestor classes
+    // outside this package so that we can skip over them.
+    int num_non_package_members = 0;
+    CFCParcel *parcel = CFCClass_get_parcel(client);
+    CFCClass *ancestor = CFCClass_get_parent(client);
+    while (ancestor && CFCClass_get_parcel(ancestor) == parcel) {
+        ancestor = CFCClass_get_parent(ancestor);
+    }
+    if (ancestor) {
+        num_non_package_members = CFCClass_num_member_vars(ancestor);
+    }
 
-    for (int i = 0; member_vars[i] != NULL; i++) {
+    // Add all member variables declared by classes in this package.
+    CFCVariable **member_vars = CFCClass_member_vars(client);
+    char *member_decs = CFCUtil_strdup("");
+    for (int i = num_non_package_members; member_vars[i] != NULL; i++) {
         const char *member_dec = CFCVariable_local_declaration(member_vars[i]);
         size_t needed = strlen(member_decs) + strlen(member_dec) + 10;
         member_decs = (char*)REALLOCATE(member_decs, needed);
@@ -410,10 +424,12 @@ char*
 CFCBindClass_spec_def(CFCBindClass *self) {
     CFCClass *client = self->client;
 
-    CFCClass    *parent     = CFCClass_get_parent(client);
-    const char  *class_name = CFCClass_get_class_name(client);
-    const char  *vt_var     = CFCClass_full_vtable_var(client);
-    const char  *struct_sym = CFCClass_full_struct_sym(client);
+    CFCClass   *parent       = CFCClass_get_parent(client);
+    const char *class_name   = CFCClass_get_class_name(client);
+    const char *vt_var       = CFCClass_full_vtable_var(client);
+    const char *struct_sym   = CFCClass_full_struct_sym(client);
+    const char *ivars_struct = CFCClass_full_ivars_struct(client);
+    const char *prefix       = CFCClass_get_prefix(client);
 
     // Create a pointer to the parent class's vtable.
     char *parent_ref;
@@ -436,23 +452,23 @@ CFCBindClass_spec_def(CFCBindClass *self) {
     FREEMEM(fresh_methods);
     const char *ms_var = num_fresh ? self->method_specs_var : "NULL";
 
-    // Hack to get size of object.  TODO: This will have to be replaced by
-    // dynamic initialization.
-    char *ivars_or_not = strcmp(CFCClass_get_prefix(client), "cfish_") == 0
-                         ? "" : "IVARS";
+    const char *ivars_or_not = strcmp(prefix, "cfish_") == 0
+                               ? struct_sym : ivars_struct;
+    const char *ivars_offset_name = CFCClass_full_ivars_offset(client);
 
     char pattern[] =
         "    {\n"
         "        &%s, /* vtable */\n"
         "        %s, /* parent */\n"
         "        \"%s\", /* name */\n"
-        "        sizeof(%s%s), /* obj_alloc_size */\n"
+        "        sizeof(%s), /* ivars_size */\n"
+        "        &%s, /* ivars_offset_ptr */\n"
         "        %d, /* num_fresh */\n"
         "        %d, /* num_novel */\n"
         "        %s /* method_specs */\n"
         "    }";
     char *code = CFCUtil_sprintf(pattern, vt_var, parent_ref, class_name,
-                                 struct_sym, ivars_or_not,
+                                 ivars_or_not, ivars_offset_name,
                                  num_fresh, num_novel, ms_var);
 
     FREEMEM(parent_ref);

http://git-wip-us.apache.org/repos/asf/lucy/blob/adacb96f/clownfish/compiler/src/CFCBindCore.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCBindCore.c b/clownfish/compiler/src/CFCBindCore.c
index 91721a2..7abc4c2 100644
--- a/clownfish/compiler/src/CFCBindCore.c
+++ b/clownfish/compiler/src/CFCBindCore.c
@@ -235,7 +235,8 @@ S_write_parcel_h(CFCBindCore *self, CFCParcel *parcel) {
         "    cfish_VTable     **vtable;\n"
         "    cfish_VTable     **parent;\n"
         "    const char        *name;\n"
-        "    size_t             obj_alloc_size;\n"
+        "    size_t             ivars_size;\n"
+        "    size_t            *ivars_offset_ptr;\n"
         "    size_t             num_fresh;\n"
         "    size_t             num_novel;\n"
         "    cfish_MethodSpec  *method_specs;\n"

http://git-wip-us.apache.org/repos/asf/lucy/blob/adacb96f/clownfish/compiler/src/CFCClass.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCClass.c b/clownfish/compiler/src/CFCClass.c
index ea316cf..79c1ec6 100644
--- a/clownfish/compiler/src/CFCClass.c
+++ b/clownfish/compiler/src/CFCClass.c
@@ -769,6 +769,11 @@ CFCClass_member_vars(CFCClass *self) {
     return self->member_vars;
 }
 
+size_t
+CFCClass_num_member_vars(CFCClass *self) {
+    return self->num_member_vars;
+}
+
 CFCVariable**
 CFCClass_inert_vars(CFCClass *self) {
     return self->inert_vars;

http://git-wip-us.apache.org/repos/asf/lucy/blob/adacb96f/clownfish/compiler/src/CFCClass.h
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCClass.h b/clownfish/compiler/src/CFCClass.h
index 3d4d680..e247e3d 100644
--- a/clownfish/compiler/src/CFCClass.h
+++ b/clownfish/compiler/src/CFCClass.h
@@ -199,6 +199,9 @@ CFCClass_num_methods(CFCClass *self);
 struct CFCVariable**
 CFCClass_member_vars(CFCClass *self);
 
+size_t
+CFCClass_num_member_vars(CFCClass *self);
+
 /** Return an array of all inert (shared, class) variables.
  */
 struct CFCVariable**

http://git-wip-us.apache.org/repos/asf/lucy/blob/adacb96f/clownfish/runtime/core/Clownfish/VTable.c
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/VTable.c b/clownfish/runtime/core/Clownfish/VTable.c
index f278527..268664c 100644
--- a/clownfish/runtime/core/Clownfish/VTable.c
+++ b/clownfish/runtime/core/Clownfish/VTable.c
@@ -46,20 +46,42 @@ S_scrunch_charbuf(CharBuf *source, CharBuf *target);
 static Method*
 S_find_method(VTable *self, const char *meth_name);
 
+static int32_t
+S_claim_parcel_id(void);
+
 LockFreeRegistry *VTable_registry = NULL;
 
 void
 VTable_bootstrap(VTableSpec *specs, size_t num_specs)
 {
+    int32_t parcel_id = S_claim_parcel_id();
+
     /* Pass 1:
+     * - Initialize IVARS_OFFSET.
      * - Allocate memory.
      * - Initialize parent, flags, obj_alloc_size, vt_alloc_size.
+     * - Assign parcel_id.
      * - Initialize method pointers.
      */
     for (size_t i = 0; i < num_specs; ++i) {
         VTableSpec *spec   = &specs[i];
         VTable     *parent = spec->parent ? *spec->parent : NULL;
 
+        size_t ivars_offset = 0;
+        if (spec->ivars_offset_ptr != NULL) {
+            if (parent) {
+                VTable *ancestor = parent;
+                while (ancestor && ancestor->parcel_id == parcel_id) {
+                    ancestor = ancestor->parent;
+                }
+                ivars_offset = ancestor ? ancestor->obj_alloc_size : 0;
+                *spec->ivars_offset_ptr = ivars_offset;
+            }
+            else {
+                *spec->ivars_offset_ptr = 0;
+            }
+        }
+
         size_t vt_alloc_size = parent
                                ? parent->vt_alloc_size
                                : offsetof(VTable, method_ptrs);
@@ -67,8 +89,9 @@ VTable_bootstrap(VTableSpec *specs, size_t num_specs)
         VTable *vtable = (VTable*)Memory_wrapped_calloc(vt_alloc_size, 1);
 
         vtable->parent         = parent;
+        vtable->parcel_id      = parcel_id;
         vtable->flags          = 0;
-        vtable->obj_alloc_size = spec->obj_alloc_size;
+        vtable->obj_alloc_size = ivars_offset + spec->ivars_size;
         vtable->vt_alloc_size  = vt_alloc_size;
 
         if (parent) {
@@ -392,4 +415,22 @@ S_find_method(VTable *self, const char *name) {
     return NULL;
 }
 
+static size_t parcel_count;
+
+static int32_t
+S_claim_parcel_id(void) {
+    // TODO: use ordinary cas rather than cas_ptr.
+    union { size_t num; void *ptr; } old_value;
+    union { size_t num; void *ptr; } new_value;
+
+    bool succeeded = false;
+    do {
+        old_value.num = parcel_count;
+        new_value.num = old_value.num + 1;
+        succeeded = Atomic_cas_ptr((void*volatile*)&parcel_count,
+                                   old_value.ptr, new_value.ptr);
+    } while (!succeeded);
+
+    return new_value.num;
+}
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/adacb96f/clownfish/runtime/core/Clownfish/VTable.cfh
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/VTable.cfh b/clownfish/runtime/core/Clownfish/VTable.cfh
index 3c19d37..6d62f44 100644
--- a/clownfish/runtime/core/Clownfish/VTable.cfh
+++ b/clownfish/runtime/core/Clownfish/VTable.cfh
@@ -28,6 +28,7 @@ class Clownfish::VTable inherits Clownfish::Obj {
     VTable            *parent;
     CharBuf           *name;
     uint32_t           flags;
+    int32_t            parcel_id;
     size_t             obj_alloc_size;
     size_t             vt_alloc_size;
     VArray            *methods;


[lucy-commits] [17/34] git commit: refs/heads/master - Migrate Lucy's store classes to IVARS.

Posted by ma...@apache.org.
Migrate Lucy's store classes to IVARS.

Change all Lucy's store classes to access instance vars via an IVARS
struct rather than via `self`.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/d04580a1
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/d04580a1
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/d04580a1

Branch: refs/heads/master
Commit: d04580a14c75c2fc4fa2eb684f13069607dbffe1
Parents: 474e8b4
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Fri Jun 28 14:07:41 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 16:08:42 2013 -0700

----------------------------------------------------------------------
 core/Lucy/Store/CompoundFileReader.c | 142 ++++++++++++---------
 core/Lucy/Store/CompoundFileWriter.c |  35 +++---
 core/Lucy/Store/DirHandle.c          |  14 ++-
 core/Lucy/Store/FSDirHandle.c        | 121 ++++++++++--------
 core/Lucy/Store/FSFileHandle.c       | 197 ++++++++++++++++-------------
 core/Lucy/Store/FSFolder.c           |  34 +++--
 core/Lucy/Store/FileHandle.c         |  13 +-
 core/Lucy/Store/FileWindow.c         |  16 +--
 core/Lucy/Store/Folder.c             |  27 ++--
 core/Lucy/Store/InStream.c           | 202 +++++++++++++++++-------------
 core/Lucy/Store/Lock.c               |  91 ++++++++------
 core/Lucy/Store/LockFactory.c        |  16 ++-
 core/Lucy/Store/OutStream.c          | 155 +++++++++++++----------
 core/Lucy/Store/RAMDirHandle.c       |  40 +++---
 core/Lucy/Store/RAMFile.c            |  14 ++-
 core/Lucy/Store/RAMFileHandle.c      |  52 ++++----
 core/Lucy/Store/RAMFileHandle.cfh    |   1 +
 core/Lucy/Store/RAMFolder.c          |  50 +++++---
 core/Lucy/Store/SharedLock.c         |  45 ++++---
 19 files changed, 715 insertions(+), 550 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/d04580a1/core/Lucy/Store/CompoundFileReader.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/CompoundFileReader.c b/core/Lucy/Store/CompoundFileReader.c
index 21e08a8..c519498 100644
--- a/core/Lucy/Store/CompoundFileReader.c
+++ b/core/Lucy/Store/CompoundFileReader.c
@@ -35,6 +35,7 @@ CFReader_open(Folder *folder) {
 
 CompoundFileReader*
 CFReader_do_open(CompoundFileReader *self, Folder *folder) {
+    CompoundFileReaderIVARS *const ivars = CFReader_IVARS(self);
     CharBuf *cfmeta_file = (CharBuf*)ZCB_WRAP_STR("cfmeta.json", 11);
     Hash *metadata = (Hash*)Json_slurp_json((Folder*)folder, cfmeta_file);
     Err *error = NULL;
@@ -48,18 +49,18 @@ CFReader_do_open(CompoundFileReader *self, Folder *folder) {
     }
     else {
         Obj *format = Hash_Fetch_Str(metadata, "format", 6);
-        self->format = format ? (int32_t)Obj_To_I64(format) : 0;
-        self->records = (Hash*)INCREF(Hash_Fetch_Str(metadata, "files", 5));
-        if (self->format < 1) {
+        ivars->format = format ? (int32_t)Obj_To_I64(format) : 0;
+        ivars->records = (Hash*)INCREF(Hash_Fetch_Str(metadata, "files", 5));
+        if (ivars->format < 1) {
             error = Err_new(CB_newf("Corrupt %o file: Missing or invalid 'format'",
                                     cfmeta_file));
         }
-        else if (self->format > CFWriter_current_file_format) {
+        else if (ivars->format > CFWriter_current_file_format) {
             error = Err_new(CB_newf("Unsupported compound file format: %i32 "
-                                    "(current = %i32", self->format,
+                                    "(current = %i32", ivars->format,
                                     CFWriter_current_file_format));
         }
-        else if (!self->records) {
+        else if (!ivars->records) {
             error = Err_new(CB_newf("Corrupt %o file: missing 'files' key",
                                     cfmeta_file));
         }
@@ -73,19 +74,19 @@ CFReader_do_open(CompoundFileReader *self, Folder *folder) {
 
     // Open an instream which we'll clone over and over.
     CharBuf *cf_file = (CharBuf*)ZCB_WRAP_STR("cf.dat", 6);
-    self->instream = Folder_Open_In(folder, cf_file);
-    if (!self->instream) {
+    ivars->instream = Folder_Open_In(folder, cf_file);
+    if (!ivars->instream) {
         ERR_ADD_FRAME(Err_get_error());
         DECREF(self);
         return NULL;
     }
 
     // Assign.
-    self->real_folder = (Folder*)INCREF(folder);
+    ivars->real_folder = (Folder*)INCREF(folder);
 
     // Strip directory name from filepaths for old format.
-    if (self->format == 1) {
-        VArray *files = Hash_Keys(self->records);
+    if (ivars->format == 1) {
+        VArray *files = Hash_Keys(ivars->records);
         ZombieCharBuf *filename = ZCB_BLANK();
         ZombieCharBuf *folder_name
             = IxFileNames_local_part(Folder_Get_Path(folder), ZCB_BLANK());
@@ -94,10 +95,10 @@ CFReader_do_open(CompoundFileReader *self, Folder *folder) {
         for (uint32_t i = 0, max = VA_Get_Size(files); i < max; i++) {
             CharBuf *orig = (CharBuf*)VA_Fetch(files, i);
             if (CB_Starts_With(orig, (CharBuf*)folder_name)) {
-                Obj *record = Hash_Delete(self->records, (Obj*)orig);
+                Obj *record = Hash_Delete(ivars->records, (Obj*)orig);
                 ZCB_Assign(filename, orig);
                 ZCB_Nip(filename, folder_name_len + sizeof(DIR_SEP) - 1);
-                Hash_Store(self->records, (Obj*)filename, (Obj*)record);
+                Hash_Store(ivars->records, (Obj*)filename, (Obj*)record);
             }
         }
 
@@ -109,35 +110,38 @@ CFReader_do_open(CompoundFileReader *self, Folder *folder) {
 
 void
 CFReader_destroy(CompoundFileReader *self) {
-    DECREF(self->real_folder);
-    DECREF(self->instream);
-    DECREF(self->records);
+    CompoundFileReaderIVARS *const ivars = CFReader_IVARS(self);
+    DECREF(ivars->real_folder);
+    DECREF(ivars->instream);
+    DECREF(ivars->records);
     SUPER_DESTROY(self, COMPOUNDFILEREADER);
 }
 
 Folder*
 CFReader_get_real_folder(CompoundFileReader *self) {
-    return self->real_folder;
+    return CFReader_IVARS(self)->real_folder;
 }
 
 void
 CFReader_set_path(CompoundFileReader *self, const CharBuf *path) {
-    Folder_Set_Path(self->real_folder, path);
+    CompoundFileReaderIVARS *const ivars = CFReader_IVARS(self);
+    Folder_Set_Path(ivars->real_folder, path);
     Folder_set_path((Folder*)self, path);
 }
 
 FileHandle*
 CFReader_local_open_filehandle(CompoundFileReader *self,
                                const CharBuf *name, uint32_t flags) {
-    Hash *entry = (Hash*)Hash_Fetch(self->records, (Obj*)name);
+    CompoundFileReaderIVARS *const ivars = CFReader_IVARS(self);
+    Hash *entry = (Hash*)Hash_Fetch(ivars->records, (Obj*)name);
     FileHandle *fh = NULL;
 
     if (entry) {
         Err_set_error(Err_new(CB_newf("Can't open FileHandle for virtual file %o in '%o'",
-                                      name, self->path)));
+                                      name, ivars->path)));
     }
     else {
-        fh = Folder_Local_Open_FileHandle(self->real_folder, name, flags);
+        fh = Folder_Local_Open_FileHandle(ivars->real_folder, name, flags);
         if (!fh) {
             ERR_ADD_FRAME(Err_get_error());
         }
@@ -148,22 +152,23 @@ CFReader_local_open_filehandle(CompoundFileReader *self,
 
 bool
 CFReader_local_delete(CompoundFileReader *self, const CharBuf *name) {
-    Hash *record = (Hash*)Hash_Delete(self->records, (Obj*)name);
+    CompoundFileReaderIVARS *const ivars = CFReader_IVARS(self);
+    Hash *record = (Hash*)Hash_Delete(ivars->records, (Obj*)name);
     DECREF(record);
 
     if (record == NULL) {
-        return Folder_Local_Delete(self->real_folder, name);
+        return Folder_Local_Delete(ivars->real_folder, name);
     }
     else {
         // Once the number of virtual files falls to 0, remove the compound
         // files.
-        if (Hash_Get_Size(self->records) == 0) {
+        if (Hash_Get_Size(ivars->records) == 0) {
             CharBuf *cf_file = (CharBuf*)ZCB_WRAP_STR("cf.dat", 6);
-            if (!Folder_Delete(self->real_folder, cf_file)) {
+            if (!Folder_Delete(ivars->real_folder, cf_file)) {
                 return false;
             }
             CharBuf *cfmeta_file = (CharBuf*)ZCB_WRAP_STR("cfmeta.json", 11);
-            if (!Folder_Delete(self->real_folder, cfmeta_file)) {
+            if (!Folder_Delete(ivars->real_folder, cfmeta_file)) {
                 return false;
 
             }
@@ -174,10 +179,11 @@ CFReader_local_delete(CompoundFileReader *self, const CharBuf *name) {
 
 InStream*
 CFReader_local_open_in(CompoundFileReader *self, const CharBuf *name) {
-    Hash *entry = (Hash*)Hash_Fetch(self->records, (Obj*)name);
+    CompoundFileReaderIVARS *const ivars = CFReader_IVARS(self);
+    Hash *entry = (Hash*)Hash_Fetch(ivars->records, (Obj*)name);
 
     if (!entry) {
-        InStream *instream = Folder_Local_Open_In(self->real_folder, name);
+        InStream *instream = Folder_Local_Open_In(ivars->real_folder, name);
         if (!instream) {
             ERR_ADD_FRAME(Err_get_error());
         }
@@ -188,18 +194,18 @@ CFReader_local_open_in(CompoundFileReader *self, const CharBuf *name) {
         Obj *offset = Hash_Fetch_Str(entry, "offset", 6);
         if (!len || !offset) {
             Err_set_error(Err_new(CB_newf("Malformed entry for '%o' in '%o'",
-                                          name, Folder_Get_Path(self->real_folder))));
+                                          name, Folder_Get_Path(ivars->real_folder))));
             return NULL;
         }
-        else if (CB_Get_Size(self->path)) {
-            CharBuf *fullpath = CB_newf("%o/%o", self->path, name);
-            InStream *instream = InStream_Reopen(self->instream, fullpath,
+        else if (CB_Get_Size(ivars->path)) {
+            CharBuf *fullpath = CB_newf("%o/%o", ivars->path, name);
+            InStream *instream = InStream_Reopen(ivars->instream, fullpath,
                                                  Obj_To_I64(offset), Obj_To_I64(len));
             DECREF(fullpath);
             return instream;
         }
         else {
-            return InStream_Reopen(self->instream, name, Obj_To_I64(offset),
+            return InStream_Reopen(ivars->instream, name, Obj_To_I64(offset),
                                    Obj_To_I64(len));
         }
     }
@@ -207,31 +213,35 @@ CFReader_local_open_in(CompoundFileReader *self, const CharBuf *name) {
 
 bool
 CFReader_local_exists(CompoundFileReader *self, const CharBuf *name) {
-    if (Hash_Fetch(self->records, (Obj*)name))        { return true; }
-    if (Folder_Local_Exists(self->real_folder, name)) { return true; }
+    CompoundFileReaderIVARS *const ivars = CFReader_IVARS(self);
+    if (Hash_Fetch(ivars->records, (Obj*)name))        { return true; }
+    if (Folder_Local_Exists(ivars->real_folder, name)) { return true; }
     return false;
 }
 
 bool
 CFReader_local_is_directory(CompoundFileReader *self, const CharBuf *name) {
-    if (Hash_Fetch(self->records, (Obj*)name))              { return false; }
-    if (Folder_Local_Is_Directory(self->real_folder, name)) { return true; }
+    CompoundFileReaderIVARS *const ivars = CFReader_IVARS(self);
+    if (Hash_Fetch(ivars->records, (Obj*)name))              { return false; }
+    if (Folder_Local_Is_Directory(ivars->real_folder, name)) { return true; }
     return false;
 }
 
 void
 CFReader_close(CompoundFileReader *self) {
-    InStream_Close(self->instream);
+    CompoundFileReaderIVARS *const ivars = CFReader_IVARS(self);
+    InStream_Close(ivars->instream);
 }
 
 bool
 CFReader_local_mkdir(CompoundFileReader *self, const CharBuf *name) {
-    if (Hash_Fetch(self->records, (Obj*)name)) {
+    CompoundFileReaderIVARS *const ivars = CFReader_IVARS(self);
+    if (Hash_Fetch(ivars->records, (Obj*)name)) {
         Err_set_error(Err_new(CB_newf("Can't MkDir: '%o' exists", name)));
         return false;
     }
     else {
-        bool result = Folder_Local_MkDir(self->real_folder, name);
+        bool result = Folder_Local_MkDir(ivars->real_folder, name);
         if (!result) { ERR_ADD_FRAME(Err_get_error()); }
         return result;
     }
@@ -239,8 +249,9 @@ CFReader_local_mkdir(CompoundFileReader *self, const CharBuf *name) {
 
 Folder*
 CFReader_local_find_folder(CompoundFileReader *self, const CharBuf *name) {
-    if (Hash_Fetch(self->records, (Obj*)name)) { return false; }
-    return Folder_Local_Find_Folder(self->real_folder, name);
+    CompoundFileReaderIVARS *const ivars = CFReader_IVARS(self);
+    if (Hash_Fetch(ivars->records, (Obj*)name)) { return false; }
+    return Folder_Local_Find_Folder(ivars->real_folder, name);
 }
 
 DirHandle*
@@ -260,14 +271,18 @@ CFReaderDH_new(CompoundFileReader *cf_reader) {
 CFReaderDirHandle*
 CFReaderDH_init(CFReaderDirHandle *self, CompoundFileReader *cf_reader) {
     DH_init((DirHandle*)self, CFReader_Get_Path(cf_reader));
-    self->cf_reader = (CompoundFileReader*)INCREF(cf_reader);
-    self->elems  = Hash_Keys(self->cf_reader->records);
-    self->tick   = -1;
+    CFReaderDirHandleIVARS *const ivars = CFReaderDH_IVARS(self);
+    ivars->cf_reader = (CompoundFileReader*)INCREF(cf_reader);
+
+    Hash *cf_records = CFReader_IVARS(ivars->cf_reader)->records;
+    ivars->elems  = Hash_Keys(cf_records);
+    ivars->tick   = -1;
     // Accumulate entries from real Folder.
-    DirHandle *dh = Folder_Local_Open_Dir(self->cf_reader->real_folder);
+    Folder *real_folder = CFReader_Get_Real_Folder(ivars->cf_reader);
+    DirHandle *dh = Folder_Local_Open_Dir(real_folder);
     CharBuf *entry = DH_Get_Entry(dh);
     while (DH_Next(dh)) {
-        VA_Push(self->elems, (Obj*)CB_Clone(entry));
+        VA_Push(ivars->elems, (Obj*)CB_Clone(entry));
     }
     DECREF(dh);
     return self;
@@ -275,29 +290,31 @@ CFReaderDH_init(CFReaderDirHandle *self, CompoundFileReader *cf_reader) {
 
 bool
 CFReaderDH_close(CFReaderDirHandle *self) {
-    if (self->elems) {
-        VA_Dec_RefCount(self->elems);
-        self->elems = NULL;
+    CFReaderDirHandleIVARS *const ivars = CFReaderDH_IVARS(self);
+    if (ivars->elems) {
+        VA_Dec_RefCount(ivars->elems);
+        ivars->elems = NULL;
     }
-    if (self->cf_reader) {
-        CFReader_Dec_RefCount(self->cf_reader);
-        self->cf_reader = NULL;
+    if (ivars->cf_reader) {
+        CFReader_Dec_RefCount(ivars->cf_reader);
+        ivars->cf_reader = NULL;
     }
     return true;
 }
 
 bool
 CFReaderDH_next(CFReaderDirHandle *self) {
-    if (self->elems) {
-        self->tick++;
-        if (self->tick < (int32_t)VA_Get_Size(self->elems)) {
+    CFReaderDirHandleIVARS *const ivars = CFReaderDH_IVARS(self);
+    if (ivars->elems) {
+        ivars->tick++;
+        if (ivars->tick < (int32_t)VA_Get_Size(ivars->elems)) {
             CharBuf *path = (CharBuf*)CERTIFY(
-                                VA_Fetch(self->elems, self->tick), CHARBUF);
-            CB_Mimic(self->entry, (Obj*)path);
+                                VA_Fetch(ivars->elems, ivars->tick), CHARBUF);
+            CB_Mimic(ivars->entry, (Obj*)path);
             return true;
         }
         else {
-            self->tick--;
+            ivars->tick--;
             return false;
         }
     }
@@ -306,10 +323,11 @@ CFReaderDH_next(CFReaderDirHandle *self) {
 
 bool
 CFReaderDH_entry_is_dir(CFReaderDirHandle *self) {
-    if (self->elems) {
-        CharBuf *name = (CharBuf*)VA_Fetch(self->elems, self->tick);
+    CFReaderDirHandleIVARS *const ivars = CFReaderDH_IVARS(self);
+    if (ivars->elems) {
+        CharBuf *name = (CharBuf*)VA_Fetch(ivars->elems, ivars->tick);
         if (name) {
-            return CFReader_Local_Is_Directory(self->cf_reader, name);
+            return CFReader_Local_Is_Directory(ivars->cf_reader, name);
         }
     }
     return false;

http://git-wip-us.apache.org/repos/asf/lucy/blob/d04580a1/core/Lucy/Store/CompoundFileWriter.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/CompoundFileWriter.c b/core/Lucy/Store/CompoundFileWriter.c
index 2ff716b..c009e64 100644
--- a/core/Lucy/Store/CompoundFileWriter.c
+++ b/core/Lucy/Store/CompoundFileWriter.c
@@ -28,11 +28,12 @@ int32_t CFWriter_current_file_format = 2;
 
 // Helper which does the heavy lifting for CFWriter_consolidate.
 static void
-S_do_consolidate(CompoundFileWriter *self);
+S_do_consolidate(CompoundFileWriter *self, CompoundFileWriterIVARS *ivars);
 
 // Clean up files which may be left over from previous merge attempts.
 static void
-S_clean_up_old_temp_files(CompoundFileWriter *self);
+S_clean_up_old_temp_files(CompoundFileWriter *self,
+                          CompoundFileWriterIVARS *ivars);
 
 CompoundFileWriter*
 CFWriter_new(Folder *folder) {
@@ -43,32 +44,37 @@ CFWriter_new(Folder *folder) {
 
 CompoundFileWriter*
 CFWriter_init(CompoundFileWriter *self, Folder *folder) {
-    self->folder = (Folder*)INCREF(folder);
+    CompoundFileWriterIVARS *const ivars = CFWriter_IVARS(self);
+    ivars->folder = (Folder*)INCREF(folder);
     return self;
 }
 
 void
 CFWriter_destroy(CompoundFileWriter *self) {
-    DECREF(self->folder);
+    CompoundFileWriterIVARS *const ivars = CFWriter_IVARS(self);
+    DECREF(ivars->folder);
     SUPER_DESTROY(self, COMPOUNDFILEWRITER);
 }
 
 void
 CFWriter_consolidate(CompoundFileWriter *self) {
+    CompoundFileWriterIVARS *const ivars = CFWriter_IVARS(self);
     CharBuf *cfmeta_file = (CharBuf*)ZCB_WRAP_STR("cfmeta.json", 11);
-    if (Folder_Exists(self->folder, cfmeta_file)) {
+    if (Folder_Exists(ivars->folder, cfmeta_file)) {
         THROW(ERR, "Merge already performed for %o",
-              Folder_Get_Path(self->folder));
+              Folder_Get_Path(ivars->folder));
     }
     else {
-        S_clean_up_old_temp_files(self);
-        S_do_consolidate(self);
+        S_clean_up_old_temp_files(self, ivars);
+        S_do_consolidate(self, ivars);
     }
 }
 
 static void
-S_clean_up_old_temp_files(CompoundFileWriter *self) {
-    Folder  *folder      = self->folder;
+S_clean_up_old_temp_files(CompoundFileWriter *self,
+                          CompoundFileWriterIVARS *ivars) {
+    UNUSED_VAR(self);
+    Folder  *folder      = ivars->folder;
     CharBuf *cfmeta_temp = (CharBuf*)ZCB_WRAP_STR("cfmeta.json.temp", 16);
     CharBuf *cf_file     = (CharBuf*)ZCB_WRAP_STR("cf.dat", 6);
 
@@ -85,8 +91,9 @@ S_clean_up_old_temp_files(CompoundFileWriter *self) {
 }
 
 static void
-S_do_consolidate(CompoundFileWriter *self) {
-    Folder    *folder       = self->folder;
+S_do_consolidate(CompoundFileWriter *self, CompoundFileWriterIVARS *ivars) {
+    UNUSED_VAR(self);
+    Folder    *folder       = ivars->folder;
     Hash      *metadata     = Hash_new(0);
     Hash      *sub_files    = Hash_new(0);
     VArray    *files        = Folder_List(folder, NULL);
@@ -143,8 +150,8 @@ S_do_consolidate(CompoundFileWriter *self) {
     // Write metadata to cfmeta file.
     CharBuf *cfmeta_temp = (CharBuf*)ZCB_WRAP_STR("cfmeta.json.temp", 16);
     CharBuf *cfmeta_file = (CharBuf*)ZCB_WRAP_STR("cfmeta.json", 11);
-    Json_spew_json((Obj*)metadata, (Folder*)self->folder, cfmeta_temp);
-    rename_success = Folder_Rename(self->folder, cfmeta_temp, cfmeta_file);
+    Json_spew_json((Obj*)metadata, (Folder*)ivars->folder, cfmeta_temp);
+    rename_success = Folder_Rename(ivars->folder, cfmeta_temp, cfmeta_file);
     if (!rename_success) { RETHROW(INCREF(Err_get_error())); }
 
     // Clean up.

http://git-wip-us.apache.org/repos/asf/lucy/blob/d04580a1/core/Lucy/Store/DirHandle.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/DirHandle.c b/core/Lucy/Store/DirHandle.c
index 6729d5d..c9e4b03 100644
--- a/core/Lucy/Store/DirHandle.c
+++ b/core/Lucy/Store/DirHandle.c
@@ -20,28 +20,30 @@
 
 DirHandle*
 DH_init(DirHandle *self, const CharBuf *dir) {
-    self->dir   = CB_Clone(dir);
-    self->entry = CB_new(32);
+    DirHandleIVARS *const ivars = DH_IVARS(self);
+    ivars->dir   = CB_Clone(dir);
+    ivars->entry = CB_new(32);
     ABSTRACT_CLASS_CHECK(self, DIRHANDLE);
     return self;
 }
 
 void
 DH_destroy(DirHandle *self) {
+    DirHandleIVARS *const ivars = DH_IVARS(self);
     DH_Close(self);
-    DECREF(self->dir);
-    DECREF(self->entry);
+    DECREF(ivars->dir);
+    DECREF(ivars->entry);
     SUPER_DESTROY(self, DIRHANDLE);
 }
 
 CharBuf*
 DH_get_dir(DirHandle *self) {
-    return self->dir;
+    return DH_IVARS(self)->dir;
 }
 
 CharBuf*
 DH_get_entry(DirHandle *self) {
-    return self->entry;
+    return DH_IVARS(self)->entry;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/d04580a1/core/Lucy/Store/FSDirHandle.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/FSDirHandle.c b/core/Lucy/Store/FSDirHandle.c
index 27ecb59..1d2d118 100644
--- a/core/Lucy/Store/FSDirHandle.c
+++ b/core/Lucy/Store/FSDirHandle.c
@@ -39,8 +39,9 @@ FSDH_open(const CharBuf *dir) {
 void
 FSDH_destroy(FSDirHandle *self) {
     // Throw away saved error -- it's too late to call Close() now.
-    DECREF(self->saved_error);
-    self->saved_error = NULL;
+    FSDirHandleIVARS *const ivars = FSDH_IVARS(self);
+    DECREF(ivars->saved_error);
+    ivars->saved_error = NULL;
     SUPER_DESTROY(self, FSDIRHANDLE);
 }
 
@@ -70,9 +71,10 @@ FSDH_do_open(FSDirHandle *self, const CharBuf *dir) {
     char   *path_ptr = search_string;
 
     DH_init((DirHandle*)self, dir);
-    self->sys_dir_entry    = MALLOCATE(sizeof(WIN32_FIND_DATA));
-    self->sys_dirhandle    = INVALID_HANDLE_VALUE;
-    self->saved_error      = NULL;
+    FSDirHandleIVARS *const ivars = FSDH_IVARS(self);
+    ivars->sys_dir_entry    = MALLOCATE(sizeof(WIN32_FIND_DATA));
+    ivars->sys_dirhandle    = INVALID_HANDLE_VALUE;
+    ivars->saved_error      = NULL;
 
     if (dir_path_size >= MAX_PATH - 2) {
         // Deal with Windows ceiling on file path lengths.
@@ -87,9 +89,9 @@ FSDH_do_open(FSDirHandle *self, const CharBuf *dir) {
     memcpy(path_ptr, dir_path_ptr, dir_path_size);
     memcpy(path_ptr + dir_path_size, "\\*\0", 3);
 
-    self->sys_dirhandle
-        = FindFirstFile(search_string, (WIN32_FIND_DATA*)self->sys_dir_entry);
-    if (INVALID_HANDLE_VALUE == self->sys_dirhandle) {
+    ivars->sys_dirhandle
+        = FindFirstFile(search_string, (WIN32_FIND_DATA*)ivars->sys_dir_entry);
+    if (INVALID_HANDLE_VALUE == ivars->sys_dirhandle) {
         // Directory inaccessible or doesn't exist.
         Err_set_error(Err_new(CB_newf("Failed to open dir '%o'", dir)));
         CFISH_DECREF(self);
@@ -99,7 +101,7 @@ FSDH_do_open(FSDirHandle *self, const CharBuf *dir) {
         // Compensate for the fact that FindFirstFile has already returned the
         // first entry but DirHandle's API requires that you call Next() to
         // start the iterator.
-        self->delayed_iter = true;
+        ivars->delayed_iter = true;
     }
 
     return self;
@@ -107,7 +109,8 @@ FSDH_do_open(FSDirHandle *self, const CharBuf *dir) {
 
 bool
 FSDH_entry_is_dir(FSDirHandle *self) {
-    WIN32_FIND_DATA *find_data = (WIN32_FIND_DATA*)self->sys_dir_entry;
+    FSDirHandleIVARS *const ivars = FSDH_IVARS(self);
+    WIN32_FIND_DATA *find_data = (WIN32_FIND_DATA*)ivars->sys_dir_entry;
     if (find_data) {
         if ((find_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
             return true;
@@ -118,7 +121,8 @@ FSDH_entry_is_dir(FSDirHandle *self) {
 
 bool
 FSDH_entry_is_symlink(FSDirHandle *self) {
-    WIN32_FIND_DATA *find_data = (WIN32_FIND_DATA*)self->sys_dir_entry;
+    FSDirHandleIVARS *const ivars = FSDH_IVARS(self);
+    WIN32_FIND_DATA *find_data = (WIN32_FIND_DATA*)ivars->sys_dir_entry;
     if (find_data) {
         if ((find_data->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
             return true;
@@ -129,27 +133,28 @@ FSDH_entry_is_symlink(FSDirHandle *self) {
 
 bool
 FSDH_close(FSDirHandle *self) {
-    if (self->sys_dirhandle && self->sys_dirhandle != INVALID_HANDLE_VALUE) {
-        HANDLE dirhandle = (HANDLE)self->sys_dirhandle;
-        self->sys_dirhandle = NULL;
+    FSDirHandleIVARS *const ivars = FSDH_IVARS(self);
+    if (ivars->sys_dirhandle && ivars->sys_dirhandle != INVALID_HANDLE_VALUE) {
+        HANDLE dirhandle = (HANDLE)ivars->sys_dirhandle;
+        ivars->sys_dirhandle = NULL;
         if (dirhandle != INVALID_HANDLE_VALUE && !FindClose(dirhandle)) {
-            if (!self->saved_error) {
+            if (!ivars->saved_error) {
                 char *win_error = Err_win_error();
-                self->saved_error
+                ivars->saved_error
                     = Err_new(CB_newf("Error while closing directory: %s",
                                       win_error));
                 FREEMEM(win_error);
             }
         }
     }
-    if (self->sys_dir_entry) {
-        FREEMEM(self->sys_dir_entry);
-        self->sys_dir_entry = NULL;
+    if (ivars->sys_dir_entry) {
+        FREEMEM(ivars->sys_dir_entry);
+        ivars->sys_dir_entry = NULL;
     }
 
     // If we encountered an error condition previously, report it now.
-    if (self->saved_error) {
-        Err_set_error((Err*)CFISH_INCREF(self->saved_error));
+    if (ivars->saved_error) {
+        Err_set_error((Err*)CFISH_INCREF(ivars->saved_error));
         return false;
     }
     else {
@@ -159,22 +164,23 @@ FSDH_close(FSDirHandle *self) {
 
 bool
 FSDH_next(FSDirHandle *self) {
-    HANDLE           dirhandle = (HANDLE)self->sys_dirhandle;
-    WIN32_FIND_DATA *find_data = (WIN32_FIND_DATA*)self->sys_dir_entry;
+    FSDirHandleIVARS *const ivars = FSDH_IVARS(self);
+    HANDLE           dirhandle = (HANDLE)ivars->sys_dirhandle;
+    WIN32_FIND_DATA *find_data = (WIN32_FIND_DATA*)ivars->sys_dir_entry;
 
     // Attempt to move forward or absorb cached iter.
     if (!dirhandle || dirhandle == INVALID_HANDLE_VALUE) {
         return false;
     }
-    else if (self->delayed_iter) {
-        self->delayed_iter = false;
+    else if (ivars->delayed_iter) {
+        ivars->delayed_iter = false;
     }
     else if ((FindNextFile(dirhandle, find_data) == 0)) {
         // Iterator exhausted.  Verify that no errors were encountered.
-        CB_Set_Size(self->entry, 0);
+        CB_Set_Size(ivars->entry, 0);
         if (GetLastError() != ERROR_NO_MORE_FILES) {
             char *win_error = Err_win_error();
-            self->saved_error
+            ivars->saved_error
                 = Err_new(CB_newf("Error while traversing directory: %s",
                                   win_error));
             FREEMEM(win_error);
@@ -188,7 +194,7 @@ FSDH_next(FSDirHandle *self) {
         return FSDH_Next(self);
     }
     else {
-        CB_Mimic_Str(self->entry, find_data->cFileName, len);
+        CB_Mimic_Str(ivars->entry, find_data->cFileName, len);
         return true;
     }
 }
@@ -203,11 +209,12 @@ FSDH_do_open(FSDirHandle *self, const CharBuf *dir) {
     char *dir_path_ptr = (char*)CB_Get_Ptr8(dir);
 
     DH_init((DirHandle*)self, dir);
-    self->sys_dir_entry    = NULL;
-    self->fullpath         = NULL;
+    FSDirHandleIVARS *const ivars = FSDH_IVARS(self);
+    ivars->sys_dir_entry    = NULL;
+    ivars->fullpath         = NULL;
 
-    self->sys_dirhandle = opendir(dir_path_ptr);
-    if (!self->sys_dirhandle) {
+    ivars->sys_dirhandle = opendir(dir_path_ptr);
+    if (!ivars->sys_dirhandle) {
         Err_set_error(Err_new(CB_newf("Failed to opendir '%o'", dir)));
         DECREF(self);
         return NULL;
@@ -218,13 +225,14 @@ FSDH_do_open(FSDirHandle *self, const CharBuf *dir) {
 
 bool
 FSDH_next(FSDirHandle *self) {
-    self->sys_dir_entry = (struct dirent*)readdir((DIR*)self->sys_dirhandle);
-    if (!self->sys_dir_entry) {
-        CB_Set_Size(self->entry, 0);
+    FSDirHandleIVARS *const ivars = FSDH_IVARS(self);
+    ivars->sys_dir_entry = (struct dirent*)readdir((DIR*)ivars->sys_dirhandle);
+    if (!ivars->sys_dir_entry) {
+        CB_Set_Size(ivars->entry, 0);
         return false;
     }
     else {
-        struct dirent *sys_dir_entry = (struct dirent*)self->sys_dir_entry;
+        struct dirent *sys_dir_entry = (struct dirent*)ivars->sys_dir_entry;
         #ifdef CHY_HAS_DIRENT_D_NAMLEN
         size_t len = sys_dir_entry->d_namlen;
         #else
@@ -234,7 +242,7 @@ FSDH_next(FSDirHandle *self) {
             return FSDH_Next(self);
         }
         else {
-            CB_Mimic_Str(self->entry, sys_dir_entry->d_name, len);
+            CB_Mimic_Str(ivars->entry, sys_dir_entry->d_name, len);
             return true;
         }
     }
@@ -242,7 +250,8 @@ FSDH_next(FSDirHandle *self) {
 
 bool
 FSDH_entry_is_dir(FSDirHandle *self) {
-    struct dirent *sys_dir_entry = (struct dirent*)self->sys_dir_entry;
+    FSDirHandleIVARS *const ivars = FSDH_IVARS(self);
+    struct dirent *sys_dir_entry = (struct dirent*)ivars->sys_dir_entry;
     if (!sys_dir_entry) { return false; }
 
     // If d_type is available, try to avoid a stat() call.  If it's not, or if
@@ -257,12 +266,12 @@ FSDH_entry_is_dir(FSDirHandle *self) {
     #endif
 
     struct stat stat_buf;
-    if (!self->fullpath) {
-        self->fullpath = CB_new(CB_Get_Size(self->dir) + 20);
+    if (!ivars->fullpath) {
+        ivars->fullpath = CB_new(CB_Get_Size(ivars->dir) + 20);
     }
-    CB_setf(self->fullpath, "%o%s%o", self->dir, CHY_DIR_SEP,
-            self->entry);
-    if (stat((char*)CB_Get_Ptr8(self->fullpath), &stat_buf) != -1) {
+    CB_setf(ivars->fullpath, "%o%s%o", ivars->dir, CHY_DIR_SEP,
+            ivars->entry);
+    if (stat((char*)CB_Get_Ptr8(ivars->fullpath), &stat_buf) != -1) {
         if (stat_buf.st_mode & S_IFDIR) { return true; }
     }
     return false;
@@ -270,7 +279,8 @@ FSDH_entry_is_dir(FSDirHandle *self) {
 
 bool
 FSDH_entry_is_symlink(FSDirHandle *self) {
-    struct dirent *sys_dir_entry = (struct dirent*)self->sys_dir_entry;
+    FSDirHandleIVARS *const ivars = FSDH_IVARS(self);
+    struct dirent *sys_dir_entry = (struct dirent*)ivars->sys_dir_entry;
     if (!sys_dir_entry) { return false; }
 
     #ifdef CHY_HAS_DIRENT_D_TYPE
@@ -278,12 +288,12 @@ FSDH_entry_is_symlink(FSDirHandle *self) {
     #else
     {
         struct stat stat_buf;
-        if (!self->fullpath) {
-            self->fullpath = CB_new(CB_Get_Size(self->dir) + 20);
+        if (!ivars->fullpath) {
+            ivars->fullpath = CB_new(CB_Get_Size(ivars->dir) + 20);
         }
-        CB_setf(self->fullpath, "%o%s%o", self->dir, CHY_DIR_SEP,
-                self->entry);
-        if (stat((char*)CB_Get_Ptr8(self->fullpath), &stat_buf) != -1) {
+        CB_setf(ivars->fullpath, "%o%s%o", ivars->dir, CHY_DIR_SEP,
+                ivars->entry);
+        if (stat((char*)CB_Get_Ptr8(ivars->fullpath), &stat_buf) != -1) {
             if (stat_buf.st_mode & S_IFLNK) { return true; }
         }
         return false;
@@ -293,13 +303,14 @@ FSDH_entry_is_symlink(FSDirHandle *self) {
 
 bool
 FSDH_close(FSDirHandle *self) {
-    if (self->fullpath) {
-        CB_Dec_RefCount(self->fullpath);
-        self->fullpath = NULL;
+    FSDirHandleIVARS *const ivars = FSDH_IVARS(self);
+    if (ivars->fullpath) {
+        CB_Dec_RefCount(ivars->fullpath);
+        ivars->fullpath = NULL;
     }
-    if (self->sys_dirhandle) {
-        DIR *sys_dirhandle = (DIR*)self->sys_dirhandle;
-        self->sys_dirhandle = NULL;
+    if (ivars->sys_dirhandle) {
+        DIR *sys_dirhandle = (DIR*)ivars->sys_dirhandle;
+        ivars->sys_dirhandle = NULL;
         if (closedir(sys_dirhandle) == -1) {
             Err_set_error(Err_new(CB_newf("Error closing dirhandle: %s",
                                           strerror(errno))));

http://git-wip-us.apache.org/repos/asf/lucy/blob/d04580a1/core/Lucy/Store/FSFileHandle.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/FSFileHandle.c b/core/Lucy/Store/FSFileHandle.c
index d9f9b41..4074a75 100644
--- a/core/Lucy/Store/FSFileHandle.c
+++ b/core/Lucy/Store/FSFileHandle.c
@@ -61,7 +61,8 @@ SI_posix_flags(uint32_t fh_flags) {
 // the requested length is 0, return NULL.  If an error occurs, return NULL
 // and set Err_error.
 static INLINE void*
-SI_map(FSFileHandle *self, int64_t offset, int64_t len);
+SI_map(FSFileHandle *self, FSFileHandleIVARS *ivars, int64_t offset,
+       int64_t len);
 
 // Release a memory mapped region assigned by SI_map.
 static INLINE bool
@@ -69,11 +70,12 @@ SI_unmap(FSFileHandle *self, char *ptr, int64_t len);
 
 // 32-bit or 64-bit inlined helpers for FSFH_window.
 static INLINE bool
-SI_window(FSFileHandle *self, FileWindow *window, int64_t offset, int64_t len);
+SI_window(FSFileHandle *self, FSFileHandleIVARS *ivars, FileWindow *window,
+          int64_t offset, int64_t len);
 
 // Architecture- and OS- specific initialization for a read-only FSFileHandle.
 static INLINE bool
-SI_init_read_only(FSFileHandle *self);
+SI_init_read_only(FSFileHandle *self, FSFileHandleIVARS *ivars);
 
 // Windows-specific routine needed for closing read-only handles.
 #ifdef CHY_HAS_WINDOWS_H
@@ -90,6 +92,7 @@ FSFH_open(const CharBuf *path, uint32_t flags) {
 FSFileHandle*
 FSFH_do_open(FSFileHandle *self, const CharBuf *path, uint32_t flags) {
     FH_do_open((FileHandle*)self, path, flags);
+    FSFileHandleIVARS *const ivars = FSFH_IVARS(self);
     if (!path || !CB_Get_Size(path)) {
         Err_set_error(Err_new(CB_newf("Missing required param 'path'")));
         CFISH_DECREF(self);
@@ -98,31 +101,31 @@ FSFH_do_open(FSFileHandle *self, const CharBuf *path, uint32_t flags) {
 
     // Attempt to open file.
     if (flags & FH_WRITE_ONLY) {
-        self->fd = open((char*)CB_Get_Ptr8(path), SI_posix_flags(flags), 0666);
-        if (self->fd == -1) {
-            self->fd = 0;
+        ivars->fd = open((char*)CB_Get_Ptr8(path), SI_posix_flags(flags), 0666);
+        if (ivars->fd == -1) {
+            ivars->fd = 0;
             Err_set_error(Err_new(CB_newf("Attempt to open '%o' failed: %s",
                                           path, strerror(errno))));
             CFISH_DECREF(self);
             return NULL;
         }
         if (flags & FH_EXCLUSIVE) {
-            self->len = 0;
+            ivars->len = 0;
         }
         else {
             // Derive length.
-            self->len = lseek64(self->fd, INT64_C(0), SEEK_END);
-            if (self->len == -1) {
+            ivars->len = lseek64(ivars->fd, INT64_C(0), SEEK_END);
+            if (ivars->len == -1) {
                 Err_set_error(Err_new(CB_newf("lseek64 on %o failed: %s",
-                                              self->path, strerror(errno))));
+                                              ivars->path, strerror(errno))));
                 CFISH_DECREF(self);
                 return NULL;
             }
             else {
-                int64_t check_val = lseek64(self->fd, INT64_C(0), SEEK_SET);
+                int64_t check_val = lseek64(ivars->fd, INT64_C(0), SEEK_SET);
                 if (check_val == -1) {
                     Err_set_error(Err_new(CB_newf("lseek64 on %o failed: %s",
-                                                  self->path, strerror(errno))));
+                                                  ivars->path, strerror(errno))));
                     CFISH_DECREF(self);
                     return NULL;
                 }
@@ -130,11 +133,11 @@ FSFH_do_open(FSFileHandle *self, const CharBuf *path, uint32_t flags) {
         }
     }
     else if (flags & FH_READ_ONLY) {
-        if (SI_init_read_only(self)) {
+        if (SI_init_read_only(self, ivars)) {
             // On 64-bit systems, map the whole file up-front.
-            if (IS_64_BIT && self->len) {
-                self->buf = (char*)SI_map(self, 0, self->len);
-                if (!self->buf) {
+            if (IS_64_BIT && ivars->len) {
+                ivars->buf = (char*)SI_map(self, ivars, 0, ivars->len);
+                if (!ivars->buf) {
                     // An error occurred during SI_map, which has set
                     // Err_error for us already.
                     CFISH_DECREF(self);
@@ -159,23 +162,25 @@ FSFH_do_open(FSFileHandle *self, const CharBuf *path, uint32_t flags) {
 
 bool
 FSFH_close(FSFileHandle *self) {
+    FSFileHandleIVARS *const ivars = FSFH_IVARS(self);
+
     // On 64-bit systems, cancel the whole-file mapping.
-    if (IS_64_BIT && (self->flags & FH_READ_ONLY) && self->buf != NULL) {
-        if (!SI_unmap(self, self->buf, self->len)) { return false; }
-        self->buf = NULL;
+    if (IS_64_BIT && (ivars->flags & FH_READ_ONLY) && ivars->buf != NULL) {
+        if (!SI_unmap(self, ivars->buf, ivars->len)) { return false; }
+        ivars->buf = NULL;
     }
 
     // Close system-specific handles.
-    if (self->fd) {
-        if (close(self->fd)) {
+    if (ivars->fd) {
+        if (close(ivars->fd)) {
             Err_set_error(Err_new(CB_newf("Failed to close file: %s",
                                           strerror(errno))));
             return false;
         }
-        self->fd  = 0;
+        ivars->fd  = 0;
     }
     #if (defined(CHY_HAS_WINDOWS_H) && !defined(CHY_HAS_SYS_MMAN_H))
-    if (self->win_fhandle) {
+    if (ivars->win_fhandle) {
         if (!SI_close_win_handles(self)) { return false; }
     }
     #endif
@@ -185,10 +190,12 @@ FSFH_close(FSFileHandle *self) {
 
 bool
 FSFH_write(FSFileHandle *self, const void *data, size_t len) {
+    FSFileHandleIVARS *const ivars = FSFH_IVARS(self);
+
     if (len) {
         // Write data, track file length, check for errors.
-        int64_t check_val = write(self->fd, data, len);
-        self->len += check_val;
+        int64_t check_val = write(ivars->fd, data, len);
+        ivars->len += check_val;
         if ((size_t)check_val != len) {
             if (check_val == -1) {
                 Err_set_error(Err_new(CB_newf("Error when writing %u64 bytes: %s",
@@ -207,14 +214,15 @@ FSFH_write(FSFileHandle *self, const void *data, size_t len) {
 
 int64_t
 FSFH_length(FSFileHandle *self) {
-    return self->len;
+    return FSFH_IVARS(self)->len;
 }
 
 bool
 FSFH_window(FSFileHandle *self, FileWindow *window, int64_t offset,
             int64_t len) {
+    FSFileHandleIVARS *const ivars = FSFH_IVARS(self);
     const int64_t end = offset + len;
-    if (!(self->flags & FH_READ_ONLY)) {
+    if (!(ivars->flags & FH_READ_ONLY)) {
         Err_set_error(Err_new(CB_newf("Can't read from write-only handle")));
         return false;
     }
@@ -223,13 +231,13 @@ FSFH_window(FSFileHandle *self, FileWindow *window, int64_t offset,
                                       offset)));
         return false;
     }
-    else if (end > self->len) {
+    else if (end > ivars->len) {
         Err_set_error(Err_new(CB_newf("Tried to read past EOF: offset %i64 + request %i64 > len %i64",
-                                      offset, len, self->len)));
+                                      offset, len, ivars->len)));
         return false;
     }
     else {
-        return SI_window(self, window, offset, len);
+        return SI_window(self, ivars, window, offset, len);
     }
 }
 
@@ -238,9 +246,10 @@ FSFH_window(FSFileHandle *self, FileWindow *window, int64_t offset,
 #if IS_64_BIT
 
 static INLINE bool
-SI_window(FSFileHandle *self, FileWindow *window, int64_t offset,
-          int64_t len) {
-    FileWindow_Set_Window(window, self->buf + offset, offset, len);
+SI_window(FSFileHandle *self, FSFileHandleIVARS *ivars, FileWindow *window,
+          int64_t offset, int64_t len) {
+    UNUSED_VAR(self);
+    FileWindow_Set_Window(window, ivars->buf + offset, offset, len);
     return true;
 }
 
@@ -253,9 +262,10 @@ FSFH_release_window(FSFileHandle *self, FileWindow *window) {
 
 bool
 FSFH_read(FSFileHandle *self, char *dest, int64_t offset, size_t len) {
+    FSFileHandleIVARS *const ivars = FSFH_IVARS(self);
     const int64_t end = offset + len;
 
-    if (self->flags & FH_WRITE_ONLY) {
+    if (ivars->flags & FH_WRITE_ONLY) {
         Err_set_error(Err_new(CB_newf("Can't read from write-only filehandle")));
         return false;
     }
@@ -264,12 +274,12 @@ FSFH_read(FSFileHandle *self, char *dest, int64_t offset, size_t len) {
                                       offset)));
         return false;
     }
-    else if (end > self->len) {
+    else if (end > ivars->len) {
         Err_set_error(Err_new(CB_newf("Tried to read past EOF: offset %i64 + request %u64 > len %i64",
-                                      offset, (uint64_t)len, self->len)));
+                                      offset, (uint64_t)len, ivars->len)));
         return false;
     }
-    memcpy(dest, self->buf + offset, len);
+    memcpy(dest, ivars->buf + offset, len);
     return true;
 }
 
@@ -278,18 +288,19 @@ FSFH_read(FSFileHandle *self, char *dest, int64_t offset, size_t len) {
 #else
 
 static INLINE bool
-SI_window(FSFileHandle *self, FileWindow *window, int64_t offset,
-          int64_t len) {
+SI_window(FSFileHandle *self, FSFileHandleIVARS *ivars, FileWindow *window,
+          int64_t offset, int64_t len) {
     // Release the previously mmap'd region, if any.
     FSFH_release_window(self, window);
 
     // Start map on a page boundary.  Ensure that the window is at
     // least wide enough to view all the data spec'd in the original
     // request.
-    const int64_t remainder       = offset % self->page_size;
+    const int64_t remainder       = offset % ivars->page_size;
     const int64_t adjusted_offset = offset - remainder;
     const int64_t adjusted_len    = len + remainder;
-    char *const buf = (char*)SI_map(self, adjusted_offset, adjusted_len);
+    char *const buf
+        = (char*)SI_map(self, ivars, adjusted_offset, adjusted_len);
     if (len && buf == NULL) {
         return false;
     }
@@ -314,38 +325,40 @@ FSFH_release_window(FSFileHandle *self, FileWindow *window) {
 #ifdef CHY_HAS_SYS_MMAN_H
 
 static INLINE bool
-SI_init_read_only(FSFileHandle *self) {
+SI_init_read_only(FSFileHandle *self, FSFileHandleIVARS *ivars) {
+    UNUSED_VAR(self);
+
     // Open.
-    self->fd = open((char*)CB_Get_Ptr8(self->path),
-                    SI_posix_flags(self->flags), 0666);
-    if (self->fd == -1) {
-        self->fd = 0;
-        Err_set_error(Err_new(CB_newf("Can't open '%o': %s", self->path,
+    ivars->fd = open((char*)CB_Get_Ptr8(ivars->path),
+                    SI_posix_flags(ivars->flags), 0666);
+    if (ivars->fd == -1) {
+        ivars->fd = 0;
+        Err_set_error(Err_new(CB_newf("Can't open '%o': %s", ivars->path,
                                       strerror(errno))));
         return false;
     }
 
     // Derive len.
-    self->len = lseek64(self->fd, INT64_C(0), SEEK_END);
-    if (self->len == -1) {
-        Err_set_error(Err_new(CB_newf("lseek64 on %o failed: %s", self->path,
+    ivars->len = lseek64(ivars->fd, INT64_C(0), SEEK_END);
+    if (ivars->len == -1) {
+        Err_set_error(Err_new(CB_newf("lseek64 on %o failed: %s", ivars->path,
                                       strerror(errno))));
         return false;
     }
     else {
-        int64_t check_val = lseek64(self->fd, INT64_C(0), SEEK_SET);
+        int64_t check_val = lseek64(ivars->fd, INT64_C(0), SEEK_SET);
         if (check_val == -1) {
             Err_set_error(Err_new(CB_newf("lseek64 on %o failed: %s",
-                                          self->path, strerror(errno))));
+                                          ivars->path, strerror(errno))));
             return false;
         }
     }
 
     // Get system page size.
 #if defined(_SC_PAGESIZE)
-    self->page_size = sysconf(_SC_PAGESIZE);
+    ivars->page_size = sysconf(_SC_PAGESIZE);
 #elif defined(_SC_PAGE_SIZE)
-    self->page_size = sysconf(_SC_PAGE_SIZE);
+    ivars->page_size = sysconf(_SC_PAGE_SIZE);
 #else
     #error "Can't determine system memory page size"
 #endif
@@ -354,17 +367,19 @@ SI_init_read_only(FSFileHandle *self) {
 }
 
 static INLINE void*
-SI_map(FSFileHandle *self, int64_t offset, int64_t len) {
+SI_map(FSFileHandle *self, FSFileHandleIVARS *ivars, int64_t offset,
+       int64_t len) {
+    UNUSED_VAR(self);
     void *buf = NULL;
 
     if (len) {
         // Read-only memory mapping.
-        buf = mmap(NULL, len, PROT_READ, MAP_SHARED, self->fd, offset);
+        buf = mmap(NULL, len, PROT_READ, MAP_SHARED, ivars->fd, offset);
         if (buf == (void*)(-1)) {
             Err_set_error(Err_new(CB_newf("mmap of offset %i64 and length %i64 (page size %i64) "
                                           "against '%o' failed: %s",
-                                          offset, len, self->page_size,
-                                          self->path, strerror(errno))));
+                                          offset, len, ivars->page_size,
+                                          ivars->path, strerror(errno))));
             return NULL;
         }
     }
@@ -377,7 +392,8 @@ SI_unmap(FSFileHandle *self, char *buf, int64_t len) {
     if (buf != NULL) {
         if (munmap(buf, len)) {
             Err_set_error(Err_new(CB_newf("Failed to munmap '%o': %s",
-                                          self->path, strerror(errno))));
+                                          FSFH_IVARS(self)->path,
+                                          strerror(errno))));
             return false;
         }
     }
@@ -387,6 +403,7 @@ SI_unmap(FSFileHandle *self, char *buf, int64_t len) {
 #if !IS_64_BIT
 bool
 FSFH_read(FSFileHandle *self, char *dest, int64_t offset, size_t len) {
+    FSFileHandleIVARS *const ivars = FSFH_IVARS(self);
     int64_t check_val;
 
     // Sanity check.
@@ -397,7 +414,7 @@ FSFH_read(FSFileHandle *self, char *dest, int64_t offset, size_t len) {
     }
 
     // Read.
-    check_val = pread64(self->fd, dest, len, offset);
+    check_val = pread64(ivars->fd, dest, len, offset);
     if (check_val != (int64_t)len) {
         if (check_val == -1) {
             Err_set_error(Err_new(CB_newf("Tried to read %u64 bytes, got %i64: %s",
@@ -419,16 +436,16 @@ FSFH_read(FSFileHandle *self, char *dest, int64_t offset, size_t len) {
 #elif defined(CHY_HAS_WINDOWS_H)
 
 static INLINE bool
-SI_init_read_only(FSFileHandle *self) {
-    char *filepath = (char*)CB_Get_Ptr8(self->path);
+SI_init_read_only(FSFileHandle *self, FSFileHandleIVARS *ivars) {
+    char *filepath = (char*)CB_Get_Ptr8(ivars->path);
     SYSTEM_INFO sys_info;
 
     // Get system page size.
     GetSystemInfo(&sys_info);
-    self->page_size = sys_info.dwAllocationGranularity;
+    ivars->page_size = sys_info.dwAllocationGranularity;
 
     // Open.
-    self->win_fhandle = CreateFile(
+    ivars->win_fhandle = CreateFile(
                             filepath,
                             GENERIC_READ,
                             FILE_SHARE_READ,
@@ -437,33 +454,33 @@ SI_init_read_only(FSFileHandle *self) {
                             FILE_ATTRIBUTE_READONLY | FILE_FLAG_OVERLAPPED,
                             NULL
                         );
-    if (self->win_fhandle == INVALID_HANDLE_VALUE) {
+    if (ivars->win_fhandle == INVALID_HANDLE_VALUE) {
         char *win_error = Err_win_error();
         Err_set_error(Err_new(CB_newf("CreateFile for %o failed: %s",
-                                      self->path, win_error)));
+                                      ivars->path, win_error)));
         FREEMEM(win_error);
         return false;
     }
 
     // Derive len.
     DWORD file_size_hi;
-    DWORD file_size_lo = GetFileSize(self->win_fhandle, &file_size_hi);
+    DWORD file_size_lo = GetFileSize(ivars->win_fhandle, &file_size_hi);
     if (file_size_lo == INVALID_FILE_SIZE && GetLastError() != NO_ERROR) {
         Err_set_error(Err_new(CB_newf("GetFileSize for %o failed",
-                                      self->path)));
+                                      ivars->path)));
         return false;
     }
-    self->len = ((uint64_t)file_size_hi << 32) | file_size_lo;
+    ivars->len = ((uint64_t)file_size_hi << 32) | file_size_lo;
 
     // Init mapping handle.
-    self->buf = NULL;
-    if (self->len) {
-        self->win_maphandle = CreateFileMapping(self->win_fhandle, NULL,
-                                                PAGE_READONLY, 0, 0, NULL);
-        if (self->win_maphandle == NULL) {
+    ivars->buf = NULL;
+    if (ivars->len) {
+        ivars->win_maphandle = CreateFileMapping(ivars->win_fhandle, NULL,
+                                                 PAGE_READONLY, 0, 0, NULL);
+        if (ivars->win_maphandle == NULL) {
             char *win_error = Err_win_error();
             Err_set_error(Err_new(CB_newf("CreateFileMapping for %o failed: %s",
-                                          self->path, win_error)));
+                                          ivars->path, win_error)));
             FREEMEM(win_error);
             return false;
         }
@@ -473,7 +490,8 @@ SI_init_read_only(FSFileHandle *self) {
 }
 
 static INLINE void*
-SI_map(FSFileHandle *self, int64_t offset, int64_t len) {
+SI_map(FSFileHandle *self, FSFileHandleIVARS *ivars, int64_t offset,
+       int64_t len) {
     void *buf = NULL;
 
     if (len) {
@@ -482,12 +500,12 @@ SI_map(FSFileHandle *self, int64_t offset, int64_t len) {
         DWORD file_offset_hi = offs >> 32;
         DWORD file_offset_lo = offs & 0xFFFFFFFF;
         size_t amount = (size_t)len;
-        buf = MapViewOfFile(self->win_maphandle, FILE_MAP_READ,
+        buf = MapViewOfFile(ivars->win_maphandle, FILE_MAP_READ,
                             file_offset_hi, file_offset_lo, amount);
         if (buf == NULL) {
             char *win_error = Err_win_error();
             Err_set_error(Err_new(CB_newf("MapViewOfFile for %o failed: %s",
-                                          self->path, win_error)));
+                                          ivars->path, win_error)));
             FREEMEM(win_error);
         }
     }
@@ -496,12 +514,13 @@ SI_map(FSFileHandle *self, int64_t offset, int64_t len) {
 }
 
 static INLINE bool
-SI_unmap(FSFileHandle *self, char *buf, int64_t len) {
+SI_unmap(FSFileHandle *self, char *ptr, int64_t len) {
     if (buf != NULL) {
         if (!UnmapViewOfFile(buf)) {
             char *win_error = Err_win_error();
             Err_set_error(Err_new(CB_newf("Failed to unmap '%o': %s",
-                                          self->path, win_error)));
+                                          FSFH_IVARS(self)->path,
+                                          win_error)));
             FREEMEM(win_error);
             return false;
         }
@@ -511,26 +530,27 @@ SI_unmap(FSFileHandle *self, char *buf, int64_t len) {
 
 static INLINE bool
 SI_close_win_handles(FSFileHandle *self) {
+    FSFileHandleIVARS *ivars = FSFH_IVARS(self);
     // Close both standard handle and mapping handle.
-    if (self->win_maphandle) {
-        if (!CloseHandle(self->win_maphandle)) {
+    if (ivars->win_maphandle) {
+        if (!CloseHandle(ivars->win_maphandle)) {
             char *win_error = Err_win_error();
             Err_set_error(Err_new(CB_newf("Failed to close file mapping handle: %s",
                                           win_error)));
             FREEMEM(win_error);
             return false;
         }
-        self->win_maphandle = NULL;
+        ivars->win_maphandle = NULL;
     }
-    if (self->win_fhandle) {
-        if (!CloseHandle(self->win_fhandle)) {
+    if (ivars->win_fhandle) {
+        if (!CloseHandle(ivars->win_fhandle)) {
             char *win_error = Err_win_error();
             Err_set_error(Err_new(CB_newf("Failed to close file handle: %s",
                                           win_error)));
             FREEMEM(win_error);
             return false;
         }
-        self->win_fhandle = NULL;
+        ivars->win_fhandle = NULL;
     }
 
     return true;
@@ -539,6 +559,7 @@ SI_close_win_handles(FSFileHandle *self) {
 #if !IS_64_BIT
 bool
 FSFH_read(FSFileHandle *self, char *dest, int64_t offset, size_t len) {
+    FSFileHandleIVARS *const ivars = FSFH_IVARS(self);
     BOOL check_val;
     DWORD got;
     OVERLAPPED read_op_state;
@@ -564,12 +585,12 @@ FSFH_read(FSFileHandle *self, char *dest, int64_t offset, size_t len) {
     }
 
     // Read.
-    check_val = ReadFile(self->win_fhandle, dest, len, &got, &read_op_state);
+    check_val = ReadFile(ivars->win_fhandle, dest, len, &got, &read_op_state);
     if (!check_val && GetLastError() == ERROR_IO_PENDING) {
         // Read has been queued by the OS and will soon complete.  Wait for
         // it, since this is a blocking IO call from the point of the rest of
         // the library.
-        check_val = GetOverlappedResult(self->win_fhandle, &read_op_state,
+        check_val = GetOverlappedResult(ivars->win_fhandle, &read_op_state,
                                         &got, TRUE);
     }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/d04580a1/core/Lucy/Store/FSFolder.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/FSFolder.c b/core/Lucy/Store/FSFolder.c
index ab6b15c..c80fff5 100644
--- a/core/Lucy/Store/FSFolder.c
+++ b/core/Lucy/Store/FSFolder.c
@@ -90,8 +90,9 @@ FSFolder_init(FSFolder *self, const CharBuf *path) {
 
 void
 FSFolder_initialize(FSFolder *self) {
-    if (!S_dir_ok(self->path)) {
-        if (!S_create_dir(self->path)) {
+    FSFolderIVARS *const ivars = FSFolder_IVARS(self);
+    if (!S_dir_ok(ivars->path)) {
+        if (!S_create_dir(ivars->path)) {
             RETHROW(INCREF(Err_get_error()));
         }
     }
@@ -99,7 +100,8 @@ FSFolder_initialize(FSFolder *self) {
 
 bool
 FSFolder_check(FSFolder *self) {
-    return S_dir_ok(self->path);
+    FSFolderIVARS *const ivars = FSFolder_IVARS(self);
+    return S_dir_ok(ivars->path);
 }
 
 FileHandle*
@@ -123,14 +125,16 @@ FSFolder_local_mkdir(FSFolder *self, const CharBuf *name) {
 
 DirHandle*
 FSFolder_local_open_dir(FSFolder *self) {
-    DirHandle *dh = (DirHandle*)FSDH_open(self->path);
+    FSFolderIVARS *const ivars = FSFolder_IVARS(self);
+    DirHandle *dh = (DirHandle*)FSDH_open(ivars->path);
     if (!dh) { ERR_ADD_FRAME(Err_get_error()); }
     return dh;
 }
 
 bool
 FSFolder_local_exists(FSFolder *self, const CharBuf *name) {
-    if (Hash_Fetch(self->entries, (Obj*)name)) {
+    FSFolderIVARS *const ivars = FSFolder_IVARS(self);
+    if (Hash_Fetch(ivars->entries, (Obj*)name)) {
         return true;
     }
     else if (!S_is_local_entry(name)) {
@@ -150,8 +154,10 @@ FSFolder_local_exists(FSFolder *self, const CharBuf *name) {
 
 bool
 FSFolder_local_is_directory(FSFolder *self, const CharBuf *name) {
+    FSFolderIVARS *const ivars = FSFolder_IVARS(self);
+
     // Check for a cached object, then fall back to a system call.
-    Obj *elem = Hash_Fetch(self->entries, (Obj*)name);
+    Obj *elem = Hash_Fetch(ivars->entries, (Obj*)name);
     if (elem && Obj_Is_A(elem, FOLDER)) {
         return true;
     }
@@ -191,6 +197,8 @@ FSFolder_hard_link(FSFolder *self, const CharBuf *from,
 
 bool
 FSFolder_local_delete(FSFolder *self, const CharBuf *name) {
+    FSFolderIVARS *const ivars = FSFolder_IVARS(self);
+
     CharBuf *fullpath = S_fullpath(self, name);
     char    *path_ptr = (char*)CB_Get_Ptr8(fullpath);
 #ifdef CHY_REMOVE_ZAPS_DIRS
@@ -198,18 +206,21 @@ FSFolder_local_delete(FSFolder *self, const CharBuf *name) {
 #else
     bool result = !rmdir(path_ptr) || !remove(path_ptr);
 #endif
-    DECREF(Hash_Delete(self->entries, (Obj*)name));
+    DECREF(Hash_Delete(ivars->entries, (Obj*)name));
     DECREF(fullpath);
     return result;
 }
 
 void
 FSFolder_close(FSFolder *self) {
-    Hash_Clear(self->entries);
+    FSFolderIVARS *const ivars = FSFolder_IVARS(self);
+    Hash_Clear(ivars->entries);
 }
 
 Folder*
 FSFolder_local_find_folder(FSFolder *self, const CharBuf *name) {
+    FSFolderIVARS *const ivars = FSFolder_IVARS(self);
+
     Folder *subfolder = NULL;
     if (!name || !CB_Get_Size(name)) {
         // No entity can be identified by NULL or empty string.
@@ -222,7 +233,7 @@ FSFolder_local_find_folder(FSFolder *self, const CharBuf *name) {
         // Don't allow access outside of the main dir.
         return NULL;
     }
-    else if (NULL != (subfolder = (Folder*)Hash_Fetch(self->entries, (Obj*)name))) {
+    else if (NULL != (subfolder = (Folder*)Hash_Fetch(ivars->entries, (Obj*)name))) {
         if (Folder_Is_A(subfolder, FOLDER)) {
             return subfolder;
         }
@@ -248,7 +259,7 @@ FSFolder_local_find_folder(FSFolder *self, const CharBuf *name) {
                 subfolder = (Folder*)cf_reader;
             }
         }
-        Hash_Store(self->entries, (Obj*)name, (Obj*)subfolder);
+        Hash_Store(ivars->entries, (Obj*)name, (Obj*)subfolder);
     }
     DECREF(fullpath);
 
@@ -257,7 +268,8 @@ FSFolder_local_find_folder(FSFolder *self, const CharBuf *name) {
 
 static CharBuf*
 S_fullpath(FSFolder *self, const CharBuf *path) {
-    CharBuf *fullpath = CB_newf("%o%s%o", self->path, DIR_SEP, path);
+    FSFolderIVARS *const ivars = FSFolder_IVARS(self);
+    CharBuf *fullpath = CB_newf("%o%s%o", ivars->path, DIR_SEP, path);
     if (DIR_SEP[0] != '/') {
         CB_Swap_Chars(fullpath, '/', DIR_SEP[0]);
     }

http://git-wip-us.apache.org/repos/asf/lucy/blob/d04580a1/core/Lucy/Store/FileHandle.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/FileHandle.c b/core/Lucy/Store/FileHandle.c
index 9b37809..4fcb235 100644
--- a/core/Lucy/Store/FileHandle.c
+++ b/core/Lucy/Store/FileHandle.c
@@ -23,8 +23,9 @@ int32_t FH_object_count = 0;
 
 FileHandle*
 FH_do_open(FileHandle *self, const CharBuf *path, uint32_t flags) {
-    self->path    = path ? CB_Clone(path) : CB_new(0);
-    self->flags   = flags;
+    FileHandleIVARS *const ivars = FH_IVARS(self);
+    ivars->path    = path ? CB_Clone(path) : CB_new(0);
+    ivars->flags   = flags;
 
     // Track number of live FileHandles released into the wild.
     FH_object_count++;
@@ -35,8 +36,9 @@ FH_do_open(FileHandle *self, const CharBuf *path, uint32_t flags) {
 
 void
 FH_destroy(FileHandle *self) {
+    FileHandleIVARS *const ivars = FH_IVARS(self);
     FH_Close(self);
-    DECREF(self->path);
+    DECREF(ivars->path);
     SUPER_DESTROY(self, FILEHANDLE);
 
     // Decrement count of FileHandle objects in existence.
@@ -52,12 +54,13 @@ FH_grow(FileHandle *self, int64_t length) {
 
 void
 FH_set_path(FileHandle *self, const CharBuf *path) {
-    CB_Mimic(self->path, (Obj*)path);
+    FileHandleIVARS *const ivars = FH_IVARS(self);
+    CB_Mimic(ivars->path, (Obj*)path);
 }
 
 CharBuf*
 FH_get_path(FileHandle *self) {
-    return self->path;
+    return FH_IVARS(self)->path;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/d04580a1/core/Lucy/Store/FileWindow.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/FileWindow.c b/core/Lucy/Store/FileWindow.c
index 51b747e..067c6a8 100644
--- a/core/Lucy/Store/FileWindow.c
+++ b/core/Lucy/Store/FileWindow.c
@@ -32,21 +32,23 @@ FileWindow_init(FileWindow *self) {
 
 void
 FileWindow_set_offset(FileWindow *self, int64_t offset) {
-    if (self->buf != NULL) {
-        if (offset != self->offset) {
+    FileWindowIVARS *const ivars = FileWindow_IVARS(self);
+    if (ivars->buf != NULL) {
+        if (offset != ivars->offset) {
             THROW(ERR, "Can't set offset to %i64 instead of %i64 unless buf "
-                  "is NULL", offset, self->offset);
+                  "is NULL", offset, ivars->offset);
         }
     }
-    self->offset = offset;
+    ivars->offset = offset;
 }
 
 void
 FileWindow_set_window(FileWindow *self, char *buf, int64_t offset,
                       int64_t len) {
-    self->buf    = buf;
-    self->offset = offset;
-    self->len    = len;
+    FileWindowIVARS *const ivars = FileWindow_IVARS(self);
+    ivars->buf    = buf;
+    ivars->offset = offset;
+    ivars->len    = len;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/d04580a1/core/Lucy/Store/Folder.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/Folder.c b/core/Lucy/Store/Folder.c
index 414a189..d87db4b 100644
--- a/core/Lucy/Store/Folder.c
+++ b/core/Lucy/Store/Folder.c
@@ -30,18 +30,20 @@
 
 Folder*
 Folder_init(Folder *self, const CharBuf *path) {
+    FolderIVARS *const ivars = Folder_IVARS(self);
+
     // Init.
-    self->entries = Hash_new(16);
+    ivars->entries = Hash_new(16);
 
     // Copy.
     if (path == NULL) {
-        self->path = CB_new_from_trusted_utf8("", 0);
+        ivars->path = CB_new_from_trusted_utf8("", 0);
     }
     else {
         // Copy path, strip trailing slash or equivalent.
-        self->path = CB_Clone(path);
-        if (CB_Ends_With_Str(self->path, DIR_SEP, strlen(DIR_SEP))) {
-            CB_Chop(self->path, 1);
+        ivars->path = CB_Clone(path);
+        if (CB_Ends_With_Str(ivars->path, DIR_SEP, strlen(DIR_SEP))) {
+            CB_Chop(ivars->path, 1);
         }
     }
 
@@ -51,8 +53,9 @@ Folder_init(Folder *self, const CharBuf *path) {
 
 void
 Folder_destroy(Folder *self) {
-    DECREF(self->path);
-    DECREF(self->entries);
+    FolderIVARS *const ivars = Folder_IVARS(self);
+    DECREF(ivars->path);
+    DECREF(ivars->entries);
     SUPER_DESTROY(self, FOLDER);
 }
 
@@ -382,13 +385,14 @@ Folder_slurp_file(Folder *self, const CharBuf *path) {
 
 CharBuf*
 Folder_get_path(Folder *self) {
-    return self->path;
+    return Folder_IVARS(self)->path;
 }
 
 void
 Folder_set_path(Folder *self, const CharBuf *path) {
-    DECREF(self->path);
-    self->path = CB_Clone(path);
+    FolderIVARS *const ivars = Folder_IVARS(self);
+    DECREF(ivars->path);
+    ivars->path = CB_Clone(path);
 }
 
 void
@@ -409,7 +413,8 @@ Folder_consolidate(Folder *self, const CharBuf *path) {
             ZombieCharBuf *name = IxFileNames_local_part(path, ZCB_BLANK());
             CompoundFileReader *cf_reader = CFReader_open(folder);
             if (!cf_reader) { RETHROW(INCREF(Err_get_error())); }
-            Hash_Store(enclosing_folder->entries, (Obj*)name,
+            Hash *entries = Folder_IVARS(enclosing_folder)->entries;
+            Hash_Store(entries, (Obj*)name,
                        (Obj*)cf_reader);
         }
     }

http://git-wip-us.apache.org/repos/asf/lucy/blob/d04580a1/core/Lucy/Store/InStream.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/InStream.c b/core/Lucy/Store/InStream.c
index 977d4a4..7727a11 100644
--- a/core/Lucy/Store/InStream.c
+++ b/core/Lucy/Store/InStream.c
@@ -35,7 +35,7 @@ SI_read_bytes(InStream *self, char* buf, size_t len);
 
 // Inlined version of InStream_Read_U8.
 static INLINE uint8_t
-SI_read_u8(InStream *self);
+SI_read_u8(InStream *self, InStreamIVARS *const ivars);
 
 // Ensure that the buffer contains exactly the specified amount of data.
 static void
@@ -55,22 +55,24 @@ InStream_open(Obj *file) {
 
 InStream*
 InStream_do_open(InStream *self, Obj *file) {
+    InStreamIVARS *const ivars = InStream_IVARS(self);
+
     // Init.
-    self->buf           = NULL;
-    self->limit         = NULL;
-    self->offset        = 0;
-    self->window        = FileWindow_new();
+    ivars->buf          = NULL;
+    ivars->limit        = NULL;
+    ivars->offset       = 0;
+    ivars->window       = FileWindow_new();
 
     // Obtain a FileHandle.
     if (Obj_Is_A(file, FILEHANDLE)) {
-        self->file_handle = (FileHandle*)INCREF(file);
+        ivars->file_handle = (FileHandle*)INCREF(file);
     }
     else if (Obj_Is_A(file, RAMFILE)) {
-        self->file_handle
+        ivars->file_handle
             = (FileHandle*)RAMFH_open(NULL, FH_READ_ONLY, (RAMFile*)file);
     }
     else if (Obj_Is_A(file, CHARBUF)) {
-        self->file_handle
+        ivars->file_handle
             = (FileHandle*)FSFH_open((CharBuf*)file, FH_READ_ONLY);
     }
     else {
@@ -79,16 +81,16 @@ InStream_do_open(InStream *self, Obj *file) {
         DECREF(self);
         return NULL;
     }
-    if (!self->file_handle) {
+    if (!ivars->file_handle) {
         ERR_ADD_FRAME(Err_get_error());
         DECREF(self);
         return NULL;
     }
 
     // Get length and filename from the FileHandle.
-    self->filename      = CB_Clone(FH_Get_Path(self->file_handle));
-    self->len           = FH_Length(self->file_handle);
-    if (self->len == -1) {
+    ivars->filename     = CB_Clone(FH_Get_Path(ivars->file_handle));
+    ivars->len          = FH_Length(ivars->file_handle);
+    if (ivars->len == -1) {
         ERR_ADD_FRAME(Err_get_error());
         DECREF(self);
         return NULL;
@@ -99,70 +101,79 @@ InStream_do_open(InStream *self, Obj *file) {
 
 void
 InStream_close(InStream *self) {
-    if (self->file_handle) {
-        FH_Release_Window(self->file_handle, self->window);
+    InStreamIVARS *const ivars = InStream_IVARS(self);
+    if (ivars->file_handle) {
+        FH_Release_Window(ivars->file_handle, ivars->window);
         // Note that we don't close the FileHandle, because it's probably
         // shared.
-        DECREF(self->file_handle);
-        self->file_handle = NULL;
+        DECREF(ivars->file_handle);
+        ivars->file_handle = NULL;
     }
 }
 
 void
 InStream_destroy(InStream *self) {
-    if (self->file_handle) {
+    InStreamIVARS *const ivars = InStream_IVARS(self);
+    if (ivars->file_handle) {
         InStream_Close(self);
     }
-    DECREF(self->filename);
-    DECREF(self->window);
+    DECREF(ivars->filename);
+    DECREF(ivars->window);
     SUPER_DESTROY(self, INSTREAM);
 }
 
 InStream*
 InStream_reopen(InStream *self, const CharBuf *filename, int64_t offset,
                 int64_t len) {
-    if (!self->file_handle) {
-        THROW(ERR, "Can't Reopen() closed InStream %o", self->filename);
+    InStreamIVARS *const ivars = InStream_IVARS(self);
+    if (!ivars->file_handle) {
+        THROW(ERR, "Can't Reopen() closed InStream %o", ivars->filename);
     }
-    if (offset + len > FH_Length(self->file_handle)) {
+    if (offset + len > FH_Length(ivars->file_handle)) {
         THROW(ERR, "Offset + length too large (%i64 + %i64 > %i64)",
-              offset, len, FH_Length(self->file_handle));
+              offset, len, FH_Length(ivars->file_handle));
     }
 
-    InStream *twin = (InStream*)VTable_Make_Obj(self->vtable);
-    InStream_do_open(twin, (Obj*)self->file_handle);
-    if (filename != NULL) { CB_Mimic(twin->filename, (Obj*)filename); }
-    twin->offset = offset;
-    twin->len    = len;
-    InStream_Seek(twin, 0);
+    VTable *vtable = InStream_Get_VTable(self);
+    InStream *other = (InStream*)VTable_Make_Obj(vtable);
+    InStreamIVARS *const ovars = InStream_IVARS(other);
+    InStream_do_open(other, (Obj*)ivars->file_handle);
+    if (filename != NULL) { CB_Mimic(ovars->filename, (Obj*)filename); }
+    ovars->offset = offset;
+    ovars->len    = len;
+    InStream_Seek(other, 0);
 
-    return twin;
+    return other;
 }
 
 InStream*
 InStream_clone(InStream *self) {
-    InStream *twin = (InStream*)VTable_Make_Obj(self->vtable);
-    InStream_do_open(twin, (Obj*)self->file_handle);
+    InStreamIVARS *const ivars = InStream_IVARS(self);
+    VTable *vtable = InStream_Get_VTable(self);
+    InStream *twin = (InStream*)VTable_Make_Obj(vtable);
+    InStream_do_open(twin, (Obj*)ivars->file_handle);
     InStream_Seek(twin, SI_tell(self));
     return twin;
 }
 
 CharBuf*
 InStream_get_filename(InStream *self) {
-    return self->filename;
+    return InStream_IVARS(self)->filename;
 }
 
 static int64_t
 S_refill(InStream *self) {
+    InStreamIVARS *const ivars = InStream_IVARS(self);
+
     // Determine the amount to request.
     const int64_t sub_file_pos = SI_tell(self);
-    const int64_t remaining    = self->len - sub_file_pos;
+    const int64_t remaining    = ivars->len - sub_file_pos;
     const int64_t amount       = remaining < IO_STREAM_BUF_SIZE
                                  ? remaining
                                  : IO_STREAM_BUF_SIZE;
     if (!remaining) {
         THROW(ERR, "Read past EOF of '%o' (offset: %i64 len: %i64)",
-              self->filename, self->offset, self->len);
+              ivars->filename, ivars->offset, ivars->len);
     }
 
     // Make the request.
@@ -178,31 +189,32 @@ InStream_refill(InStream *self) {
 
 static void
 S_fill(InStream *self, int64_t amount) {
-    FileWindow *const window     = self->window;
+    InStreamIVARS *const ivars     = InStream_IVARS(self);
+    FileWindow *const window       = ivars->window;
     const int64_t virtual_file_pos = SI_tell(self);
-    const int64_t real_file_pos    = virtual_file_pos + self->offset;
-    const int64_t remaining        = self->len - virtual_file_pos;
+    const int64_t real_file_pos    = virtual_file_pos + ivars->offset;
+    const int64_t remaining        = ivars->len - virtual_file_pos;
 
     // Throw an error if the requested amount would take us beyond EOF.
     if (amount > remaining) {
         THROW(ERR,  "Read past EOF of %o (pos: %u64 len: %u64 request: %u64)",
-              self->filename, virtual_file_pos, self->len, amount);
+              ivars->filename, virtual_file_pos, ivars->len, amount);
     }
 
     // Make the request.
-    if (FH_Window(self->file_handle, window, real_file_pos, amount)) {
+    if (FH_Window(ivars->file_handle, window, real_file_pos, amount)) {
         char *const window_limit = window->buf + window->len;
-        self->buf = window->buf
-                    - window->offset    // theoretical start of real file
-                    + self->offset      // top of virtual file
-                    + virtual_file_pos; // position within virtual file
-        self->limit = window_limit - self->buf > remaining
-                      ? self->buf + remaining
-                      : window_limit;
+        ivars->buf = window->buf
+                     - window->offset     // theoretical start of real file
+                     + ivars->offset      // top of virtual file
+                     + virtual_file_pos;  // position within virtual file
+        ivars->limit = window_limit - ivars->buf > remaining
+                       ? ivars->buf + remaining
+                       : window_limit;
     }
     else {
         Err *error = Err_get_error();
-        CB_catf(Err_Get_Mess(error), " (%o)", self->filename);
+        CB_catf(Err_Get_Mess(error), " (%o)", ivars->filename);
         RETHROW(INCREF(error));
     }
 }
@@ -214,40 +226,42 @@ InStream_fill(InStream *self, int64_t amount) {
 
 void
 InStream_seek(InStream *self, int64_t target) {
-    FileWindow *const window = self->window;
-    int64_t virtual_window_top = window->offset - self->offset;
+    InStreamIVARS *const ivars = InStream_IVARS(self);
+    FileWindow *const window = ivars->window;
+    int64_t virtual_window_top = window->offset - ivars->offset;
     int64_t virtual_window_end = virtual_window_top + window->len;
 
     if (target < 0) {
-        THROW(ERR, "Can't Seek '%o' to negative target %i64", self->filename,
+        THROW(ERR, "Can't Seek '%o' to negative target %i64", ivars->filename,
               target);
     }
     // Seek within window if possible.
     else if (target >= virtual_window_top
              && target <= virtual_window_end
             ) {
-        self->buf = window->buf - window->offset + self->offset + target;
+        ivars->buf = window->buf - window->offset + ivars->offset + target;
     }
-    else if (target > self->len) {
-        THROW(ERR, "Can't Seek '%o' past EOF (%i64 > %i64)", self->filename,
-              target, self->len);
+    else if (target > ivars->len) {
+        THROW(ERR, "Can't Seek '%o' past EOF (%i64 > %i64)", ivars->filename,
+              target, ivars->len);
     }
     else {
         // Target is outside window.  Set all buffer and limit variables to
         // NULL to trigger refill on the next read.  Store the file position
         // in the FileWindow's offset.
-        FH_Release_Window(self->file_handle, window);
-        self->buf   = NULL;
-        self->limit = NULL;
-        FileWindow_Set_Offset(window, self->offset + target);
+        FH_Release_Window(ivars->file_handle, window);
+        ivars->buf   = NULL;
+        ivars->limit = NULL;
+        FileWindow_Set_Offset(window, ivars->offset + target);
     }
 }
 
 static INLINE int64_t
 SI_tell(InStream *self) {
-    FileWindow *const window = self->window;
-    int64_t pos_in_buf = PTR_TO_I64(self->buf) - PTR_TO_I64(window->buf);
-    return pos_in_buf + window->offset - self->offset;
+    InStreamIVARS *const ivars = InStream_IVARS(self);
+    FileWindow *const window = ivars->window;
+    int64_t pos_in_buf = PTR_TO_I64(ivars->buf) - PTR_TO_I64(window->buf);
+    return pos_in_buf + window->offset - ivars->offset;
 }
 
 int64_t
@@ -257,12 +271,13 @@ InStream_tell(InStream *self) {
 
 int64_t
 InStream_length(InStream *self) {
-    return self->len;
+    return InStream_IVARS(self)->len;
 }
 
 char*
 InStream_buf(InStream *self, size_t request) {
-    const int64_t bytes_in_buf = PTR_TO_I64(self->limit) - PTR_TO_I64(self->buf);
+    InStreamIVARS *const ivars = InStream_IVARS(self);
+    const int64_t bytes_in_buf = PTR_TO_I64(ivars->limit) - PTR_TO_I64(ivars->buf);
 
     /* It's common for client code to overestimate how much is needed, because
      * the request has to figure in worst-case for compressed data.  However,
@@ -270,7 +285,7 @@ InStream_buf(InStream *self, size_t request) {
      * bytes, they really need 1 byte, and there's 1k in the buffer), we can
      * skip the following refill block. */
     if ((int64_t)request > bytes_in_buf) {
-        const int64_t remaining_in_file = self->len - SI_tell(self);
+        const int64_t remaining_in_file = ivars->len - SI_tell(self);
         int64_t amount = request;
 
         // Try to bump up small requests.
@@ -286,22 +301,23 @@ InStream_buf(InStream *self, size_t request) {
         }
     }
 
-    return self->buf;
+    return ivars->buf;
 }
 
 void
 InStream_advance_buf(InStream *self, char *buf) {
-    if (buf > self->limit) {
-        int64_t overrun = PTR_TO_I64(buf) - PTR_TO_I64(self->limit);
+    InStreamIVARS *const ivars = InStream_IVARS(self);
+    if (buf > ivars->limit) {
+        int64_t overrun = PTR_TO_I64(buf) - PTR_TO_I64(ivars->limit);
         THROW(ERR, "Supplied value is %i64 bytes beyond end of buffer",
               overrun);
     }
-    else if (buf < self->buf) {
-        int64_t underrun = PTR_TO_I64(self->buf) - PTR_TO_I64(buf);
+    else if (buf < ivars->buf) {
+        int64_t underrun = PTR_TO_I64(ivars->buf) - PTR_TO_I64(buf);
         THROW(ERR, "Can't Advance_Buf backwards: (underrun: %i64))", underrun);
     }
     else {
-        self->buf = buf;
+        ivars->buf = buf;
     }
 }
 
@@ -312,19 +328,20 @@ InStream_read_bytes(InStream *self, char* buf, size_t len) {
 
 static INLINE void
 SI_read_bytes(InStream *self, char* buf, size_t len) {
-    const int64_t available = PTR_TO_I64(self->limit) - PTR_TO_I64(self->buf);
+    InStreamIVARS *const ivars = InStream_IVARS(self);
+    const int64_t available = PTR_TO_I64(ivars->limit) - PTR_TO_I64(ivars->buf);
     if (available >= (int64_t)len) {
         // Request is entirely within buffer, so copy.
-        memcpy(buf, self->buf, len);
-        self->buf += len;
+        memcpy(buf, ivars->buf, len);
+        ivars->buf += len;
     }
     else {
         // Pass along whatever we've got in the buffer.
         if (available > 0) {
-            memcpy(buf, self->buf, (size_t)available);
+            memcpy(buf, ivars->buf, (size_t)available);
             buf += available;
             len -= (size_t)available;
-            self->buf += available;
+            ivars->buf += available;
         }
 
         if (len < IO_STREAM_BUF_SIZE) {
@@ -334,19 +351,19 @@ SI_read_bytes(InStream *self, char* buf, size_t len) {
                 int64_t orig_pos = SI_tell(self) - available;
                 int64_t orig_len = len + available;
                 THROW(ERR,  "Read past EOF of %o (pos: %i64 len: %i64 "
-                      "request: %i64)", self->filename, orig_pos,
-                      self->len, orig_len);
+                      "request: %i64)", ivars->filename, orig_pos,
+                      ivars->len, orig_len);
             }
-            memcpy(buf, self->buf, len);
-            self->buf += len;
+            memcpy(buf, ivars->buf, len);
+            ivars->buf += len;
         }
         else {
             // Too big to handle via the buffer, so resort to a brute-force
             // read.
             const int64_t sub_file_pos  = SI_tell(self);
-            const int64_t real_file_pos = sub_file_pos + self->offset;
+            const int64_t real_file_pos = sub_file_pos + ivars->offset;
             bool success
-                = FH_Read(self->file_handle, buf, real_file_pos, len);
+                = FH_Read(ivars->file_handle, buf, real_file_pos, len);
             if (!success) {
                 RETHROW(INCREF(Err_get_error()));
             }
@@ -357,18 +374,20 @@ SI_read_bytes(InStream *self, char* buf, size_t len) {
 
 int8_t
 InStream_read_i8(InStream *self) {
-    return (int8_t)SI_read_u8(self);
+    InStreamIVARS *const ivars = InStream_IVARS(self);
+    return (int8_t)SI_read_u8(self, ivars);
 }
 
 static INLINE uint8_t
-SI_read_u8(InStream *self) {
-    if (self->buf >= self->limit) { S_refill(self); }
-    return (uint8_t)(*self->buf++);
+SI_read_u8(InStream *self, InStreamIVARS *ivars) {
+    if (ivars->buf >= ivars->limit) { S_refill(self); }
+    return (uint8_t)(*ivars->buf++);
 }
 
 uint8_t
 InStream_read_u8(InStream *self) {
-    return SI_read_u8(self);
+    InStreamIVARS *const ivars = InStream_IVARS(self);
+    return SI_read_u8(self, ivars);
 }
 
 static INLINE uint32_t
@@ -433,9 +452,10 @@ InStream_read_f64(InStream *self) {
 
 uint32_t
 InStream_read_c32(InStream *self) {
+    InStreamIVARS *const ivars = InStream_IVARS(self);
     uint32_t retval = 0;
     while (1) {
-        const uint8_t ubyte = SI_read_u8(self);
+        const uint8_t ubyte = SI_read_u8(self, ivars);
         retval = (retval << 7) | (ubyte & 0x7f);
         if ((ubyte & 0x80) == 0) {
             break;
@@ -446,9 +466,10 @@ InStream_read_c32(InStream *self) {
 
 uint64_t
 InStream_read_c64(InStream *self) {
+    InStreamIVARS *const ivars = InStream_IVARS(self);
     uint64_t retval = 0;
     while (1) {
-        const uint8_t ubyte = SI_read_u8(self);
+        const uint8_t ubyte = SI_read_u8(self, ivars);
         retval = (retval << 7) | (ubyte & 0x7f);
         if ((ubyte & 0x80) == 0) {
             break;
@@ -459,9 +480,10 @@ InStream_read_c64(InStream *self) {
 
 int
 InStream_read_raw_c64(InStream *self, char *buf) {
+    InStreamIVARS *const ivars = InStream_IVARS(self);
     uint8_t *dest = (uint8_t*)buf;
     do {
-        *dest = SI_read_u8(self);
+        *dest = SI_read_u8(self, ivars);
     } while ((*dest++ & 0x80) != 0);
     return dest - (uint8_t*)buf;
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/d04580a1/core/Lucy/Store/Lock.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/Lock.c b/core/Lucy/Store/Lock.c
index 323b01d..6e8c68a 100644
--- a/core/Lucy/Store/Lock.c
+++ b/core/Lucy/Store/Lock.c
@@ -32,6 +32,8 @@
 Lock*
 Lock_init(Lock *self, Folder *folder, const CharBuf *name,
           const CharBuf *host, int32_t timeout, int32_t interval) {
+    LockIVARS *const ivars = Lock_IVARS(self);
+
     // Validate.
     if (interval <= 0) {
         DECREF(self);
@@ -52,51 +54,53 @@ Lock_init(Lock *self, Folder *folder, const CharBuf *name,
     }
 
     // Assign.
-    self->folder       = (Folder*)INCREF(folder);
-    self->timeout      = timeout;
-    self->name         = CB_Clone(name);
-    self->host         = CB_Clone(host);
-    self->interval     = interval;
+    ivars->folder       = (Folder*)INCREF(folder);
+    ivars->timeout      = timeout;
+    ivars->name         = CB_Clone(name);
+    ivars->host         = CB_Clone(host);
+    ivars->interval     = interval;
 
     // Derive.
-    self->lock_path = CB_newf("locks/%o.lock", name);
+    ivars->lock_path = CB_newf("locks/%o.lock", name);
 
     return self;
 }
 
 void
 Lock_destroy(Lock *self) {
-    DECREF(self->folder);
-    DECREF(self->host);
-    DECREF(self->name);
-    DECREF(self->lock_path);
+    LockIVARS *const ivars = Lock_IVARS(self);
+    DECREF(ivars->folder);
+    DECREF(ivars->host);
+    DECREF(ivars->name);
+    DECREF(ivars->lock_path);
     SUPER_DESTROY(self, LOCK);
 }
 
 CharBuf*
 Lock_get_name(Lock *self) {
-    return self->name;
+    return Lock_IVARS(self)->name;
 }
 
 CharBuf*
 Lock_get_lock_path(Lock *self) {
-    return self->lock_path;
+    return Lock_IVARS(self)->lock_path;
 }
 
 CharBuf*
 Lock_get_host(Lock *self) {
-    return self->host;
+    return Lock_IVARS(self)->host;
 }
 
 bool
 Lock_obtain(Lock *self) {
-    int32_t time_left = self->interval == 0 ? 0 : self->timeout;
+    LockIVARS *const ivars = Lock_IVARS(self);
+    int32_t time_left = ivars->interval == 0 ? 0 : ivars->timeout;
     bool locked = Lock_Request(self);
 
     while (!locked) {
-        time_left -= self->interval;
+        time_left -= ivars->interval;
         if (time_left <= 0) { break; }
-        Sleep_millisleep(self->interval);
+        Sleep_millisleep(ivars->interval);
         locked = Lock_Request(self);
     }
 
@@ -118,7 +122,8 @@ LFLock_init(LockFileLock *self, Folder *folder, const CharBuf *name,
             const CharBuf *host, int32_t timeout, int32_t interval) {
     int pid = PID_getpid();
     Lock_init((Lock*)self, folder, name, host, timeout, interval);
-    self->link_path = CB_newf("%o.%o.%i64", self->lock_path, host, pid);
+    LockFileLockIVARS *const ivars = LFLock_IVARS(self);
+    ivars->link_path = CB_newf("%o.%o.%i64", ivars->lock_path, host, pid);
     return self;
 }
 
@@ -129,26 +134,27 @@ LFLock_shared(LockFileLock *self) {
 
 bool
 LFLock_request(LockFileLock *self) {
+    LockFileLockIVARS *const ivars = LFLock_IVARS(self);
     Hash   *file_data;
     bool wrote_json;
     bool success = false;
     bool deletion_failed = false;
 
-    if (Folder_Exists(self->folder, self->lock_path)) {
+    if (Folder_Exists(ivars->folder, ivars->lock_path)) {
         Err_set_error((Err*)LockErr_new(CB_newf("Can't obtain lock: '%o' exists",
-                                                self->lock_path)));
+                                                ivars->lock_path)));
         return false;
     }
 
     // Create the "locks" subdirectory if necessary.
     CharBuf *lock_dir_name = (CharBuf*)ZCB_WRAP_STR("locks", 5);
-    if (!Folder_Exists(self->folder, lock_dir_name)) {
-        if (!Folder_MkDir(self->folder, lock_dir_name)) {
+    if (!Folder_Exists(ivars->folder, lock_dir_name)) {
+        if (!Folder_MkDir(ivars->folder, lock_dir_name)) {
             Err *mkdir_err = (Err*)CERTIFY(Err_get_error(), ERR);
             LockErr *err = LockErr_new(CB_newf("Can't create 'locks' directory: %o",
                                                Err_Get_Mess(mkdir_err)));
             // Maybe our attempt failed because another process succeeded.
-            if (Folder_Find_Folder(self->folder, lock_dir_name)) {
+            if (Folder_Find_Folder(ivars->folder, lock_dir_name)) {
                 DECREF(err);
             }
             else {
@@ -163,35 +169,35 @@ LFLock_request(LockFileLock *self) {
     file_data = Hash_new(3);
     Hash_Store_Str(file_data, "pid", 3,
                    (Obj*)CB_newf("%i32", (int32_t)PID_getpid()));
-    Hash_Store_Str(file_data, "host", 4, INCREF(self->host));
-    Hash_Store_Str(file_data, "name", 4, INCREF(self->name));
+    Hash_Store_Str(file_data, "host", 4, INCREF(ivars->host));
+    Hash_Store_Str(file_data, "name", 4, INCREF(ivars->name));
 
     // Write to a temporary file, then use the creation of a hard link to
     // ensure atomic but non-destructive creation of the lockfile with its
     // complete contents.
-    wrote_json = Json_spew_json((Obj*)file_data, self->folder, self->link_path);
+    wrote_json = Json_spew_json((Obj*)file_data, ivars->folder, ivars->link_path);
     if (wrote_json) {
-        success = Folder_Hard_Link(self->folder, self->link_path,
-                                   self->lock_path);
+        success = Folder_Hard_Link(ivars->folder, ivars->link_path,
+                                   ivars->lock_path);
         if (!success) {
             Err *hard_link_err = (Err*)CERTIFY(Err_get_error(), ERR);
             Err_set_error((Err*)LockErr_new(CB_newf("Failed to obtain lock at '%o': %o",
-                                                    self->lock_path,
+                                                    ivars->lock_path,
                                                     Err_Get_Mess(hard_link_err))));
         }
-        deletion_failed = !Folder_Delete(self->folder, self->link_path);
+        deletion_failed = !Folder_Delete(ivars->folder, ivars->link_path);
     }
     else {
         Err *spew_json_err = (Err*)CERTIFY(Err_get_error(), ERR);
         Err_set_error((Err*)LockErr_new(CB_newf("Failed to obtain lock at '%o': %o",
-                                                self->lock_path,
+                                                ivars->lock_path,
                                                 Err_Get_Mess(spew_json_err))));
     }
     DECREF(file_data);
 
     // Verify that our temporary file got zapped.
     if (wrote_json && deletion_failed) {
-        CharBuf *mess = MAKE_MESS("Failed to delete '%o'", self->link_path);
+        CharBuf *mess = MAKE_MESS("Failed to delete '%o'", ivars->link_path);
         Err_throw_mess(ERR, mess);
     }
 
@@ -200,25 +206,29 @@ LFLock_request(LockFileLock *self) {
 
 void
 LFLock_release(LockFileLock *self) {
-    if (Folder_Exists(self->folder, self->lock_path)) {
-        LFLock_Maybe_Delete_File(self, self->lock_path, true, false);
+    LockFileLockIVARS *const ivars = LFLock_IVARS(self);
+    if (Folder_Exists(ivars->folder, ivars->lock_path)) {
+        LFLock_Maybe_Delete_File(self, ivars->lock_path, true, false);
     }
 }
 
 bool
 LFLock_is_locked(LockFileLock *self) {
-    return Folder_Exists(self->folder, self->lock_path);
+    LockFileLockIVARS *const ivars = LFLock_IVARS(self);
+    return Folder_Exists(ivars->folder, ivars->lock_path);
 }
 
 void
 LFLock_clear_stale(LockFileLock *self) {
-    LFLock_Maybe_Delete_File(self, self->lock_path, false, true);
+    LockFileLockIVARS *const ivars = LFLock_IVARS(self);
+    LFLock_Maybe_Delete_File(self, ivars->lock_path, false, true);
 }
 
 bool
 LFLock_maybe_delete_file(LockFileLock *self, const CharBuf *path,
                          bool delete_mine, bool delete_other) {
-    Folder *folder  = self->folder;
+    LockFileLockIVARS *const ivars = LFLock_IVARS(self);
+    Folder *folder  = ivars->folder;
     bool    success = false;
     ZombieCharBuf *scratch = ZCB_WRAP(path);
 
@@ -228,7 +238,7 @@ LFLock_maybe_delete_file(LockFileLock *self, const CharBuf *path,
         return false;
     }
     ZCB_Nip(scratch, CB_Get_Size(lock_dir_name) + 1);
-    if (!ZCB_Starts_With(scratch, self->name)) {
+    if (!ZCB_Starts_With(scratch, ivars->name)) {
         return false;
     }
 
@@ -243,9 +253,9 @@ LFLock_maybe_delete_file(LockFileLock *self, const CharBuf *path,
 
             // Match hostname and lock name.
             if (host != NULL
-                && CB_Equals(host, (Obj*)self->host)
+                && CB_Equals(host, (Obj*)ivars->host)
                 && name != NULL
-                && CB_Equals(name, (Obj*)self->name)
+                && CB_Equals(name, (Obj*)ivars->name)
                 && pid_buf != NULL
                ) {
                 // Verify that pid is either mine or dead.
@@ -273,7 +283,8 @@ LFLock_maybe_delete_file(LockFileLock *self, const CharBuf *path,
 
 void
 LFLock_destroy(LockFileLock *self) {
-    DECREF(self->link_path);
+    LockFileLockIVARS *const ivars = LFLock_IVARS(self);
+    DECREF(ivars->link_path);
     SUPER_DESTROY(self, LOCKFILELOCK);
 }
 


[lucy-commits] [05/34] git commit: refs/heads/master - Update Lucy search classes with IVARS.

Posted by ma...@apache.org.
Update Lucy search classes with IVARS.

Change all Lucy's search classes to access instance vars via an IVARS
struct rather than via `self`.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/ec90e666
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/ec90e666
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/ec90e666

Branch: refs/heads/master
Commit: ec90e66649a84224500a5db600cfb2c59940c35f
Parents: 59bd0cd
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Wed Jun 26 16:34:52 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 15:50:06 2013 -0700

----------------------------------------------------------------------
 core/Lucy/Search/ANDMatcher.c              |  49 ++---
 core/Lucy/Search/ANDQuery.c                |  12 +-
 core/Lucy/Search/BitVecMatcher.c           |  20 ++-
 core/Lucy/Search/Collector.c               |  57 +++---
 core/Lucy/Search/Compiler.c                |  48 ++---
 core/Lucy/Search/HitQueue.c                |  80 +++++----
 core/Lucy/Search/Hits.c                    |  31 ++--
 core/Lucy/Search/IndexSearcher.c           |  57 +++---
 core/Lucy/Search/LeafQuery.c               |  54 +++---
 core/Lucy/Search/MatchAllMatcher.c         |  20 ++-
 core/Lucy/Search/MatchAllQuery.c           |   5 +-
 core/Lucy/Search/MatchDoc.c                |  41 +++--
 core/Lucy/Search/NOTMatcher.c              |  41 +++--
 core/Lucy/Search/NOTQuery.c                |  12 +-
 core/Lucy/Search/NoMatchQuery.c            |  27 +--
 core/Lucy/Search/ORMatcher.c               | 229 +++++++++++++-----------
 core/Lucy/Search/ORQuery.c                 |  12 +-
 core/Lucy/Search/PhraseMatcher.c           | 106 ++++++-----
 core/Lucy/Search/PhraseQuery.c             | 126 +++++++------
 core/Lucy/Search/PolyMatcher.c             |  22 +--
 core/Lucy/Search/PolyQuery.c               |  73 +++++---
 core/Lucy/Search/PolySearcher.c            |  45 +++--
 core/Lucy/Search/Query.c                   |   8 +-
 core/Lucy/Search/QueryParser.c             |  87 +++++----
 core/Lucy/Search/RangeMatcher.c            |  29 +--
 core/Lucy/Search/RangeQuery.c              |  98 +++++-----
 core/Lucy/Search/RequiredOptionalMatcher.c |  62 ++++---
 core/Lucy/Search/RequiredOptionalQuery.c   |  27 +--
 core/Lucy/Search/Searcher.c                |  19 +-
 core/Lucy/Search/SeriesMatcher.c           |  64 +++----
 core/Lucy/Search/SortRule.c                |  34 ++--
 core/Lucy/Search/SortSpec.c                |  13 +-
 core/Lucy/Search/Span.c                    |  38 ++--
 core/Lucy/Search/TermMatcher.c             |  35 ++--
 core/Lucy/Search/TermQuery.c               | 130 ++++++++------
 core/Lucy/Search/TopDocs.c                 |  29 +--
 36 files changed, 1037 insertions(+), 803 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/ANDMatcher.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/ANDMatcher.c b/core/Lucy/Search/ANDMatcher.c
index 03636b2..d6afb74 100644
--- a/core/Lucy/Search/ANDMatcher.c
+++ b/core/Lucy/Search/ANDMatcher.c
@@ -28,39 +28,42 @@ ANDMatcher_new(VArray *children, Similarity *sim) {
 
 ANDMatcher*
 ANDMatcher_init(ANDMatcher *self, VArray *children, Similarity *sim) {
+    ANDMatcherIVARS *const ivars = ANDMatcher_IVARS(self);
 
     // Init.
     PolyMatcher_init((PolyMatcher*)self, children, sim);
-    self->first_time       = true;
+    ivars->first_time   = true;
 
     // Assign.
-    self->more             = self->num_kids ? true : false;
-    self->kids             = (Matcher**)MALLOCATE(self->num_kids * sizeof(Matcher*));
-    for (uint32_t i = 0; i < self->num_kids; i++) {
+    ivars->more         = ivars->num_kids ? true : false;
+    ivars->kids         = (Matcher**)MALLOCATE(ivars->num_kids * sizeof(Matcher*));
+    for (uint32_t i = 0; i < ivars->num_kids; i++) {
         Matcher *child = (Matcher*)VA_Fetch(children, i);
-        self->kids[i] = child;
-        if (!Matcher_Next(child)) { self->more = false; }
+        ivars->kids[i] = child;
+        if (!Matcher_Next(child)) { ivars->more = false; }
     }
 
     // Derive.
-    self->matching_kids = self->num_kids;
+    ivars->matching_kids = ivars->num_kids;
 
     return self;
 }
 
 void
 ANDMatcher_destroy(ANDMatcher *self) {
-    FREEMEM(self->kids);
+    ANDMatcherIVARS *const ivars = ANDMatcher_IVARS(self);
+    FREEMEM(ivars->kids);
     SUPER_DESTROY(self, ANDMATCHER);
 }
 
 int32_t
 ANDMatcher_next(ANDMatcher *self) {
-    if (self->first_time) {
+    ANDMatcherIVARS *const ivars = ANDMatcher_IVARS(self);
+    if (ivars->first_time) {
         return ANDMatcher_Advance(self, 1);
     }
-    if (self->more) {
-        const int32_t target = Matcher_Get_Doc_ID(self->kids[0]) + 1;
+    if (ivars->more) {
+        const int32_t target = Matcher_Get_Doc_ID(ivars->kids[0]) + 1;
         return ANDMatcher_Advance(self, target);
     }
     else {
@@ -70,20 +73,21 @@ ANDMatcher_next(ANDMatcher *self) {
 
 int32_t
 ANDMatcher_advance(ANDMatcher *self, int32_t target) {
-    Matcher **const kids     = self->kids;
-    const uint32_t  num_kids = self->num_kids;
+    ANDMatcherIVARS *const ivars = ANDMatcher_IVARS(self);
+    Matcher **const kids     = ivars->kids;
+    const uint32_t  num_kids = ivars->num_kids;
     int32_t         highest  = 0;
 
-    if (!self->more) { return 0; }
+    if (!ivars->more) { return 0; }
 
     // First step: Advance first child and use its doc as a starting point.
-    if (self->first_time) {
-        self->first_time = false;
+    if (ivars->first_time) {
+        ivars->first_time = false;
     }
     else {
         highest = Matcher_Advance(kids[0], target);
         if (!highest) {
-            self->more = false;
+            ivars->more = false;
             return 0;
         }
     }
@@ -112,7 +116,7 @@ ANDMatcher_advance(ANDMatcher *self, int32_t target) {
                 // This Matcher is definitely the highest right now.
                 highest = Matcher_Advance(child, target);
                 if (!highest) {
-                    self->more = false;
+                    ivars->more = false;
                     return 0;
                 }
             }
@@ -141,19 +145,20 @@ ANDMatcher_advance(ANDMatcher *self, int32_t target) {
 
 int32_t
 ANDMatcher_get_doc_id(ANDMatcher *self) {
-    return Matcher_Get_Doc_ID(self->kids[0]);
+    return Matcher_Get_Doc_ID(ANDMatcher_IVARS(self)->kids[0]);
 }
 
 float
 ANDMatcher_score(ANDMatcher *self) {
-    Matcher **const kids = self->kids;
+    ANDMatcherIVARS *const ivars = ANDMatcher_IVARS(self);
+    Matcher **const kids = ivars->kids;
     float score = 0.0f;
 
-    for (uint32_t i = 0; i < self->num_kids; i++) {
+    for (uint32_t i = 0; i < ivars->num_kids; i++) {
         score += Matcher_Score(kids[i]);
     }
 
-    score *= self->coord_factors[self->matching_kids];
+    score *= ivars->coord_factors[ivars->matching_kids];
 
     return score;
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/ANDQuery.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/ANDQuery.c b/core/Lucy/Search/ANDQuery.c
index f7c367d..887f686 100644
--- a/core/Lucy/Search/ANDQuery.c
+++ b/core/Lucy/Search/ANDQuery.c
@@ -43,12 +43,13 @@ ANDQuery_init(ANDQuery *self, VArray *children) {
 
 CharBuf*
 ANDQuery_to_string(ANDQuery *self) {
-    uint32_t num_kids = VA_Get_Size(self->children);
+    ANDQueryIVARS *const ivars = ANDQuery_IVARS(self);
+    uint32_t num_kids = VA_Get_Size(ivars->children);
     if (!num_kids) { return CB_new_from_trusted_utf8("()", 2); }
     else {
         CharBuf *retval = CB_new_from_trusted_utf8("(", 1);
         for (uint32_t i = 0; i < num_kids; i++) {
-            CharBuf *kid_string = Obj_To_String(VA_Fetch(self->children, i));
+            CharBuf *kid_string = Obj_To_String(VA_Fetch(ivars->children, i));
             CB_Cat(retval, kid_string);
             DECREF(kid_string);
             if (i == num_kids - 1) {
@@ -99,10 +100,11 @@ ANDCompiler_init(ANDCompiler *self, ANDQuery *parent, Searcher *searcher,
 Matcher*
 ANDCompiler_make_matcher(ANDCompiler *self, SegReader *reader,
                          bool need_score) {
-    uint32_t num_kids = VA_Get_Size(self->children);
+    ANDCompilerIVARS *const ivars = ANDCompiler_IVARS(self);
+    uint32_t num_kids = VA_Get_Size(ivars->children);
 
     if (num_kids == 1) {
-        Compiler *only_child = (Compiler*)VA_Fetch(self->children, 0);
+        Compiler *only_child = (Compiler*)VA_Fetch(ivars->children, 0);
         return Compiler_Make_Matcher(only_child, reader, need_score);
     }
     else {
@@ -110,7 +112,7 @@ ANDCompiler_make_matcher(ANDCompiler *self, SegReader *reader,
 
         // Add child matchers one by one.
         for (uint32_t i = 0; i < num_kids; i++) {
-            Compiler *child = (Compiler*)VA_Fetch(self->children, i);
+            Compiler *child = (Compiler*)VA_Fetch(ivars->children, i);
             Matcher *child_matcher
                 = Compiler_Make_Matcher(child, reader, need_score);
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/BitVecMatcher.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/BitVecMatcher.c b/core/Lucy/Search/BitVecMatcher.c
index 7c9f25f..fea5018 100644
--- a/core/Lucy/Search/BitVecMatcher.c
+++ b/core/Lucy/Search/BitVecMatcher.c
@@ -27,33 +27,37 @@ BitVecMatcher_new(BitVector *bit_vector) {
 
 BitVecMatcher*
 BitVecMatcher_init(BitVecMatcher *self, BitVector *bit_vector) {
+    BitVecMatcherIVARS *const ivars = BitVecMatcher_IVARS(self);
     Matcher_init((Matcher*)self);
-    self->bit_vec = (BitVector*)INCREF(bit_vector);
-    self->doc_id = 0;
+    ivars->bit_vec = (BitVector*)INCREF(bit_vector);
+    ivars->doc_id = 0;
     return self;
 }
 
 void
 BitVecMatcher_destroy(BitVecMatcher *self) {
-    DECREF(self->bit_vec);
+    BitVecMatcherIVARS *const ivars = BitVecMatcher_IVARS(self);
+    DECREF(ivars->bit_vec);
     SUPER_DESTROY(self, BITVECMATCHER);
 }
 
 int32_t
 BitVecMatcher_next(BitVecMatcher *self) {
-    self->doc_id = BitVec_Next_Hit(self->bit_vec, self->doc_id + 1);
-    return self->doc_id == -1 ? 0 : self->doc_id;
+    BitVecMatcherIVARS *const ivars = BitVecMatcher_IVARS(self);
+    ivars->doc_id = BitVec_Next_Hit(ivars->bit_vec, ivars->doc_id + 1);
+    return ivars->doc_id == -1 ? 0 : ivars->doc_id;
 }
 
 int32_t
 BitVecMatcher_advance(BitVecMatcher *self, int32_t target) {
-    self->doc_id = BitVec_Next_Hit(self->bit_vec, target);
-    return self->doc_id == -1 ? 0 : self->doc_id;
+    BitVecMatcherIVARS *const ivars = BitVecMatcher_IVARS(self);
+    ivars->doc_id = BitVec_Next_Hit(ivars->bit_vec, target);
+    return ivars->doc_id == -1 ? 0 : ivars->doc_id;
 }
 
 int32_t
 BitVecMatcher_get_doc_id(BitVecMatcher *self) {
-    return self->doc_id;
+    return BitVecMatcher_IVARS(self)->doc_id;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/Collector.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/Collector.c b/core/Lucy/Search/Collector.c
index 4fa9a70..d11be0d 100644
--- a/core/Lucy/Search/Collector.c
+++ b/core/Lucy/Search/Collector.c
@@ -25,35 +25,39 @@
 
 Collector*
 Coll_init(Collector *self) {
+    CollectorIVARS *const ivars = Coll_IVARS(self);
     ABSTRACT_CLASS_CHECK(self, COLLECTOR);
-    self->reader  = NULL;
-    self->matcher = NULL;
-    self->base    = 0;
+    ivars->reader  = NULL;
+    ivars->matcher = NULL;
+    ivars->base    = 0;
     return self;
 }
 
 void
 Coll_destroy(Collector *self) {
-    DECREF(self->reader);
-    DECREF(self->matcher);
+    CollectorIVARS *const ivars = Coll_IVARS(self);
+    DECREF(ivars->reader);
+    DECREF(ivars->matcher);
     SUPER_DESTROY(self, COLLECTOR);
 }
 
 void
 Coll_set_reader(Collector *self, SegReader *reader) {
-    DECREF(self->reader);
-    self->reader = (SegReader*)INCREF(reader);
+    CollectorIVARS *const ivars = Coll_IVARS(self);
+    DECREF(ivars->reader);
+    ivars->reader = (SegReader*)INCREF(reader);
 }
 
 void
 Coll_set_matcher(Collector *self, Matcher *matcher) {
-    DECREF(self->matcher);
-    self->matcher = (Matcher*)INCREF(matcher);
+    CollectorIVARS *const ivars = Coll_IVARS(self);
+    DECREF(ivars->matcher);
+    ivars->matcher = (Matcher*)INCREF(matcher);
 }
 
 void
 Coll_set_base(Collector *self, int32_t base) {
-    self->base = base;
+    Coll_IVARS(self)->base = base;
 }
 
 BitCollector*
@@ -64,21 +68,25 @@ BitColl_new(BitVector *bit_vec) {
 
 BitCollector*
 BitColl_init(BitCollector *self, BitVector *bit_vec) {
+    BitCollectorIVARS *const ivars = BitColl_IVARS(self);
     Coll_init((Collector*)self);
-    self->bit_vec = (BitVector*)INCREF(bit_vec);
+    ivars->bit_vec = (BitVector*)INCREF(bit_vec);
     return self;
 }
 
 void
 BitColl_destroy(BitCollector *self) {
-    DECREF(self->bit_vec);
+    BitCollectorIVARS *const ivars = BitColl_IVARS(self);
+    DECREF(ivars->bit_vec);
     SUPER_DESTROY(self, BITCOLLECTOR);
 }
 
 void
 BitColl_collect(BitCollector *self, int32_t doc_id) {
+    BitCollectorIVARS *const ivars = BitColl_IVARS(self);
+
     // Add the doc_id to the BitVector.
-    BitVec_Set(self->bit_vec, (self->base + doc_id));
+    BitVec_Set(ivars->bit_vec, (ivars->base + doc_id));
 }
 
 bool
@@ -96,41 +104,48 @@ OffsetColl_new(Collector *inner_coll, int32_t offset) {
 
 OffsetCollector*
 OffsetColl_init(OffsetCollector *self, Collector *inner_coll, int32_t offset) {
+    OffsetCollectorIVARS *const ivars = OffsetColl_IVARS(self);
     Coll_init((Collector*)self);
-    self->offset     = offset;
-    self->inner_coll = (Collector*)INCREF(inner_coll);
+    ivars->offset     = offset;
+    ivars->inner_coll = (Collector*)INCREF(inner_coll);
     return self;
 }
 
 void
 OffsetColl_destroy(OffsetCollector *self) {
-    DECREF(self->inner_coll);
+    OffsetCollectorIVARS *const ivars = OffsetColl_IVARS(self);
+    DECREF(ivars->inner_coll);
     SUPER_DESTROY(self, OFFSETCOLLECTOR);
 }
 
 void
 OffsetColl_set_reader(OffsetCollector *self, SegReader *reader) {
-    Coll_Set_Reader(self->inner_coll, reader);
+    OffsetCollectorIVARS *const ivars = OffsetColl_IVARS(self);
+    Coll_Set_Reader(ivars->inner_coll, reader);
 }
 
 void
 OffsetColl_set_base(OffsetCollector *self, int32_t base) {
-    Coll_Set_Base(self->inner_coll, base);
+    OffsetCollectorIVARS *const ivars = OffsetColl_IVARS(self);
+    Coll_Set_Base(ivars->inner_coll, base);
 }
 
 void
 OffsetColl_set_matcher(OffsetCollector *self, Matcher *matcher) {
-    Coll_Set_Matcher(self->inner_coll, matcher);
+    OffsetCollectorIVARS *const ivars = OffsetColl_IVARS(self);
+    Coll_Set_Matcher(ivars->inner_coll, matcher);
 }
 
 void
 OffsetColl_collect(OffsetCollector *self, int32_t doc_id) {
-    Coll_Collect(self->inner_coll, (doc_id + self->offset));
+    OffsetCollectorIVARS *const ivars = OffsetColl_IVARS(self);
+    Coll_Collect(ivars->inner_coll, (doc_id + ivars->offset));
 }
 
 bool
 OffsetColl_need_score(OffsetCollector *self) {
-    return Coll_Need_Score(self->inner_coll);
+    OffsetCollectorIVARS *const ivars = OffsetColl_IVARS(self);
+    return Coll_Need_Score(ivars->inner_coll);
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/Compiler.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/Compiler.c b/core/Lucy/Search/Compiler.c
index 585add1..901cff0 100644
--- a/core/Lucy/Search/Compiler.c
+++ b/core/Lucy/Search/Compiler.c
@@ -32,21 +32,23 @@
 Compiler*
 Compiler_init(Compiler *self, Query *parent, Searcher *searcher,
               Similarity *sim, float boost) {
+    CompilerIVARS *const ivars = Compiler_IVARS(self);
     Query_init((Query*)self, boost);
     if (!sim) {
         Schema *schema = Searcher_Get_Schema(searcher);
         sim = Schema_Get_Similarity(schema);
     }
-    self->parent  = (Query*)INCREF(parent);
-    self->sim     = (Similarity*)INCREF(sim);
+    ivars->parent  = (Query*)INCREF(parent);
+    ivars->sim     = (Similarity*)INCREF(sim);
     ABSTRACT_CLASS_CHECK(self, COMPILER);
     return self;
 }
 
 void
 Compiler_destroy(Compiler *self) {
-    DECREF(self->parent);
-    DECREF(self->sim);
+    CompilerIVARS *const ivars = Compiler_IVARS(self);
+    DECREF(ivars->parent);
+    DECREF(ivars->sim);
     SUPER_DESTROY(self, COMPILER);
 }
 
@@ -57,12 +59,12 @@ Compiler_get_weight(Compiler *self) {
 
 Similarity*
 Compiler_get_similarity(Compiler *self) {
-    return self->sim;
+    return Compiler_IVARS(self)->sim;
 }
 
 Query*
 Compiler_get_parent(Compiler *self) {
-    return self->parent;
+    return Compiler_IVARS(self)->parent;
 }
 
 float
@@ -79,11 +81,13 @@ Compiler_apply_norm_factor(Compiler *self, float factor) {
 
 void
 Compiler_normalize(Compiler *self) {
+    CompilerIVARS *const ivars = Compiler_IVARS(self);
+
     // factor = (tf_q * idf_t)
     float factor = Compiler_Sum_Of_Squared_Weights(self);
 
     // factor /= norm_q
-    factor = Sim_Query_Norm(self->sim, factor);
+    factor = Sim_Query_Norm(ivars->sim, factor);
 
     // weight *= factor
     Compiler_Apply_Norm_Factor(self, factor);
@@ -101,7 +105,8 @@ Compiler_highlight_spans(Compiler *self, Searcher *searcher,
 
 CharBuf*
 Compiler_to_string(Compiler *self) {
-    CharBuf *stringified_query = Query_To_String(self->parent);
+    CompilerIVARS *const ivars = Compiler_IVARS(self);
+    CharBuf *stringified_query = Query_To_String(ivars->parent);
     CharBuf *string = CB_new_from_trusted_utf8("compiler(", 9);
     CB_Cat(string, stringified_query);
     CB_Cat_Trusted_Str(string, ")", 1);
@@ -111,28 +116,31 @@ Compiler_to_string(Compiler *self) {
 
 bool
 Compiler_equals(Compiler *self, Obj *other) {
-    Compiler *twin = (Compiler*)other;
-    if (twin == self)                                    { return true; }
-    if (!Obj_Is_A(other, COMPILER))                      { return false; }
-    if (self->boost != twin->boost)                      { return false; }
-    if (!Query_Equals(self->parent, (Obj*)twin->parent)) { return false; }
-    if (!Sim_Equals(self->sim, (Obj*)twin->sim))         { return false; }
+    if ((Compiler*)other == self)                          { return true; }
+    if (!Obj_Is_A(other, COMPILER))                        { return false; }
+    CompilerIVARS *const ivars = Compiler_IVARS(self);
+    CompilerIVARS *const ovars = Compiler_IVARS((Compiler*)other);
+    if (ivars->boost != ovars->boost)                      { return false; }
+    if (!Query_Equals(ivars->parent, (Obj*)ovars->parent)) { return false; }
+    if (!Sim_Equals(ivars->sim, (Obj*)ovars->sim))         { return false; }
     return true;
 }
 
 void
 Compiler_serialize(Compiler *self, OutStream *outstream) {
+    CompilerIVARS *const ivars = Compiler_IVARS(self);
     ABSTRACT_CLASS_CHECK(self, COMPILER);
-    OutStream_Write_F32(outstream, self->boost);
-    FREEZE(self->parent, outstream);
-    FREEZE(self->sim, outstream);
+    OutStream_Write_F32(outstream, ivars->boost);
+    FREEZE(ivars->parent, outstream);
+    FREEZE(ivars->sim, outstream);
 }
 
 Compiler*
 Compiler_deserialize(Compiler *self, InStream *instream) {
-    self->boost  = InStream_Read_F32(instream);
-    self->parent = (Query*)THAW(instream);
-    self->sim    = (Similarity*)THAW(instream);
+    CompilerIVARS *const ivars = Compiler_IVARS(self);
+    ivars->boost  = InStream_Read_F32(instream);
+    ivars->parent = (Query*)THAW(instream);
+    ivars->sim    = (Similarity*)THAW(instream);
     return self;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/HitQueue.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/HitQueue.c b/core/Lucy/Search/HitQueue.c
index 0930cb1..868fcae 100644
--- a/core/Lucy/Search/HitQueue.c
+++ b/core/Lucy/Search/HitQueue.c
@@ -45,6 +45,7 @@ HitQ_new(Schema *schema, SortSpec *sort_spec, uint32_t wanted) {
 HitQueue*
 HitQ_init(HitQueue *self, Schema *schema, SortSpec *sort_spec,
           uint32_t wanted) {
+    HitQueueIVARS *const ivars = HitQ_IVARS(self);
     if (sort_spec) {
         VArray   *rules      = SortSpec_Get_Rules(sort_spec);
         uint32_t  num_rules  = VA_Get_Size(rules);
@@ -54,10 +55,10 @@ HitQ_init(HitQueue *self, Schema *schema, SortSpec *sort_spec,
             THROW(ERR, "Can't supply sort_spec without schema");
         }
 
-        self->need_values = false;
-        self->num_actions = num_rules;
-        self->actions     = (uint8_t*)MALLOCATE(num_rules * sizeof(uint8_t));
-        self->field_types = (FieldType**)CALLOCATE(num_rules, sizeof(FieldType*));
+        ivars->need_values = false;
+        ivars->num_actions = num_rules;
+        ivars->actions     = (uint8_t*)MALLOCATE(num_rules * sizeof(uint8_t));
+        ivars->field_types = (FieldType**)CALLOCATE(num_rules, sizeof(FieldType*));
 
         for (uint32_t i = 0; i < num_rules; i++) {
             SortRule *rule      = (SortRule*)VA_Fetch(rules, i);
@@ -65,12 +66,12 @@ HitQ_init(HitQueue *self, Schema *schema, SortSpec *sort_spec,
             bool      reverse   = SortRule_Get_Reverse(rule);
 
             if (rule_type == SortRule_SCORE) {
-                self->actions[action_num++] = reverse
+                ivars->actions[action_num++] = reverse
                                               ? COMPARE_BY_SCORE_REV
                                               : COMPARE_BY_SCORE;
             }
             else if (rule_type == SortRule_DOC_ID) {
-                self->actions[action_num++] = reverse
+                ivars->actions[action_num++] = reverse
                                               ? COMPARE_BY_DOC_ID_REV
                                               : COMPARE_BY_DOC_ID;
             }
@@ -78,11 +79,11 @@ HitQ_init(HitQueue *self, Schema *schema, SortSpec *sort_spec,
                 CharBuf   *field = SortRule_Get_Field(rule);
                 FieldType *type  = Schema_Fetch_Type(schema, field);
                 if (type) {
-                    self->field_types[action_num] = (FieldType*)INCREF(type);
-                    self->actions[action_num++] = reverse
+                    ivars->field_types[action_num] = (FieldType*)INCREF(type);
+                    ivars->actions[action_num++] = reverse
                                                   ? COMPARE_BY_VALUE_REV
                                                   : COMPARE_BY_VALUE;
-                    self->need_values = true;
+                    ivars->need_values = true;
                 }
                 else {
                     // Skip over fields we don't know how to sort on.
@@ -95,10 +96,10 @@ HitQ_init(HitQueue *self, Schema *schema, SortSpec *sort_spec,
         }
     }
     else {
-        self->num_actions = 2;
-        self->actions     = (uint8_t*)MALLOCATE(self->num_actions * sizeof(uint8_t));
-        self->actions[0]  = COMPARE_BY_SCORE;
-        self->actions[1]  = COMPARE_BY_DOC_ID;
+        ivars->num_actions = 2;
+        ivars->actions     = (uint8_t*)MALLOCATE(ivars->num_actions * sizeof(uint8_t));
+        ivars->actions[0]  = COMPARE_BY_SCORE;
+        ivars->actions[1]  = COMPARE_BY_DOC_ID;
     }
 
     return (HitQueue*)PriQ_init((PriorityQueue*)self, wanted);
@@ -106,70 +107,79 @@ HitQ_init(HitQueue *self, Schema *schema, SortSpec *sort_spec,
 
 void
 HitQ_destroy(HitQueue *self) {
-    FieldType **types = self->field_types;
-    FieldType **const limit = types + self->num_actions - 1;
+    HitQueueIVARS *const ivars = HitQ_IVARS(self);
+    FieldType **types = ivars->field_types;
+    FieldType **const limit = types + ivars->num_actions - 1;
     for (; types < limit; types++) {
         if (types) { DECREF(*types); }
     }
-    FREEMEM(self->actions);
-    FREEMEM(self->field_types);
+    FREEMEM(ivars->actions);
+    FREEMEM(ivars->field_types);
     SUPER_DESTROY(self, HITQUEUE);
 }
 
 Obj*
 HitQ_jostle(HitQueue *self, Obj *element) {
+    HitQueueIVARS *const ivars = HitQ_IVARS(self);
     MatchDoc *match_doc = (MatchDoc*)CERTIFY(element, MATCHDOC);
     HitQ_Jostle_t super_jostle
         = SUPER_METHOD_PTR(HITQUEUE, Lucy_HitQ_Jostle);
-    if (self->need_values) {
-        CERTIFY(match_doc->values, VARRAY);
+    if (ivars->need_values) {
+        MatchDocIVARS *const match_doc_ivars = MatchDoc_IVARS(match_doc);
+        CERTIFY(match_doc_ivars->values, VARRAY);
     }
     return super_jostle(self, element);
 }
 
 static INLINE int32_t
-SI_compare_by_value(HitQueue *self, uint32_t tick, MatchDoc *a, MatchDoc *b) {
-    Obj *a_val = VA_Fetch(a->values, tick);
-    Obj *b_val = VA_Fetch(b->values, tick);
-    FieldType *field_type = self->field_types[tick];
+SI_compare_by_value(HitQueueIVARS *ivars, uint32_t tick,
+                    MatchDocIVARS *a_ivars, MatchDocIVARS *b_ivars) {
+    Obj *a_val = VA_Fetch(a_ivars->values, tick);
+    Obj *b_val = VA_Fetch(b_ivars->values, tick);
+    FieldType *field_type = ivars->field_types[tick];
     return FType_null_back_compare_values(field_type, a_val, b_val);
 }
 
 bool
 HitQ_less_than(HitQueue *self, Obj *obj_a, Obj *obj_b) {
+    HitQueueIVARS *const ivars = HitQ_IVARS(self);
     MatchDoc *const a = (MatchDoc*)obj_a;
     MatchDoc *const b = (MatchDoc*)obj_b;
+    MatchDocIVARS *a_ivars = MatchDoc_IVARS(a);
+    MatchDocIVARS *b_ivars = MatchDoc_IVARS(b);
     uint32_t i = 0;
-    uint8_t *const actions = self->actions;
+    uint8_t *const actions = ivars->actions;
 
     do {
         switch (actions[i] & ACTIONS_MASK) {
             case COMPARE_BY_SCORE:
                 // Prefer high scores.
-                if (a->score > b->score)      { return false; }
-                else if (a->score < b->score) { return true;  }
+                if (a_ivars->score > b_ivars->score)      { return false; }
+                else if (a_ivars->score < b_ivars->score) { return true;  }
                 break;
             case COMPARE_BY_SCORE_REV:
-                if (a->score > b->score)      { return true;  }
-                else if (a->score < b->score) { return false; }
+                if (a_ivars->score > b_ivars->score)      { return true;  }
+                else if (a_ivars->score < b_ivars->score) { return false; }
                 break;
             case COMPARE_BY_DOC_ID:
                 // Prefer low doc ids.
-                if (a->doc_id > b->doc_id)      { return true;  }
-                else if (a->doc_id < b->doc_id) { return false; }
+                if (a_ivars->doc_id > b_ivars->doc_id)      { return true;  }
+                else if (a_ivars->doc_id < b_ivars->doc_id) { return false; }
                 break;
             case COMPARE_BY_DOC_ID_REV:
-                if (a->doc_id > b->doc_id)      { return false; }
-                else if (a->doc_id < b->doc_id) { return true;  }
+                if (a_ivars->doc_id > b_ivars->doc_id)      { return false; }
+                else if (a_ivars->doc_id < b_ivars->doc_id) { return true;  }
                 break;
             case COMPARE_BY_VALUE: {
-                    int32_t comparison = SI_compare_by_value(self, i, a, b);
+                    int32_t comparison
+                        = SI_compare_by_value(ivars, i, a_ivars, b_ivars);
                     if (comparison > 0)      { return true;  }
                     else if (comparison < 0) { return false; }
                 }
                 break;
             case COMPARE_BY_VALUE_REV: {
-                    int32_t comparison = SI_compare_by_value(self, i, b, a);
+                    int32_t comparison
+                        = SI_compare_by_value(ivars, i, b_ivars, a_ivars);
                     if (comparison > 0)      { return true;  }
                     else if (comparison < 0) { return false; }
                 }
@@ -178,7 +188,7 @@ HitQ_less_than(HitQueue *self, Obj *obj_a, Obj *obj_b) {
                 THROW(ERR, "Unexpected action %u8", actions[i]);
         }
 
-    } while (++i < self->num_actions);
+    } while (++i < ivars->num_actions);
 
     return false;
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/Hits.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/Hits.c b/core/Lucy/Search/Hits.c
index 89008c9..3f28551 100644
--- a/core/Lucy/Search/Hits.c
+++ b/core/Lucy/Search/Hits.c
@@ -33,25 +33,28 @@ Hits_new(Searcher *searcher, TopDocs *top_docs, uint32_t offset) {
 
 Hits*
 Hits_init(Hits *self, Searcher *searcher, TopDocs *top_docs, uint32_t offset) {
-    self->searcher   = (Searcher*)INCREF(searcher);
-    self->top_docs   = (TopDocs*)INCREF(top_docs);
-    self->match_docs = (VArray*)INCREF(TopDocs_Get_Match_Docs(top_docs));
-    self->offset     = offset;
+    HitsIVARS *const ivars = Hits_IVARS(self);
+    ivars->searcher   = (Searcher*)INCREF(searcher);
+    ivars->top_docs   = (TopDocs*)INCREF(top_docs);
+    ivars->match_docs = (VArray*)INCREF(TopDocs_Get_Match_Docs(top_docs));
+    ivars->offset     = offset;
     return self;
 }
 
 void
 Hits_destroy(Hits *self) {
-    DECREF(self->searcher);
-    DECREF(self->top_docs);
-    DECREF(self->match_docs);
+    HitsIVARS *const ivars = Hits_IVARS(self);
+    DECREF(ivars->searcher);
+    DECREF(ivars->top_docs);
+    DECREF(ivars->match_docs);
     SUPER_DESTROY(self, HITS);
 }
 
 HitDoc*
 Hits_next(Hits *self) {
-    MatchDoc *match_doc = (MatchDoc*)VA_Fetch(self->match_docs, self->offset);
-    self->offset++;
+    HitsIVARS *const ivars = Hits_IVARS(self);
+    MatchDoc *match_doc = (MatchDoc*)VA_Fetch(ivars->match_docs, ivars->offset);
+    ivars->offset++;
 
     if (!match_doc) {
         /** Bail if there aren't any more *captured* hits. (There may be more
@@ -60,16 +63,18 @@ Hits_next(Hits *self) {
     }
     else {
         // Lazily fetch HitDoc, set score.
-        HitDoc *hit_doc = Searcher_Fetch_Doc(self->searcher,
-                                             match_doc->doc_id);
-        HitDoc_Set_Score(hit_doc, match_doc->score);
+        MatchDocIVARS *match_doc_ivars = MatchDoc_IVARS(match_doc);
+        HitDoc *hit_doc = Searcher_Fetch_Doc(ivars->searcher,
+                                             match_doc_ivars->doc_id);
+        HitDoc_Set_Score(hit_doc, match_doc_ivars->score);
         return hit_doc;
     }
 }
 
 uint32_t
 Hits_total_hits(Hits *self) {
-    return TopDocs_Get_Total_Hits(self->top_docs);
+    HitsIVARS *const ivars = Hits_IVARS(self);
+    return TopDocs_Get_Total_Hits(ivars->top_docs);
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/IndexSearcher.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/IndexSearcher.c b/core/Lucy/Search/IndexSearcher.c
index fc48c13..ff4dd26 100644
--- a/core/Lucy/Search/IndexSearcher.c
+++ b/core/Lucy/Search/IndexSearcher.c
@@ -51,56 +51,62 @@ IxSearcher_new(Obj *index) {
 
 IndexSearcher*
 IxSearcher_init(IndexSearcher *self, Obj *index) {
+    IndexSearcherIVARS *const ivars = IxSearcher_IVARS(self);
     if (Obj_Is_A(index, INDEXREADER)) {
-        self->reader = (IndexReader*)INCREF(index);
+        ivars->reader = (IndexReader*)INCREF(index);
     }
     else {
-        self->reader = IxReader_open(index, NULL, NULL);
+        ivars->reader = IxReader_open(index, NULL, NULL);
     }
-    Searcher_init((Searcher*)self, IxReader_Get_Schema(self->reader));
-    self->seg_readers = IxReader_Seg_Readers(self->reader);
-    self->seg_starts  = IxReader_Offsets(self->reader);
-    self->doc_reader = (DocReader*)IxReader_Fetch(
-                           self->reader, VTable_Get_Name(DOCREADER));
-    self->hl_reader = (HighlightReader*)IxReader_Fetch(
-                          self->reader, VTable_Get_Name(HIGHLIGHTREADER));
-    if (self->doc_reader) { INCREF(self->doc_reader); }
-    if (self->hl_reader)  { INCREF(self->hl_reader); }
+    Searcher_init((Searcher*)self, IxReader_Get_Schema(ivars->reader));
+    ivars->seg_readers = IxReader_Seg_Readers(ivars->reader);
+    ivars->seg_starts  = IxReader_Offsets(ivars->reader);
+    ivars->doc_reader = (DocReader*)IxReader_Fetch(
+                           ivars->reader, VTable_Get_Name(DOCREADER));
+    ivars->hl_reader = (HighlightReader*)IxReader_Fetch(
+                          ivars->reader, VTable_Get_Name(HIGHLIGHTREADER));
+    if (ivars->doc_reader) { INCREF(ivars->doc_reader); }
+    if (ivars->hl_reader)  { INCREF(ivars->hl_reader); }
 
     return self;
 }
 
 void
 IxSearcher_destroy(IndexSearcher *self) {
-    DECREF(self->reader);
-    DECREF(self->doc_reader);
-    DECREF(self->hl_reader);
-    DECREF(self->seg_readers);
-    DECREF(self->seg_starts);
+    IndexSearcherIVARS *const ivars = IxSearcher_IVARS(self);
+    DECREF(ivars->reader);
+    DECREF(ivars->doc_reader);
+    DECREF(ivars->hl_reader);
+    DECREF(ivars->seg_readers);
+    DECREF(ivars->seg_starts);
     SUPER_DESTROY(self, INDEXSEARCHER);
 }
 
 HitDoc*
 IxSearcher_fetch_doc(IndexSearcher *self, int32_t doc_id) {
-    if (!self->doc_reader) { THROW(ERR, "No DocReader"); }
-    return DocReader_Fetch_Doc(self->doc_reader, doc_id);
+    IndexSearcherIVARS *const ivars = IxSearcher_IVARS(self);
+    if (!ivars->doc_reader) { THROW(ERR, "No DocReader"); }
+    return DocReader_Fetch_Doc(ivars->doc_reader, doc_id);
 }
 
 DocVector*
 IxSearcher_fetch_doc_vec(IndexSearcher *self, int32_t doc_id) {
-    if (!self->hl_reader) { THROW(ERR, "No HighlightReader"); }
-    return HLReader_Fetch_Doc_Vec(self->hl_reader, doc_id);
+    IndexSearcherIVARS *const ivars = IxSearcher_IVARS(self);
+    if (!ivars->hl_reader) { THROW(ERR, "No HighlightReader"); }
+    return HLReader_Fetch_Doc_Vec(ivars->hl_reader, doc_id);
 }
 
 int32_t
 IxSearcher_doc_max(IndexSearcher *self) {
-    return IxReader_Doc_Max(self->reader);
+    IndexSearcherIVARS *const ivars = IxSearcher_IVARS(self);
+    return IxReader_Doc_Max(ivars->reader);
 }
 
 uint32_t
 IxSearcher_doc_freq(IndexSearcher *self, const CharBuf *field, Obj *term) {
+    IndexSearcherIVARS *const ivars = IxSearcher_IVARS(self);
     LexiconReader *lex_reader
-        = (LexiconReader*)IxReader_Fetch(self->reader,
+        = (LexiconReader*)IxReader_Fetch(ivars->reader,
                                          VTable_Get_Name(LEXICONREADER));
     return lex_reader ? LexReader_Doc_Freq(lex_reader, field, term) : 0;
 }
@@ -123,8 +129,9 @@ IxSearcher_top_docs(IndexSearcher *self, Query *query, uint32_t num_wanted,
 
 void
 IxSearcher_collect(IndexSearcher *self, Query *query, Collector *collector) {
-    VArray   *const seg_readers = self->seg_readers;
-    I32Array *const seg_starts  = self->seg_starts;
+    IndexSearcherIVARS *const ivars = IxSearcher_IVARS(self);
+    VArray   *const seg_readers = ivars->seg_readers;
+    I32Array *const seg_starts  = ivars->seg_starts;
     bool      need_score        = Coll_Need_Score(collector);
     Compiler *compiler = Query_Is_A(query, COMPILER)
                          ? (Compiler*)INCREF(query)
@@ -156,7 +163,7 @@ IxSearcher_collect(IndexSearcher *self, Query *query, Collector *collector) {
 
 IndexReader*
 IxSearcher_get_reader(IndexSearcher *self) {
-    return self->reader;
+    return IxSearcher_IVARS(self)->reader;
 }
 
 void

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/LeafQuery.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/LeafQuery.c b/core/Lucy/Search/LeafQuery.c
index 7dc6864..f5fb944 100644
--- a/core/Lucy/Search/LeafQuery.c
+++ b/core/Lucy/Search/LeafQuery.c
@@ -32,76 +32,82 @@ LeafQuery_new(const CharBuf *field, const CharBuf *text) {
 
 LeafQuery*
 LeafQuery_init(LeafQuery *self, const CharBuf *field, const CharBuf *text) {
+    LeafQueryIVARS *const ivars = LeafQuery_IVARS(self);
     Query_init((Query*)self, 1.0f);
-    self->field       = field ? CB_Clone(field) : NULL;
-    self->text        = CB_Clone(text);
+    ivars->field       = field ? CB_Clone(field) : NULL;
+    ivars->text        = CB_Clone(text);
     return self;
 }
 
 void
 LeafQuery_destroy(LeafQuery *self) {
-    DECREF(self->field);
-    DECREF(self->text);
+    LeafQueryIVARS *const ivars = LeafQuery_IVARS(self);
+    DECREF(ivars->field);
+    DECREF(ivars->text);
     SUPER_DESTROY(self, LEAFQUERY);
 }
 
 CharBuf*
 LeafQuery_get_field(LeafQuery *self) {
-    return self->field;
+    return LeafQuery_IVARS(self)->field;
 }
 
 CharBuf*
 LeafQuery_get_text(LeafQuery *self) {
-    return self->text;
+    return LeafQuery_IVARS(self)->text;
 }
 
 bool
 LeafQuery_equals(LeafQuery *self, Obj *other) {
-    LeafQuery *twin = (LeafQuery*)other;
-    if (twin == self)                  { return true; }
+    if ((LeafQuery*)other == self)     { return true; }
     if (!Obj_Is_A(other, LEAFQUERY))   { return false; }
-    if (self->boost != twin->boost)    { return false; }
-    if (!!self->field ^ !!twin->field) { return false; }
-    if (self->field) {
-        if (!CB_Equals(self->field, (Obj*)twin->field)) { return false; }
+    LeafQueryIVARS *const ivars = LeafQuery_IVARS(self);
+    LeafQueryIVARS *const ovars = LeafQuery_IVARS((LeafQuery*)other);
+    if (ivars->boost != ovars->boost)    { return false; }
+    if (!!ivars->field ^ !!ovars->field) { return false; }
+    if (ivars->field) {
+        if (!CB_Equals(ivars->field, (Obj*)ovars->field)) { return false; }
     }
-    if (!CB_Equals(self->text, (Obj*)twin->text)) { return false; }
+    if (!CB_Equals(ivars->text, (Obj*)ovars->text)) { return false; }
     return true;
 }
 
 CharBuf*
 LeafQuery_to_string(LeafQuery *self) {
-    if (self->field) {
-        return CB_newf("%o:%o", self->field, self->text);
+    LeafQueryIVARS *const ivars = LeafQuery_IVARS(self);
+    if (ivars->field) {
+        return CB_newf("%o:%o", ivars->field, ivars->text);
     }
     else {
-        return CB_Clone(self->text);
+        return CB_Clone(ivars->text);
     }
 }
 
 void
 LeafQuery_serialize(LeafQuery *self, OutStream *outstream) {
-    if (self->field) {
+    LeafQueryIVARS *const ivars = LeafQuery_IVARS(self);
+    if (ivars->field) {
         OutStream_Write_U8(outstream, true);
-        Freezer_serialize_charbuf(self->field, outstream);
+        Freezer_serialize_charbuf(ivars->field, outstream);
     }
     else {
         OutStream_Write_U8(outstream, false);
     }
-    Freezer_serialize_charbuf(self->text, outstream);
-    OutStream_Write_F32(outstream, self->boost);
+    Freezer_serialize_charbuf(ivars->text, outstream);
+    OutStream_Write_F32(outstream, ivars->boost);
 }
 
 LeafQuery*
 LeafQuery_deserialize(LeafQuery *self, InStream *instream) {
+    LeafQueryIVARS *const ivars = LeafQuery_IVARS(self);
     if (InStream_Read_U8(instream)) {
-        self->field = Freezer_read_charbuf(instream);
+        ivars->field = Freezer_read_charbuf(instream);
     }
     else {
-        self->field = NULL;
+        ivars->field = NULL;
     }
-    self->text = Freezer_read_charbuf(instream);
-    self->boost = InStream_Read_F32(instream);
+    ivars->text = Freezer_read_charbuf(instream);
+    ivars->boost = InStream_Read_F32(instream);
     return self;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/MatchAllMatcher.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/MatchAllMatcher.c b/core/Lucy/Search/MatchAllMatcher.c
index 815443d..1effa2f 100644
--- a/core/Lucy/Search/MatchAllMatcher.c
+++ b/core/Lucy/Search/MatchAllMatcher.c
@@ -28,38 +28,40 @@ MatchAllMatcher_new(float score, int32_t doc_max) {
 
 MatchAllMatcher*
 MatchAllMatcher_init(MatchAllMatcher *self, float score, int32_t doc_max) {
+    MatchAllMatcherIVARS *const ivars = MatchAllMatcher_IVARS(self);
     Matcher_init((Matcher*)self);
-    self->doc_id        = 0;
-    self->score         = score;
-    self->doc_max       = doc_max;
+    ivars->doc_id        = 0;
+    ivars->score         = score;
+    ivars->doc_max       = doc_max;
     return self;
 }
 
 int32_t
 MatchAllMatcher_next(MatchAllMatcher* self) {
-    if (++self->doc_id <= self->doc_max) {
-        return self->doc_id;
+    MatchAllMatcherIVARS *const ivars = MatchAllMatcher_IVARS(self);
+    if (++ivars->doc_id <= ivars->doc_max) {
+        return ivars->doc_id;
     }
     else {
-        self->doc_id--;
+        ivars->doc_id--;
         return 0;
     }
 }
 
 int32_t
 MatchAllMatcher_advance(MatchAllMatcher* self, int32_t target) {
-    self->doc_id = target - 1;
+    MatchAllMatcher_IVARS(self)->doc_id = target - 1;
     return MatchAllMatcher_next(self);
 }
 
 float
 MatchAllMatcher_score(MatchAllMatcher* self) {
-    return self->score;
+    return MatchAllMatcher_IVARS(self)->score;
 }
 
 int32_t
 MatchAllMatcher_get_doc_id(MatchAllMatcher* self) {
-    return self->doc_id;
+    return MatchAllMatcher_IVARS(self)->doc_id;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/MatchAllQuery.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/MatchAllQuery.c b/core/Lucy/Search/MatchAllQuery.c
index aa1eda0..92f6d27 100644
--- a/core/Lucy/Search/MatchAllQuery.c
+++ b/core/Lucy/Search/MatchAllQuery.c
@@ -42,9 +42,10 @@ MatchAllQuery_init(MatchAllQuery *self) {
 
 bool
 MatchAllQuery_equals(MatchAllQuery *self, Obj *other) {
-    MatchAllQuery *twin = (MatchAllQuery*)other;
     if (!Obj_Is_A(other, MATCHALLQUERY)) { return false; }
-    if (self->boost != twin->boost)      { return false; }
+    MatchAllQueryIVARS *const ivars = MatchAllQuery_IVARS(self);
+    MatchAllQueryIVARS *const ovars = MatchAllQuery_IVARS((MatchAllQuery*)other);
+    if (ivars->boost != ovars->boost)    { return false; }
     return true;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/MatchDoc.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/MatchDoc.c b/core/Lucy/Search/MatchDoc.c
index 8a89f2b..2508028 100644
--- a/core/Lucy/Search/MatchDoc.c
+++ b/core/Lucy/Search/MatchDoc.c
@@ -30,65 +30,70 @@ MatchDoc_new(int32_t doc_id, float score, VArray *values) {
 
 MatchDoc*
 MatchDoc_init(MatchDoc *self, int32_t doc_id, float score, VArray *values) {
-    self->doc_id      = doc_id;
-    self->score       = score;
-    self->values      = (VArray*)INCREF(values);
+    MatchDocIVARS *const ivars = MatchDoc_IVARS(self);
+    ivars->doc_id      = doc_id;
+    ivars->score       = score;
+    ivars->values      = (VArray*)INCREF(values);
     return self;
 }
 
 void
 MatchDoc_destroy(MatchDoc *self) {
-    DECREF(self->values);
+    MatchDocIVARS *const ivars = MatchDoc_IVARS(self);
+    DECREF(ivars->values);
     SUPER_DESTROY(self, MATCHDOC);
 }
 
 void
 MatchDoc_serialize(MatchDoc *self, OutStream *outstream) {
-    OutStream_Write_C32(outstream, self->doc_id);
-    OutStream_Write_F32(outstream, self->score);
-    OutStream_Write_U8(outstream, self->values ? 1 : 0);
-    if (self->values) { Freezer_serialize_varray(self->values, outstream); }
+    MatchDocIVARS *const ivars = MatchDoc_IVARS(self);
+    OutStream_Write_C32(outstream, ivars->doc_id);
+    OutStream_Write_F32(outstream, ivars->score);
+    OutStream_Write_U8(outstream, ivars->values ? 1 : 0);
+    if (ivars->values) { Freezer_serialize_varray(ivars->values, outstream); }
 }
 
 MatchDoc*
 MatchDoc_deserialize(MatchDoc *self, InStream *instream) {
-    self->doc_id = InStream_Read_C32(instream);
-    self->score  = InStream_Read_F32(instream);
+    MatchDocIVARS *const ivars = MatchDoc_IVARS(self);
+    ivars->doc_id = InStream_Read_C32(instream);
+    ivars->score  = InStream_Read_F32(instream);
     if (InStream_Read_U8(instream)) {
-        self->values = Freezer_read_varray(instream);
+        ivars->values = Freezer_read_varray(instream);
     }
     return self;
 }
 
 int32_t
 MatchDoc_get_doc_id(MatchDoc *self) {
-    return self->doc_id;
+    return MatchDoc_IVARS(self)->doc_id;
 }
 
 float
 MatchDoc_get_score(MatchDoc *self) {
-    return self->score;
+    return MatchDoc_IVARS(self)->score;
 }
 
 VArray*
 MatchDoc_get_values(MatchDoc *self) {
-    return self->values;
+    return MatchDoc_IVARS(self)->values;
 }
 
 void
 MatchDoc_set_doc_id(MatchDoc *self, int32_t doc_id) {
-    self->doc_id = doc_id;
+    MatchDoc_IVARS(self)->doc_id = doc_id;
 }
 
 void
 MatchDoc_set_score(MatchDoc *self, float score) {
-    self->score = score;
+    MatchDoc_IVARS(self)->score = score;
 }
 
 void
 MatchDoc_set_values(MatchDoc *self, VArray *values) {
-    DECREF(self->values);
-    self->values = (VArray*)INCREF(values);
+    MatchDocIVARS *const ivars = MatchDoc_IVARS(self);
+    DECREF(ivars->values);
+    ivars->values = (VArray*)INCREF(values);
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/NOTMatcher.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/NOTMatcher.c b/core/Lucy/Search/NOTMatcher.c
index 25208cd..bd1b095 100644
--- a/core/Lucy/Search/NOTMatcher.c
+++ b/core/Lucy/Search/NOTMatcher.c
@@ -29,17 +29,18 @@ NOTMatcher_new(Matcher *negated_matcher, int32_t doc_max) {
 
 NOTMatcher*
 NOTMatcher_init(NOTMatcher *self, Matcher *negated_matcher, int32_t doc_max) {
+    NOTMatcherIVARS *const ivars = NOTMatcher_IVARS(self);
     VArray *children = VA_new(1);
     VA_Push(children, INCREF(negated_matcher));
     PolyMatcher_init((PolyMatcher*)self, children, NULL);
 
     // Init.
-    self->doc_id           = 0;
-    self->next_negation    = 0;
+    ivars->doc_id           = 0;
+    ivars->next_negation    = 0;
 
     // Assign.
-    self->negated_matcher  = (Matcher*)INCREF(negated_matcher);
-    self->doc_max          = doc_max;
+    ivars->negated_matcher  = (Matcher*)INCREF(negated_matcher);
+    ivars->doc_max          = doc_max;
 
     DECREF(children);
 
@@ -48,46 +49,48 @@ NOTMatcher_init(NOTMatcher *self, Matcher *negated_matcher, int32_t doc_max) {
 
 void
 NOTMatcher_destroy(NOTMatcher *self) {
-    DECREF(self->negated_matcher);
+    NOTMatcherIVARS *const ivars = NOTMatcher_IVARS(self);
+    DECREF(ivars->negated_matcher);
     SUPER_DESTROY(self, NOTMATCHER);
 }
 
 int32_t
 NOTMatcher_next(NOTMatcher *self) {
+    NOTMatcherIVARS *const ivars = NOTMatcher_IVARS(self);
     while (1) {
-        self->doc_id++;
+        ivars->doc_id++;
 
         // Get next negated doc id.
-        if (self->next_negation < self->doc_id) {
-            self->next_negation
-                = Matcher_Advance(self->negated_matcher, self->doc_id);
-            if (self->next_negation == 0) {
-                DECREF(self->negated_matcher);
-                self->negated_matcher = NULL;
-                self->next_negation = self->doc_max + 1;
+        if (ivars->next_negation < ivars->doc_id) {
+            ivars->next_negation
+                = Matcher_Advance(ivars->negated_matcher, ivars->doc_id);
+            if (ivars->next_negation == 0) {
+                DECREF(ivars->negated_matcher);
+                ivars->negated_matcher = NULL;
+                ivars->next_negation = ivars->doc_max + 1;
             }
         }
 
-        if (self->doc_id > self->doc_max) {
-            self->doc_id = self->doc_max; // halt advance
+        if (ivars->doc_id > ivars->doc_max) {
+            ivars->doc_id = ivars->doc_max; // halt advance
             return 0;
         }
-        else if (self->doc_id != self->next_negation) {
+        else if (ivars->doc_id != ivars->next_negation) {
             // Success!
-            return self->doc_id;
+            return ivars->doc_id;
         }
     }
 }
 
 int32_t
 NOTMatcher_advance(NOTMatcher *self, int32_t target) {
-    self->doc_id = target - 1;
+    NOTMatcher_IVARS(self)->doc_id = target - 1;
     return NOTMatcher_next(self);
 }
 
 int32_t
 NOTMatcher_get_doc_id(NOTMatcher *self) {
-    return self->doc_id;
+    return NOTMatcher_IVARS(self)->doc_id;
 }
 
 float

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/NOTQuery.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/NOTQuery.c b/core/Lucy/Search/NOTQuery.c
index 11062d3..f2050ba 100644
--- a/core/Lucy/Search/NOTQuery.c
+++ b/core/Lucy/Search/NOTQuery.c
@@ -43,17 +43,20 @@ NOTQuery_init(NOTQuery *self, Query *negated_query) {
 
 Query*
 NOTQuery_get_negated_query(NOTQuery *self) {
-    return (Query*)VA_Fetch(self->children, 0);
+    NOTQueryIVARS *const ivars = NOTQuery_IVARS(self);
+    return (Query*)VA_Fetch(ivars->children, 0);
 }
 
 void
 NOTQuery_set_negated_query(NOTQuery *self, Query *negated_query) {
-    VA_Store(self->children, 0, INCREF(negated_query));
+    NOTQueryIVARS *const ivars = NOTQuery_IVARS(self);
+    VA_Store(ivars->children, 0, INCREF(negated_query));
 }
 
 CharBuf*
 NOTQuery_to_string(NOTQuery *self) {
-    CharBuf *neg_string = Obj_To_String(VA_Fetch(self->children, 0));
+    NOTQueryIVARS *const ivars = NOTQuery_IVARS(self);
+    CharBuf *neg_string = Obj_To_String(VA_Fetch(ivars->children, 0));
     CharBuf *retval = CB_newf("-%o", neg_string);
     DECREF(neg_string);
     return retval;
@@ -111,8 +114,9 @@ NOTCompiler_highlight_spans(NOTCompiler *self, Searcher *searcher,
 Matcher*
 NOTCompiler_make_matcher(NOTCompiler *self, SegReader *reader,
                          bool need_score) {
+    NOTCompilerIVARS *const ivars = NOTCompiler_IVARS(self);
     Compiler *negated_compiler
-        = (Compiler*)CERTIFY(VA_Fetch(self->children, 0), COMPILER);
+        = (Compiler*)CERTIFY(VA_Fetch(ivars->children, 0), COMPILER);
     Matcher *negated_matcher
         = Compiler_Make_Matcher(negated_compiler, reader, false);
     UNUSED_VAR(need_score);

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/NoMatchQuery.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/NoMatchQuery.c b/core/Lucy/Search/NoMatchQuery.c
index ca07a3c..1950c16 100644
--- a/core/Lucy/Search/NoMatchQuery.c
+++ b/core/Lucy/Search/NoMatchQuery.c
@@ -35,17 +35,19 @@ NoMatchQuery_new() {
 
 NoMatchQuery*
 NoMatchQuery_init(NoMatchQuery *self) {
+    NoMatchQueryIVARS *const ivars = NoMatchQuery_IVARS(self);
     Query_init((Query*)self, 0.0f);
-    self->fails_to_match = true;
+    ivars->fails_to_match = true;
     return self;
 }
 
 bool
 NoMatchQuery_equals(NoMatchQuery *self, Obj *other) {
-    NoMatchQuery *twin = (NoMatchQuery*)other;
-    if (!Obj_Is_A(other, NOMATCHQUERY))                   { return false; }
-    if (self->boost != twin->boost)                       { return false; }
-    if (!!self->fails_to_match != !!twin->fails_to_match) { return false; }
+    if (!Obj_Is_A(other, NOMATCHQUERY))                     { return false; }
+    NoMatchQueryIVARS *const ivars = NoMatchQuery_IVARS(self);
+    NoMatchQueryIVARS *const ovars = NoMatchQuery_IVARS((NoMatchQuery*)other);
+    if (ivars->boost != ovars->boost)                       { return false; }
+    if (!!ivars->fails_to_match != !!ovars->fails_to_match) { return false; }
     return true;
 }
 
@@ -67,21 +69,22 @@ NoMatchQuery_make_compiler(NoMatchQuery *self, Searcher *searcher,
 
 void
 NoMatchQuery_set_fails_to_match(NoMatchQuery *self, bool fails_to_match) {
-    self->fails_to_match = fails_to_match;
+    NoMatchQuery_IVARS(self)->fails_to_match = fails_to_match;
 }
 
 bool
 NoMatchQuery_get_fails_to_match(NoMatchQuery *self) {
-    return self->fails_to_match;
+    return NoMatchQuery_IVARS(self)->fails_to_match;
 }
 
 Obj*
 NoMatchQuery_dump(NoMatchQuery *self) {
+    NoMatchQueryIVARS *const ivars = NoMatchQuery_IVARS(self);
     NoMatchQuery_Dump_t super_dump
         = SUPER_METHOD_PTR(NOMATCHQUERY, Lucy_NoMatchQuery_Dump);
     Hash *dump = (Hash*)CERTIFY(super_dump(self), HASH);
     Hash_Store_Str(dump, "fails_to_match", 14,
-                   (Obj*)Bool_singleton(self->fails_to_match));
+                   (Obj*)Bool_singleton(ivars->fails_to_match));
     return (Obj*)dump;
 }
 
@@ -92,19 +95,21 @@ NoMatchQuery_load(NoMatchQuery *self, Obj *dump) {
         = SUPER_METHOD_PTR(NOMATCHQUERY, Lucy_NoMatchQuery_Load);
     NoMatchQuery *loaded = super_load(self, dump);
     Obj *fails = Cfish_Hash_Fetch_Str(source, "fails_to_match", 14);
-    loaded->fails_to_match = fails ? Obj_To_Bool(fails) : true;
+    NoMatchQuery_IVARS(loaded)->fails_to_match
+        = fails ? Obj_To_Bool(fails) : true;
     return loaded;
 }
 
 void
 NoMatchQuery_serialize(NoMatchQuery *self, OutStream *outstream) {
-    OutStream_Write_I8(outstream, !!self->fails_to_match);
+    NoMatchQueryIVARS *const ivars = NoMatchQuery_IVARS(self);
+    OutStream_Write_I8(outstream, !!ivars->fails_to_match);
 }
 
 NoMatchQuery*
 NoMatchQuery_deserialize(NoMatchQuery *self, InStream *instream) {
     NoMatchQuery_init(self);
-    self->fails_to_match = !!InStream_Read_I8(instream);
+    NoMatchQuery_IVARS(self)->fails_to_match = !!InStream_Read_I8(instream);
     return self;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/ORMatcher.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/ORMatcher.c b/core/Lucy/Search/ORMatcher.c
index c3b627b..94d5eca 100644
--- a/core/Lucy/Search/ORMatcher.c
+++ b/core/Lucy/Search/ORMatcher.c
@@ -24,21 +24,22 @@
 // Add an element to the queue.  Unsafe -- bounds checking of queue size is
 // left to the caller.
 static void
-S_add_element(ORMatcher *self, Matcher *matcher, int32_t doc_id);
+S_add_element(ORMatcher *self, ORMatcherIVARS *ivars, Matcher *matcher,
+              int32_t doc_id);
 
 // Empty out the queue.
 static void
-S_clear(ORMatcher *self);
+S_clear(ORMatcher *self, ORMatcherIVARS *ivars);
 
 // Call Matcher_Next() on the top queue element and adjust the queue,
 // removing the element if Matcher_Next() returns false.
 static INLINE int32_t
-SI_top_next(ORMatcher *self);
+SI_top_next(ORMatcher *self, ORMatcherIVARS *ivars);
 
 // Call Matcher_Advance() on the top queue element and adjust the queue,
 // removing the element if Matcher_Advance() returns false.
 static INLINE int32_t
-SI_top_advance(ORMatcher *self, int32_t target);
+SI_top_advance(ORMatcher *self, ORMatcherIVARS *ivars, int32_t target);
 
 /* React to a change in the top element, or "root" -- presumably the update of
  * its doc_id resulting from a call to Matcher_Next() or Matcher_Advance().
@@ -48,19 +49,19 @@ SI_top_advance(ORMatcher *self, int32_t target);
  * the root node, or 0 if the queue has been emptied.
  */
 static int32_t
-S_adjust_root(ORMatcher *self);
+S_adjust_root(ORMatcher *self, ORMatcherIVARS *ivars);
 
 // Take the bottom node (which probably violates the heap property when this
 // is called) and bubble it up through the heap until the heap property is
 // restored.
 static void
-S_bubble_up(ORMatcher *self);
+S_bubble_up(ORMatcher *self, ORMatcherIVARS *ivars);
 
 // Take the top node (which probably violates the heap property when this
 // is called) and sift it down through the heap until the heap property is
 // restored.
 static void
-S_sift_down(ORMatcher *self);
+S_sift_down(ORMatcher *self, ORMatcherIVARS *ivars);
 
 ORMatcher*
 ORMatcher_new(VArray *children) {
@@ -69,33 +70,34 @@ ORMatcher_new(VArray *children) {
 }
 
 static ORMatcher*
-S_ormatcher_init2(ORMatcher *self, VArray *children, Similarity *sim) {
+S_ormatcher_init2(ORMatcher *self, ORMatcherIVARS *ivars, VArray *children,
+                  Similarity *sim) {
     // Init.
     PolyMatcher_init((PolyMatcher*)self, children, sim);
-    self->size = 0;
+    ivars->size = 0;
 
     // Derive.
-    self->max_size = VA_Get_Size(children);
+    ivars->max_size = VA_Get_Size(children);
 
     // Allocate.
-    self->heap = (HeapedMatcherDoc**)CALLOCATE(self->max_size + 1, sizeof(HeapedMatcherDoc*));
+    ivars->heap = (HeapedMatcherDoc**)CALLOCATE(ivars->max_size + 1, sizeof(HeapedMatcherDoc*));
 
     // Create a pool of HMDs.  Encourage CPU cache hits by using a single
     // allocation for all of them.
-    size_t amount_to_malloc = (self->max_size + 1) * sizeof(HeapedMatcherDoc);
-    self->blob = (char*)MALLOCATE(amount_to_malloc);
-    self->pool = (HeapedMatcherDoc**)CALLOCATE(self->max_size + 1, sizeof(HeapedMatcherDoc*));
-    for (uint32_t i = 1; i <= self->max_size; i++) {
+    size_t amount_to_malloc = (ivars->max_size + 1) * sizeof(HeapedMatcherDoc);
+    ivars->blob = (char*)MALLOCATE(amount_to_malloc);
+    ivars->pool = (HeapedMatcherDoc**)CALLOCATE(ivars->max_size + 1, sizeof(HeapedMatcherDoc*));
+    for (uint32_t i = 1; i <= ivars->max_size; i++) {
         size_t offset = i * sizeof(HeapedMatcherDoc);
-        HeapedMatcherDoc *hmd = (HeapedMatcherDoc*)(self->blob + offset);
-        self->pool[i] = hmd;
+        HeapedMatcherDoc *hmd = (HeapedMatcherDoc*)(ivars->blob + offset);
+        ivars->pool[i] = hmd;
     }
 
     // Prime queue.
-    for (uint32_t i = 0; i < self->max_size; i++) {
+    for (uint32_t i = 0; i < ivars->max_size; i++) {
         Matcher *matcher = (Matcher*)VA_Fetch(children, i);
         if (matcher) {
-            S_add_element(self, (Matcher*)INCREF(matcher), 0);
+            S_add_element(self, ivars, (Matcher*)INCREF(matcher), 0);
         }
     }
 
@@ -104,134 +106,141 @@ S_ormatcher_init2(ORMatcher *self, VArray *children, Similarity *sim) {
 
 ORMatcher*
 ORMatcher_init(ORMatcher *self, VArray *children) {
-    return S_ormatcher_init2(self, children, NULL);
+    ORMatcherIVARS *const ivars = ORMatcher_IVARS(self);
+    return S_ormatcher_init2(self, ivars, children, NULL);
 }
 
 void
 ORMatcher_destroy(ORMatcher *self) {
-    if (self->blob) { S_clear(self); }
-    FREEMEM(self->blob);
-    FREEMEM(self->pool);
-    FREEMEM(self->heap);
+    ORMatcherIVARS *const ivars = ORMatcher_IVARS(self);
+    if (ivars->blob) { S_clear(self, ivars); }
+    FREEMEM(ivars->blob);
+    FREEMEM(ivars->pool);
+    FREEMEM(ivars->heap);
     SUPER_DESTROY(self, ORMATCHER);
 }
 
 int32_t
 ORMatcher_next(ORMatcher *self) {
-    if (self->size == 0) {
+    ORMatcherIVARS *const ivars = ORMatcher_IVARS(self);
+    if (ivars->size == 0) {
         return 0;
     }
     else {
-        int32_t last_doc_id = self->top_hmd->doc;
-        while (self->top_hmd->doc == last_doc_id) {
-            int32_t top_doc_id = SI_top_next(self);
-            if (!top_doc_id && self->size == 0) {
+        int32_t last_doc_id = ivars->top_hmd->doc;
+        while (ivars->top_hmd->doc == last_doc_id) {
+            int32_t top_doc_id = SI_top_next(self, ivars);
+            if (!top_doc_id && ivars->size == 0) {
                 return 0;
             }
         }
-        return self->top_hmd->doc;
+        return ivars->top_hmd->doc;
     }
 }
 
 int32_t
 ORMatcher_advance(ORMatcher *self, int32_t target) {
-    if (!self->size) { return 0; }
+    ORMatcherIVARS *const ivars = ORMatcher_IVARS(self);
+    if (!ivars->size) { return 0; }
     do {
-        int32_t least = SI_top_advance(self, target);
+        int32_t least = SI_top_advance(self, ivars, target);
         if (least >= target) { return least; }
         if (!least) {
-            if (!self->size) { return 0; }
+            if (!ivars->size) { return 0; }
         }
     } while (true);
 }
 
 int32_t
 ORMatcher_get_doc_id(ORMatcher *self) {
-    return self->top_hmd->doc;
+    return ORMatcher_IVARS(self)->top_hmd->doc;
 }
 
 static void
-S_clear(ORMatcher *self) {
-    HeapedMatcherDoc **const heap = self->heap;
-    HeapedMatcherDoc **const pool = self->pool;
+S_clear(ORMatcher *self, ORMatcherIVARS *ivars) {
+    UNUSED_VAR(self);
+    HeapedMatcherDoc **const heap = ivars->heap;
+    HeapedMatcherDoc **const pool = ivars->pool;
 
     // Node 0 is held empty, to make the algo clearer.
-    for (; self->size > 0; self->size--) {
-        HeapedMatcherDoc *hmd = heap[self->size];
-        heap[self->size] = NULL;
+    for (; ivars->size > 0; ivars->size--) {
+        HeapedMatcherDoc *hmd = heap[ivars->size];
+        heap[ivars->size] = NULL;
         DECREF(hmd->matcher);
 
         // Put HMD back in pool.
-        pool[self->size] = hmd;
+        pool[ivars->size] = hmd;
     }
 }
 
 static INLINE int32_t
-SI_top_next(ORMatcher *self) {
-    HeapedMatcherDoc *const top_hmd = self->top_hmd;
+SI_top_next(ORMatcher *self, ORMatcherIVARS *ivars) {
+    HeapedMatcherDoc *const top_hmd = ivars->top_hmd;
     top_hmd->doc = Matcher_Next(top_hmd->matcher);
-    return S_adjust_root(self);
+    return S_adjust_root(self, ivars);
 }
 
 static INLINE int32_t
-SI_top_advance(ORMatcher *self, int32_t target) {
-    HeapedMatcherDoc *const top_hmd = self->top_hmd;
+SI_top_advance(ORMatcher *self, ORMatcherIVARS *ivars, int32_t target) {
+    HeapedMatcherDoc *const top_hmd = ivars->top_hmd;
     top_hmd->doc = Matcher_Advance(top_hmd->matcher, target);
-    return S_adjust_root(self);
+    return S_adjust_root(self, ivars);
 }
 
 static void
-S_add_element(ORMatcher *self, Matcher *matcher, int32_t doc_id) {
-    HeapedMatcherDoc **const heap = self->heap;
-    HeapedMatcherDoc **const pool = self->pool;
+S_add_element(ORMatcher *self, ORMatcherIVARS *ivars, Matcher *matcher,
+              int32_t doc_id) {
+    HeapedMatcherDoc **const heap = ivars->heap;
+    HeapedMatcherDoc **const pool = ivars->pool;
     HeapedMatcherDoc *hmd;
 
     // Increment size.
-    self->size++;
+    ivars->size++;
 
     // Put element at the bottom of the heap.
-    hmd          = pool[self->size];
+    hmd          = pool[ivars->size];
     hmd->matcher = matcher;
     hmd->doc     = doc_id;
-    heap[self->size] = hmd;
+    heap[ivars->size] = hmd;
 
     // Adjust heap.
-    S_bubble_up(self);
+    S_bubble_up(self, ivars);
 }
 
 static int32_t
-S_adjust_root(ORMatcher *self) {
-    HeapedMatcherDoc *const top_hmd = self->top_hmd;
+S_adjust_root(ORMatcher *self, ORMatcherIVARS *ivars) {
+    HeapedMatcherDoc *const top_hmd = ivars->top_hmd;
 
     // Inlined pop.
     if (!top_hmd->doc) {
-        HeapedMatcherDoc *const last_hmd = self->heap[self->size];
+        HeapedMatcherDoc *const last_hmd = ivars->heap[ivars->size];
 
         // Last to first.
         DECREF(top_hmd->matcher);
         top_hmd->matcher = last_hmd->matcher;
         top_hmd->doc     = last_hmd->doc;
-        self->heap[self->size] = NULL;
+        ivars->heap[ivars->size] = NULL;
 
         // Put back in pool.
-        self->pool[self->size] = last_hmd;
+        ivars->pool[ivars->size] = last_hmd;
 
-        self->size--;
-        if (self->size == 0) {
+        ivars->size--;
+        if (ivars->size == 0) {
             return 0;
         }
     }
 
     // Move queue no matter what.
-    S_sift_down(self);
+    S_sift_down(self, ivars);
 
-    return self->top_hmd->doc;
+    return ivars->top_hmd->doc;
 }
 
 static void
-S_bubble_up(ORMatcher *self) {
-    HeapedMatcherDoc **const heap = self->heap;
-    uint32_t i = self->size;
+S_bubble_up(ORMatcher *self, ORMatcherIVARS *ivars) {
+    UNUSED_VAR(self);
+    HeapedMatcherDoc **const heap = ivars->heap;
+    uint32_t i = ivars->size;
     uint32_t j = i >> 1;
     HeapedMatcherDoc *const node = heap[i]; // save bottom node
 
@@ -241,46 +250,47 @@ S_bubble_up(ORMatcher *self) {
         j = j >> 1;
     }
     heap[i] = node;
-    self->top_hmd = heap[1];
+    ivars->top_hmd = heap[1];
 }
 
 static void
-S_sift_down(ORMatcher *self) {
-    HeapedMatcherDoc **const heap = self->heap;
+S_sift_down(ORMatcher *self, ORMatcherIVARS *ivars) {
+    UNUSED_VAR(self);
+    HeapedMatcherDoc **const heap = ivars->heap;
     uint32_t i = 1;
     uint32_t j = i << 1;
     uint32_t k = j + 1;
     HeapedMatcherDoc *const node = heap[i]; // save top node
 
     // Find smaller child.
-    if (k <= self->size && heap[k]->doc < heap[j]->doc) {
+    if (k <= ivars->size && heap[k]->doc < heap[j]->doc) {
         j = k;
     }
 
-    while (j <= self->size && heap[j]->doc < node->doc) {
+    while (j <= ivars->size && heap[j]->doc < node->doc) {
         heap[i] = heap[j];
         i = j;
         j = i << 1;
         k = j + 1;
-        if (k <= self->size && heap[k]->doc < heap[j]->doc) {
+        if (k <= ivars->size && heap[k]->doc < heap[j]->doc) {
             j = k;
         }
     }
     heap[i] = node;
 
-    self->top_hmd = heap[1];
+    ivars->top_hmd = heap[1];
 }
 
 /***************************************************************************/
 
-/* When this is called, all children are past the current self->doc_id.  The
- * least doc_id amongst them becomes the new self->doc_id, and they are all
+/* When this is called, all children are past the current ivars->doc_id.  The
+ * least doc_id amongst them becomes the new ivars->doc_id, and they are all
  * advanced so that they are once again out in front of it.  While they are
  * advancing, their scores are cached in an array, to be summed during
  * Score().
  */
 static int32_t
-S_advance_after_current(ORScorer *self);
+S_advance_after_current(ORScorer *self, ORScorerIVARS *ivars);
 
 ORScorer*
 ORScorer_new(VArray *children, Similarity *sim) {
@@ -290,9 +300,10 @@ ORScorer_new(VArray *children, Similarity *sim) {
 
 ORScorer*
 ORScorer_init(ORScorer *self, VArray *children, Similarity *sim) {
-    S_ormatcher_init2((ORMatcher*)self, children, sim);
-    self->doc_id = 0;
-    self->scores = (float*)MALLOCATE(self->num_kids * sizeof(float));
+    ORScorerIVARS *const ivars = ORScorer_IVARS(self);
+    S_ormatcher_init2((ORMatcher*)self, (ORMatcherIVARS*)ivars, children, sim);
+    ivars->doc_id = 0;
+    ivars->scores = (float*)MALLOCATE(ivars->num_kids * sizeof(float));
 
     // Establish the state of all child matchers being past the current doc
     // id, by invoking ORMatcher's Next() method.
@@ -303,91 +314,97 @@ ORScorer_init(ORScorer *self, VArray *children, Similarity *sim) {
 
 void
 ORScorer_destroy(ORScorer *self) {
-    FREEMEM(self->scores);
+    ORScorerIVARS *const ivars = ORScorer_IVARS(self);
+    FREEMEM(ivars->scores);
     SUPER_DESTROY(self, ORSCORER);
 }
 
 int32_t
 ORScorer_next(ORScorer *self) {
-    return S_advance_after_current(self);
+    ORScorerIVARS *const ivars = ORScorer_IVARS(self);
+    return S_advance_after_current(self, ivars);
 }
 
 static int32_t
-S_advance_after_current(ORScorer *self) {
-    float *const     scores = self->scores;
+S_advance_after_current(ORScorer *self, ORScorerIVARS *ivars) {
+    float *const     scores = ivars->scores;
     Matcher *child;
 
     // Get the top Matcher, or bail because there are no Matchers left.
-    if (!self->size) { return 0; }
-    else             { child = self->top_hmd->matcher; }
+    if (!ivars->size) { return 0; }
+    else              { child = ivars->top_hmd->matcher; }
 
     // The top matcher will already be at the correct doc, so start there.
-    self->doc_id        = self->top_hmd->doc;
-    scores[0]           = Matcher_Score(child);
-    self->matching_kids = 1;
+    ivars->doc_id        = ivars->top_hmd->doc;
+    scores[0]            = Matcher_Score(child);
+    ivars->matching_kids = 1;
 
     do {
         // Attempt to advance past current doc.
-        int32_t top_doc_id = SI_top_next((ORMatcher*)self);
+        int32_t top_doc_id
+            = SI_top_next((ORMatcher*)self, (ORMatcherIVARS*)ivars);
         if (!top_doc_id) {
-            if (!self->size) {
+            if (!ivars->size) {
                 break; // bail, no more to advance
             }
         }
 
-        if (top_doc_id != self->doc_id) {
+        if (top_doc_id != ivars->doc_id) {
             // Bail, least doc in queue is now past the one we're scoring.
             break;
         }
         else {
             // Accumulate score.
-            child = self->top_hmd->matcher;
-            scores[self->matching_kids] = Matcher_Score(child);
-            self->matching_kids++;
+            child = ivars->top_hmd->matcher;
+            scores[ivars->matching_kids] = Matcher_Score(child);
+            ivars->matching_kids++;
         }
     } while (true);
 
-    return self->doc_id;
+    return ivars->doc_id;
 }
 
 int32_t
 ORScorer_advance(ORScorer *self, int32_t target) {
+    ORScorerIVARS *const ivars = ORScorer_IVARS(self);
+
     // Return sentinel once exhausted.
-    if (!self->size) { return 0; }
+    if (!ivars->size) { return 0; }
 
     // Succeed if we're already past and still on a valid doc.
-    if (target <= self->doc_id) {
-        return self->doc_id;
+    if (target <= ivars->doc_id) {
+        return ivars->doc_id;
     }
 
     do {
         // If all matchers are caught up, accumulate score and return.
-        if (self->top_hmd->doc >= target) {
-            return S_advance_after_current(self);
+        if (ivars->top_hmd->doc >= target) {
+            return S_advance_after_current(self, ivars);
         }
 
         // Not caught up yet, so keep skipping matchers.
-        if (!SI_top_advance((ORMatcher*)self, target)) {
-            if (!self->size) { return 0; }
+        if (!SI_top_advance((ORMatcher*)self, (ORMatcherIVARS*)ivars, target)) {
+            if (!ivars->size) { return 0; }
         }
     } while (true);
 }
 
 int32_t
 ORScorer_get_doc_id(ORScorer *self) {
-    return self->doc_id;
+    return ORScorer_IVARS(self)->doc_id;
 }
 
 float
 ORScorer_score(ORScorer *self) {
-    float *const scores = self->scores;
+    ORScorerIVARS *const ivars = ORScorer_IVARS(self);
+    float *const scores = ivars->scores;
     float score = 0.0f;
 
     // Accumulate score, then factor in coord bonus.
-    for (uint32_t i = 0; i < self->matching_kids; i++) {
+    for (uint32_t i = 0; i < ivars->matching_kids; i++) {
         score += scores[i];
     }
-    score *= self->coord_factors[self->matching_kids];
+    score *= ivars->coord_factors[ivars->matching_kids];
 
     return score;
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/ORQuery.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/ORQuery.c b/core/Lucy/Search/ORQuery.c
index 7f5c9d7..c50826f 100644
--- a/core/Lucy/Search/ORQuery.c
+++ b/core/Lucy/Search/ORQuery.c
@@ -56,13 +56,14 @@ ORQuery_equals(ORQuery *self, Obj *other) {
 
 CharBuf*
 ORQuery_to_string(ORQuery *self) {
-    uint32_t num_kids = VA_Get_Size(self->children);
+    ORQueryIVARS *const ivars = ORQuery_IVARS(self);
+    uint32_t num_kids = VA_Get_Size(ivars->children);
     if (!num_kids) { return CB_new_from_trusted_utf8("()", 2); }
     else {
         CharBuf *retval = CB_new_from_trusted_utf8("(", 1);
         uint32_t last_kid = num_kids - 1;
         for (uint32_t i = 0; i < num_kids; i++) {
-            CharBuf *kid_string = Obj_To_String(VA_Fetch(self->children, i));
+            CharBuf *kid_string = Obj_To_String(VA_Fetch(ivars->children, i));
             CB_Cat(retval, kid_string);
             DECREF(kid_string);
             if (i == last_kid) {
@@ -95,11 +96,12 @@ ORCompiler_init(ORCompiler *self, ORQuery *parent, Searcher *searcher,
 Matcher*
 ORCompiler_make_matcher(ORCompiler *self, SegReader *reader,
                         bool need_score) {
-    uint32_t num_kids = VA_Get_Size(self->children);
+    ORCompilerIVARS *const ivars = ORCompiler_IVARS(self);
+    uint32_t num_kids = VA_Get_Size(ivars->children);
 
     if (num_kids == 1) {
         // No need for an ORMatcher wrapper.
-        Compiler *only_child = (Compiler*)VA_Fetch(self->children, 0);
+        Compiler *only_child = (Compiler*)VA_Fetch(ivars->children, 0);
         return Compiler_Make_Matcher(only_child, reader, need_score);
     }
     else {
@@ -108,7 +110,7 @@ ORCompiler_make_matcher(ORCompiler *self, SegReader *reader,
 
         // Accumulate sub-matchers.
         for (uint32_t i = 0; i < num_kids; i++) {
-            Compiler *child = (Compiler*)VA_Fetch(self->children, i);
+            Compiler *child = (Compiler*)VA_Fetch(ivars->children, i);
             Matcher *submatcher
                 = Compiler_Make_Matcher(child, reader, need_score);
             VA_Push(submatchers, (Obj*)submatcher);

http://git-wip-us.apache.org/repos/asf/lucy/blob/ec90e666/core/Lucy/Search/PhraseMatcher.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Search/PhraseMatcher.c b/core/Lucy/Search/PhraseMatcher.c
index a101980..0fb956d 100644
--- a/core/Lucy/Search/PhraseMatcher.c
+++ b/core/Lucy/Search/PhraseMatcher.c
@@ -36,56 +36,59 @@ PhraseMatcher*
 PhraseMatcher_init(PhraseMatcher *self, Similarity *similarity, VArray *plists,
                    Compiler *compiler) {
     Matcher_init((Matcher*)self);
+    PhraseMatcherIVARS *const ivars = PhraseMatcher_IVARS(self);
 
     // Init.
-    self->anchor_set       = BB_new(0);
-    self->phrase_freq      = 0.0;
-    self->phrase_boost     = 0.0;
-    self->first_time       = true;
-    self->more             = true;
+    ivars->anchor_set       = BB_new(0);
+    ivars->phrase_freq      = 0.0;
+    ivars->phrase_boost     = 0.0;
+    ivars->first_time       = true;
+    ivars->more             = true;
 
     // Extract PostingLists out of VArray into local C array for quick access.
-    self->num_elements = VA_Get_Size(plists);
-    self->plists = (PostingList**)MALLOCATE(
-                       self->num_elements * sizeof(PostingList*));
-    for (size_t i = 0; i < self->num_elements; i++) {
+    ivars->num_elements = VA_Get_Size(plists);
+    ivars->plists = (PostingList**)MALLOCATE(
+                       ivars->num_elements * sizeof(PostingList*));
+    for (size_t i = 0; i < ivars->num_elements; i++) {
         PostingList *const plist
             = (PostingList*)CERTIFY(VA_Fetch(plists, i), POSTINGLIST);
         if (plist == NULL) {
             THROW(ERR, "Missing element %u32", i);
         }
-        self->plists[i] = (PostingList*)INCREF(plist);
+        ivars->plists[i] = (PostingList*)INCREF(plist);
     }
 
     // Assign.
-    self->sim       = (Similarity*)INCREF(similarity);
-    self->compiler  = (Compiler*)INCREF(compiler);
-    self->weight    = Compiler_Get_Weight(compiler);
+    ivars->sim       = (Similarity*)INCREF(similarity);
+    ivars->compiler  = (Compiler*)INCREF(compiler);
+    ivars->weight    = Compiler_Get_Weight(compiler);
 
     return self;
 }
 
 void
 PhraseMatcher_destroy(PhraseMatcher *self) {
-    if (self->plists) {
-        for (size_t i = 0; i < self->num_elements; i++) {
-            DECREF(self->plists[i]);
+    PhraseMatcherIVARS *const ivars = PhraseMatcher_IVARS(self);
+    if (ivars->plists) {
+        for (size_t i = 0; i < ivars->num_elements; i++) {
+            DECREF(ivars->plists[i]);
         }
-        FREEMEM(self->plists);
+        FREEMEM(ivars->plists);
     }
-    DECREF(self->sim);
-    DECREF(self->anchor_set);
-    DECREF(self->compiler);
+    DECREF(ivars->sim);
+    DECREF(ivars->anchor_set);
+    DECREF(ivars->compiler);
     SUPER_DESTROY(self, PHRASEMATCHER);
 }
 
 int32_t
 PhraseMatcher_next(PhraseMatcher *self) {
-    if (self->first_time) {
+    PhraseMatcherIVARS *const ivars = PhraseMatcher_IVARS(self);
+    if (ivars->first_time) {
         return PhraseMatcher_Advance(self, 1);
     }
-    else if (self->more) {
-        const int32_t target = PList_Get_Doc_ID(self->plists[0]) + 1;
+    else if (ivars->more) {
+        const int32_t target = PList_Get_Doc_ID(ivars->plists[0]) + 1;
         return PhraseMatcher_Advance(self, target);
     }
     else {
@@ -95,25 +98,26 @@ PhraseMatcher_next(PhraseMatcher *self) {
 
 int32_t
 PhraseMatcher_advance(PhraseMatcher *self, int32_t target) {
-    PostingList **const plists       = self->plists;
-    const uint32_t      num_elements = self->num_elements;
+    PhraseMatcherIVARS *const ivars  = PhraseMatcher_IVARS(self);
+    PostingList **const plists       = ivars->plists;
+    const uint32_t      num_elements = ivars->num_elements;
     int32_t             highest      = 0;
 
     // Reset match variables to indicate no match.  New values will be
     // assigned if a match succeeds.
-    self->phrase_freq = 0.0;
-    self->doc_id      = 0;
+    ivars->phrase_freq = 0.0;
+    ivars->doc_id      = 0;
 
     // Find the lowest possible matching doc ID greater than the current doc
     // ID.  If any one of the PostingLists is exhausted, we're done.
-    if (self->first_time) {
-        self->first_time = false;
+    if (ivars->first_time) {
+        ivars->first_time = false;
 
         // On the first call to Advance(), advance all PostingLists.
-        for (size_t i = 0, max = self->num_elements; i < max; i++) {
+        for (size_t i = 0, max = ivars->num_elements; i < max; i++) {
             int32_t candidate = PList_Advance(plists[i], target);
             if (!candidate) {
-                self->more = false;
+                ivars->more = false;
                 return 0;
             }
             else if (candidate > highest) {
@@ -127,7 +131,7 @@ PhraseMatcher_advance(PhraseMatcher *self, int32_t target) {
         // becomes the minimum target which all the others must move up to.
         highest = PList_Advance(plists[0], target);
         if (highest == 0) {
-            self->more = false;
+            ivars->more = false;
             return 0;
         }
     }
@@ -152,7 +156,7 @@ PhraseMatcher_advance(PhraseMatcher *self, int32_t target) {
 
                 // If this PostingList is exhausted, we're done.
                 if (candidate == 0) {
-                    self->more = false;
+                    ivars->more = false;
                     return 0;
                 }
 
@@ -174,14 +178,14 @@ PhraseMatcher_advance(PhraseMatcher *self, int32_t target) {
         // If we've found a doc with all terms in it, see if they form a
         // phrase.
         if (agreement && highest >= target) {
-            self->phrase_freq = PhraseMatcher_Calc_Phrase_Freq(self);
-            if (self->phrase_freq == 0.0) {
+            ivars->phrase_freq = PhraseMatcher_Calc_Phrase_Freq(self);
+            if (ivars->phrase_freq == 0.0) {
                 // No phrase.  Move on to another doc.
                 target += 1;
             }
             else {
                 // Success!
-                self->doc_id = highest;
+                ivars->doc_id = highest;
                 return highest;
             }
         }
@@ -241,7 +245,8 @@ DONE:
 
 float
 PhraseMatcher_calc_phrase_freq(PhraseMatcher *self) {
-    PostingList **const plists = self->plists;
+    PhraseMatcherIVARS *const ivars = PhraseMatcher_IVARS(self);
+    PostingList **const plists = ivars->plists;
 
     /* Create a overwriteable "anchor set" from the first posting.
      *
@@ -263,21 +268,23 @@ PhraseMatcher_calc_phrase_freq(PhraseMatcher *self) {
      * is our phrase freq.
      */
     ScorePosting *posting = (ScorePosting*)PList_Get_Posting(plists[0]);
-    uint32_t anchors_remaining = posting->freq;
+    ScorePostingIVARS *const post_ivars = ScorePost_IVARS(posting);
+    uint32_t anchors_remaining = post_ivars->freq;
     if (!anchors_remaining) { return 0.0f; }
 
     size_t    amount        = anchors_remaining * sizeof(uint32_t);
-    uint32_t *anchors_start = (uint32_t*)BB_Grow(self->anchor_set, amount);
+    uint32_t *anchors_start = (uint32_t*)BB_Grow(ivars->anchor_set, amount);
     uint32_t *anchors_end   = anchors_start + anchors_remaining;
-    memcpy(anchors_start, posting->prox, amount);
+    memcpy(anchors_start, post_ivars->prox, amount);
 
     // Match the positions of other terms against the anchor set.
-    for (uint32_t i = 1, max = self->num_elements; i < max; i++) {
+    for (uint32_t i = 1, max = ivars->num_elements; i < max; i++) {
         // Get the array of positions for the next term.  Unlike the anchor
         // set (which is a copy), these won't be overwritten.
-        ScorePosting *posting = (ScorePosting*)PList_Get_Posting(plists[i]);
-        uint32_t *candidates_start = posting->prox;
-        uint32_t *candidates_end   = candidates_start + posting->freq;
+        ScorePosting *next_post = (ScorePosting*)PList_Get_Posting(plists[i]);
+        ScorePostingIVARS *const next_post_ivars = ScorePost_IVARS(next_post);
+        uint32_t *candidates_start = next_post_ivars->prox;
+        uint32_t *candidates_end   = candidates_start + next_post_ivars->freq;
 
         // Splice out anchors that don't match the next term.  Bail out if
         // we've eliminated all possible anchors.
@@ -296,15 +303,16 @@ PhraseMatcher_calc_phrase_freq(PhraseMatcher *self) {
 
 int32_t
 PhraseMatcher_get_doc_id(PhraseMatcher *self) {
-    return self->doc_id;
+    return PhraseMatcher_IVARS(self)->doc_id;
 }
 
 float
 PhraseMatcher_score(PhraseMatcher *self) {
-    ScorePosting *posting = (ScorePosting*)PList_Get_Posting(self->plists[0]);
-    float score = Sim_TF(self->sim, self->phrase_freq)
-                  * self->weight
-                  * posting->weight;
+    PhraseMatcherIVARS *const ivars = PhraseMatcher_IVARS(self);
+    ScorePosting *posting = (ScorePosting*)PList_Get_Posting(ivars->plists[0]);
+    float score = Sim_TF(ivars->sim, ivars->phrase_freq)
+                  * ivars->weight
+                  * ScorePost_IVARS(posting)->weight;
     return score;
 }
 


[lucy-commits] [32/34] git commit: refs/heads/master - Avoid non-parcel member access in TestLucy.

Posted by ma...@apache.org.
Avoid non-parcel member access in TestLucy.

Use various techniques to avoid accessing member vars defined in other
parcels.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/bef4852e
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/bef4852e
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/bef4852e

Branch: refs/heads/master
Commit: bef4852e664e0232267cc585a32275dd3031abae
Parents: abf9363
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Fri Jul 12 19:18:18 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 16:08:44 2013 -0700

----------------------------------------------------------------------
 core/Lucy/Test/Search/TestQueryParserLogic.c |  2 +-
 core/Lucy/Test/Search/TestSortSpec.c         |  7 +-----
 core/Lucy/Test/TestSchema.c                  | 26 +++++++++++++----------
 core/Lucy/Test/TestSchema.cfh                |  6 ++++--
 4 files changed, 21 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/bef4852e/core/Lucy/Test/Search/TestQueryParserLogic.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Test/Search/TestQueryParserLogic.c b/core/Lucy/Test/Search/TestQueryParserLogic.c
index 22a86c1..5bc51e9 100644
--- a/core/Lucy/Test/Search/TestQueryParserLogic.c
+++ b/core/Lucy/Test/Search/TestQueryParserLogic.c
@@ -858,7 +858,7 @@ static Lucy_TestQPLogic_Prune_Test_t prune_test_funcs[] = {
 
 static Folder*
 S_create_index() {
-    Schema     *schema  = (Schema*)TestSchema_new();
+    Schema     *schema  = (Schema*)TestSchema_new(false);
     RAMFolder  *folder  = RAMFolder_new(NULL);
     VArray     *doc_set = TestUtils_doc_set();
     Indexer    *indexer = Indexer_new(schema, (Obj*)folder, NULL, 0);

http://git-wip-us.apache.org/repos/asf/lucy/blob/bef4852e/core/Lucy/Test/Search/TestSortSpec.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Test/Search/TestSortSpec.c b/core/Lucy/Test/Search/TestSortSpec.c
index 990ac9d..1a7df6d 100644
--- a/core/Lucy/Test/Search/TestSortSpec.c
+++ b/core/Lucy/Test/Search/TestSortSpec.c
@@ -153,12 +153,7 @@ TestReverseType_init(TestReverseType *self) {
 TestReverseType*
 TestReverseType_init2(TestReverseType *self, float boost, bool indexed,
                       bool stored, bool sortable) {
-    FType_init((FieldType*)self);
-    TestReverseTypeIVARS *const ivars = TestReverseType_IVARS(self);
-    ivars->boost      = boost;
-    ivars->indexed    = indexed;
-    ivars->stored     = stored;
-    ivars->sortable   = sortable;
+    Int32Type_init2((Int32Type*)self, boost, indexed, stored, sortable);
     return self;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/bef4852e/core/Lucy/Test/TestSchema.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Test/TestSchema.c b/core/Lucy/Test/TestSchema.c
index 2507bfb..6c28296 100644
--- a/core/Lucy/Test/TestSchema.c
+++ b/core/Lucy/Test/TestSchema.c
@@ -27,16 +27,18 @@
 #include "Lucy/Plan/Architecture.h"
 
 TestSchema*
-TestSchema_new() {
+TestSchema_new(bool use_alt_arch) {
     TestSchema *self = (TestSchema*)VTable_Make_Obj(TESTSCHEMA);
-    return TestSchema_init(self);
+    return TestSchema_init(self, use_alt_arch);
 }
 
 TestSchema*
-TestSchema_init(TestSchema *self) {
+TestSchema_init(TestSchema *self, bool use_alt_arch) {
     StandardTokenizer *tokenizer = StandardTokenizer_new();
     FullTextType *type = FullTextType_new((Analyzer*)tokenizer);
 
+    TestSchema_IVARS(self)->use_alt_arch = use_alt_arch;
+
     Schema_init((Schema*)self);
     FullTextType_Set_Highlightable(type, true);
     CharBuf *content = (CharBuf*)ZCB_WRAP_STR("content", 7);
@@ -49,8 +51,12 @@ TestSchema_init(TestSchema *self) {
 
 Architecture*
 TestSchema_architecture(TestSchema *self) {
-    UNUSED_VAR(self);
-    return (Architecture*)TestArch_new();
+    if (TestSchema_IVARS(self)->use_alt_arch) {
+        return Arch_new();
+    }
+    else {
+        return (Architecture*)TestArch_new();
+    }
 }
 
 TestBatchSchema*
@@ -60,9 +66,9 @@ TestBatchSchema_new() {
 
 static void
 test_Equals(TestBatchRunner *runner) {
-    TestSchema *schema = TestSchema_new();
-    TestSchema *arch_differs = TestSchema_new();
-    TestSchema *spec_differs = TestSchema_new();
+    TestSchema *schema = TestSchema_new(false);
+    TestSchema *arch_differs = TestSchema_new(true);
+    TestSchema *spec_differs = TestSchema_new(false);
     CharBuf    *content      = (CharBuf*)ZCB_WRAP_STR("content", 7);
     FullTextType *type = (FullTextType*)TestSchema_Fetch_Type(spec_differs,
                                                               content);
@@ -73,8 +79,6 @@ test_Equals(TestBatchRunner *runner) {
     TEST_FALSE(runner, TestSchema_Equals(schema, (Obj*)spec_differs),
                "Equals spoiled by differing FieldType");
 
-    DECREF(TestSchema_IVARS(arch_differs)->arch);
-    TestSchema_IVARS(arch_differs)->arch = Arch_new();
     TEST_FALSE(runner, TestSchema_Equals(schema, (Obj*)arch_differs),
                "Equals spoiled by differing Architecture");
 
@@ -85,7 +89,7 @@ test_Equals(TestBatchRunner *runner) {
 
 static void
 test_Dump_and_Load(TestBatchRunner *runner) {
-    TestSchema *schema = TestSchema_new();
+    TestSchema *schema = TestSchema_new(false);
     Obj        *dump   = (Obj*)TestSchema_Dump(schema);
     TestSchema *loaded = (TestSchema*)Obj_Load(dump, dump);
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/bef4852e/core/Lucy/Test/TestSchema.cfh
----------------------------------------------------------------------
diff --git a/core/Lucy/Test/TestSchema.cfh b/core/Lucy/Test/TestSchema.cfh
index c422435..87dd41a 100644
--- a/core/Lucy/Test/TestSchema.cfh
+++ b/core/Lucy/Test/TestSchema.cfh
@@ -23,11 +23,13 @@ parcel TestLucy;
  */
 
 class Lucy::Test::TestSchema inherits Lucy::Plan::Schema {
+    bool use_alt_arch;
+
     inert incremented TestSchema*
-    new();
+    new(bool use_alt_arch = false);
 
     inert TestSchema*
-    init(TestSchema *self);
+    init(TestSchema *self, bool use_alt_arch = false);
 
     public incremented Architecture*
     Architecture(TestSchema *self);


[lucy-commits] [25/34] git commit: refs/heads/master - Make object structs outside of Clownfish opaque.

Posted by ma...@apache.org.
Make object structs outside of Clownfish opaque.

Do not define object struct definitions outside the Clownfish package,
forcing all access to go through IVARS structs.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/0a487121
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/0a487121
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/0a487121

Branch: refs/heads/master
Commit: 0a4871214993943df1a64b5bafad99cee7e2ecd2
Parents: bbdd3c7
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Thu Jul 11 15:27:52 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 16:08:43 2013 -0700

----------------------------------------------------------------------
 clownfish/compiler/src/CFCBindClass.c | 25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/0a487121/clownfish/compiler/src/CFCBindClass.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCBindClass.c b/clownfish/compiler/src/CFCBindClass.c
index 33b4d71..452b58f 100644
--- a/clownfish/compiler/src/CFCBindClass.c
+++ b/clownfish/compiler/src/CFCBindClass.c
@@ -157,6 +157,7 @@ S_ivars_hack(CFCBindClass *self) {
     const char *full_ivars  = CFCClass_full_ivars_name(self->client);
     const char *short_ivars = CFCClass_short_ivars_name(self->client);
     const char *prefix      = CFCClass_get_prefix(self->client);
+    const char *PREFIX      = CFCClass_get_PREFIX(self->client);
     const char *class_cnick = CFCClass_get_cnick(self->client);
     char pattern[] =
         "typedef struct %s %s;\n"
@@ -169,8 +170,8 @@ S_ivars_hack(CFCBindClass *self) {
         "  #define %s_IVARS %s%s_IVARS\n"
         "#endif\n";
     char *content
-        = CFCUtil_sprintf(pattern, full_struct, full_ivars, full_ivars, prefix,
-                          class_cnick, full_struct, full_ivars, prefix,
+        = CFCUtil_sprintf(pattern, full_ivars, full_ivars, full_ivars, prefix,
+                          class_cnick, full_struct, full_ivars, PREFIX,
                           short_ivars, full_ivars, class_cnick, prefix,
                           class_cnick);
     return content;
@@ -360,7 +361,15 @@ CFCBindClass_to_c_data(CFCBindClass *self) {
 // Create the definition for the instantiable object struct.
 static char*
 S_struct_definition(CFCBindClass *self) {
-    const char *struct_sym = CFCClass_full_struct_sym(self->client);
+    const char *struct_sym;
+    const char *prefix = CFCClass_get_prefix(self->client);
+    if (strcmp(prefix, "cfish_") == 0) {
+        struct_sym = CFCClass_full_struct_sym(self->client);
+    }
+    else {
+        struct_sym = CFCClass_full_ivars_name(self->client);
+    }
+
     CFCVariable **member_vars = CFCClass_member_vars(self->client);
     char *member_decs = CFCUtil_strdup("");
 
@@ -410,18 +419,24 @@ CFCBindClass_spec_def(CFCBindClass *self) {
     FREEMEM(fresh_methods);
     const char *ms_var = num_fresh ? self->method_specs_var : "NULL";
 
+    // Hack to get size of object.  TODO: This will have to be replaced by
+    // dynamic initialization.
+    char *ivars_or_not = strcmp(CFCClass_get_prefix(client), "cfish_") == 0
+                         ? "" : "IVARS";
+
     char pattern[] =
         "    {\n"
         "        &%s, /* vtable */\n"
         "        %s, /* parent */\n"
         "        \"%s\", /* name */\n"
-        "        sizeof(%s), /* obj_alloc_size */\n"
+        "        sizeof(%s%s), /* obj_alloc_size */\n"
         "        %d, /* num_fresh */\n"
         "        %d, /* num_novel */\n"
         "        %s /* method_specs */\n"
         "    }";
     char *code = CFCUtil_sprintf(pattern, vt_var, parent_ref, class_name,
-                                 struct_sym, num_fresh, num_novel, ms_var);
+                                 struct_sym, ivars_or_not,
+                                 num_fresh, num_novel, ms_var);
 
     FREEMEM(parent_ref);
     return code;


[lucy-commits] [13/34] git commit: refs/heads/master - Migrate Lucy's index classes to IVARS.

Posted by ma...@apache.org.
Migrate Lucy's index classes to IVARS.

Change all of Lucy's index classes to access instance vars via an IVARS struct
rather than via `self`.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/965fdb2a
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/965fdb2a
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/965fdb2a

Branch: refs/heads/master
Commit: 965fdb2ab938992dbad70e660d7cbf25e2acb34c
Parents: c2adaf5
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Sat Jun 29 17:49:23 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 16:08:42 2013 -0700

----------------------------------------------------------------------
 core/Lucy/Index/BackgroundMerger.c           | 227 ++++++------
 core/Lucy/Index/BitVecDelDocs.c              |  26 +-
 core/Lucy/Index/DataReader.c                 |  38 +-
 core/Lucy/Index/DataWriter.c                 |  32 +-
 core/Lucy/Index/DeletionsReader.c            |  67 ++--
 core/Lucy/Index/DeletionsWriter.c            | 112 +++---
 core/Lucy/Index/DocReader.c                  |  69 ++--
 core/Lucy/Index/DocVector.c                  |  36 +-
 core/Lucy/Index/DocWriter.c                  |  43 ++-
 core/Lucy/Index/FilePurger.c                 |  47 +--
 core/Lucy/Index/HighlightReader.c            |  73 ++--
 core/Lucy/Index/HighlightWriter.c            |  68 ++--
 core/Lucy/Index/IndexManager.c               |  97 ++---
 core/Lucy/Index/IndexReader.c                |  51 +--
 core/Lucy/Index/Indexer.c                    | 225 ++++++------
 core/Lucy/Index/Inverter.c                   | 181 +++++-----
 core/Lucy/Index/LexIndex.c                   |  86 ++---
 core/Lucy/Index/Lexicon.c                    |   8 +-
 core/Lucy/Index/LexiconReader.c              |  52 +--
 core/Lucy/Index/LexiconWriter.c              | 190 +++++-----
 core/Lucy/Index/PolyLexicon.c                |  62 ++--
 core/Lucy/Index/PolyReader.c                 | 111 +++---
 core/Lucy/Index/Posting.c                    |  10 +-
 core/Lucy/Index/PostingListReader.c          |  20 +-
 core/Lucy/Index/PostingListWriter.c          | 106 +++---
 core/Lucy/Index/PostingPool.c                | 418 ++++++++++++----------
 core/Lucy/Index/RawLexicon.c                 |  35 +-
 core/Lucy/Index/RawPostingList.c             |  25 +-
 core/Lucy/Index/SegLexicon.c                 |  87 +++--
 core/Lucy/Index/SegPostingList.c             | 153 ++++----
 core/Lucy/Index/SegReader.c                  |  30 +-
 core/Lucy/Index/SegWriter.c                  |  90 +++--
 core/Lucy/Index/Segment.c                    | 106 +++---
 core/Lucy/Index/Similarity.c                 |  17 +-
 core/Lucy/Index/SkipStepper.c                |  23 +-
 core/Lucy/Index/Snapshot.c                   |  58 +--
 core/Lucy/Index/SortCache.c                  |  71 ++--
 core/Lucy/Index/SortCache/NumericSortCache.c |  60 ++--
 core/Lucy/Index/SortCache/TextSortCache.c    |  49 +--
 core/Lucy/Index/SortFieldWriter.c            | 401 +++++++++++----------
 core/Lucy/Index/SortReader.c                 |  94 ++---
 core/Lucy/Index/SortWriter.c                 | 124 ++++---
 core/Lucy/Index/TermInfo.c                   |  61 ++--
 core/Lucy/Index/TermStepper.c                |  18 +-
 core/Lucy/Index/TermVector.c                 |  83 ++---
 core/Lucy/Index/ZombieKeyedHash.c            |  23 +-
 46 files changed, 2213 insertions(+), 1850 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/BackgroundMerger.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/BackgroundMerger.c b/core/Lucy/Index/BackgroundMerger.c
index db80f68..a32f215 100644
--- a/core/Lucy/Index/BackgroundMerger.c
+++ b/core/Lucy/Index/BackgroundMerger.c
@@ -65,86 +65,87 @@ BGMerger_new(Obj *index, IndexManager *manager) {
 
 BackgroundMerger*
 BGMerger_init(BackgroundMerger *self, Obj *index, IndexManager *manager) {
+    BackgroundMergerIVARS *const ivars = BGMerger_IVARS(self);
     Folder *folder = S_init_folder(index);
 
     // Init.
-    self->optimize      = false;
-    self->prepared      = false;
-    self->needs_commit  = false;
-    self->snapfile      = NULL;
-    self->doc_maps      = Hash_new(0);
+    ivars->optimize      = false;
+    ivars->prepared      = false;
+    ivars->needs_commit  = false;
+    ivars->snapfile      = NULL;
+    ivars->doc_maps      = Hash_new(0);
 
     // Assign.
-    self->folder = folder;
+    ivars->folder = folder;
     if (manager) {
-        self->manager = (IndexManager*)INCREF(manager);
+        ivars->manager = (IndexManager*)INCREF(manager);
     }
     else {
-        self->manager = IxManager_new(NULL, NULL);
-        IxManager_Set_Write_Lock_Timeout(self->manager, 10000);
+        ivars->manager = IxManager_new(NULL, NULL);
+        IxManager_Set_Write_Lock_Timeout(ivars->manager, 10000);
     }
-    IxManager_Set_Folder(self->manager, folder);
+    IxManager_Set_Folder(ivars->manager, folder);
 
     // Obtain write lock (which we'll only hold briefly), then merge lock.
     S_obtain_write_lock(self);
-    if (!self->write_lock) {
+    if (!ivars->write_lock) {
         DECREF(self);
         RETHROW(INCREF(Err_get_error()));
     }
     S_obtain_merge_lock(self);
-    if (!self->merge_lock) {
+    if (!ivars->merge_lock) {
         DECREF(self);
         RETHROW(INCREF(Err_get_error()));
     }
 
     // Find the latest snapshot.  If there's no index content, bail early.
-    self->snapshot = Snapshot_Read_File(Snapshot_new(), folder, NULL);
-    if (!Snapshot_Get_Path(self->snapshot)) {
+    ivars->snapshot = Snapshot_Read_File(Snapshot_new(), folder, NULL);
+    if (!Snapshot_Get_Path(ivars->snapshot)) {
         S_release_write_lock(self);
         S_release_merge_lock(self);
         return self;
     }
 
     // Create FilePurger. Zap detritus from previous sessions.
-    self->file_purger = FilePurger_new(folder, self->snapshot, self->manager);
-    FilePurger_Purge(self->file_purger);
+    ivars->file_purger = FilePurger_new(folder, ivars->snapshot, ivars->manager);
+    FilePurger_Purge(ivars->file_purger);
 
     // Open a PolyReader, passing in the IndexManager so we get a read lock on
     // the Snapshot's files -- so that Indexers don't zap our files while
     // we're operating in the background.
-    self->polyreader = PolyReader_open((Obj*)folder, NULL, self->manager);
+    ivars->polyreader = PolyReader_open((Obj*)folder, NULL, ivars->manager);
 
     // Clone the PolyReader's schema.
-    Hash *dump = Schema_Dump(PolyReader_Get_Schema(self->polyreader));
-    self->schema = (Schema*)CERTIFY(VTable_Load_Obj(SCHEMA, (Obj*)dump),
+    Hash *dump = Schema_Dump(PolyReader_Get_Schema(ivars->polyreader));
+    ivars->schema = (Schema*)CERTIFY(VTable_Load_Obj(SCHEMA, (Obj*)dump),
                                     SCHEMA);
     DECREF(dump);
 
     // Create new Segment.
     int64_t new_seg_num
-        = IxManager_Highest_Seg_Num(self->manager, self->snapshot) + 1;
-    VArray *fields = Schema_All_Fields(self->schema);
-    self->segment = Seg_new(new_seg_num);
+        = IxManager_Highest_Seg_Num(ivars->manager, ivars->snapshot) + 1;
+    VArray *fields = Schema_All_Fields(ivars->schema);
+    ivars->segment = Seg_new(new_seg_num);
     for (uint32_t i = 0, max = VA_Get_Size(fields); i < max; i++) {
-        Seg_Add_Field(self->segment, (CharBuf*)VA_Fetch(fields, i));
+        Seg_Add_Field(ivars->segment, (CharBuf*)VA_Fetch(fields, i));
     }
     DECREF(fields);
 
     // Our "cutoff" is the segment this BackgroundMerger will write.  Now that
     // we've determined the cutoff, write the merge data file.
-    self->cutoff = Seg_Get_Number(self->segment);
-    IxManager_Write_Merge_Data(self->manager, self->cutoff);
+    ivars->cutoff = Seg_Get_Number(ivars->segment);
+    IxManager_Write_Merge_Data(ivars->manager, ivars->cutoff);
 
     /* Create the SegWriter but hold off on preparing the new segment
      * directory -- because if we don't need to merge any segments we don't
      * need it.  (We've reserved the dir by plopping down the merge.json
      * file.) */
-    self->seg_writer = SegWriter_new(self->schema, self->snapshot,
-                                     self->segment, self->polyreader);
+    ivars->seg_writer = SegWriter_new(ivars->schema, ivars->snapshot,
+                                      ivars->segment, ivars->polyreader);
 
     // Grab a local ref to the DeletionsWriter.
-    self->del_writer
-        = (DeletionsWriter*)INCREF(SegWriter_Get_Del_Writer(self->seg_writer));
+    ivars->del_writer
+        = (DeletionsWriter*)INCREF(SegWriter_Get_Del_Writer(ivars->seg_writer));
 
     // Release the write lock.  Now new Indexers can start while we work in
     // the background.
@@ -155,20 +156,21 @@ BGMerger_init(BackgroundMerger *self, Obj *index, IndexManager *manager) {
 
 void
 BGMerger_destroy(BackgroundMerger *self) {
+    BackgroundMergerIVARS *const ivars = BGMerger_IVARS(self);
     S_release_merge_lock(self);
     S_release_write_lock(self);
-    DECREF(self->schema);
-    DECREF(self->folder);
-    DECREF(self->segment);
-    DECREF(self->manager);
-    DECREF(self->polyreader);
-    DECREF(self->del_writer);
-    DECREF(self->snapshot);
-    DECREF(self->seg_writer);
-    DECREF(self->file_purger);
-    DECREF(self->write_lock);
-    DECREF(self->snapfile);
-    DECREF(self->doc_maps);
+    DECREF(ivars->schema);
+    DECREF(ivars->folder);
+    DECREF(ivars->segment);
+    DECREF(ivars->manager);
+    DECREF(ivars->polyreader);
+    DECREF(ivars->del_writer);
+    DECREF(ivars->snapshot);
+    DECREF(ivars->seg_writer);
+    DECREF(ivars->file_purger);
+    DECREF(ivars->write_lock);
+    DECREF(ivars->snapfile);
+    DECREF(ivars->doc_maps);
     SUPER_DESTROY(self, BACKGROUNDMERGER);
 }
 
@@ -197,13 +199,14 @@ S_init_folder(Obj *index) {
 
 void
 BGMerger_optimize(BackgroundMerger *self) {
-    self->optimize = true;
+    BGMerger_IVARS(self)->optimize = true;
 }
 
 static uint32_t
 S_maybe_merge(BackgroundMerger *self) {
-    VArray *to_merge = IxManager_Recycle(self->manager, self->polyreader,
-                                         self->del_writer, 0, self->optimize);
+    BackgroundMergerIVARS *const ivars = BGMerger_IVARS(self);
+    VArray *to_merge = IxManager_Recycle(ivars->manager, ivars->polyreader,
+                                         ivars->del_writer, 0, ivars->optimize);
     int32_t num_to_merge = VA_Get_Size(to_merge);
 
     // There's no point in merging one segment if it has no deletions, because
@@ -221,22 +224,22 @@ S_maybe_merge(BackgroundMerger *self) {
     }
 
     // Now that we're sure we're writing a new segment, prep the seg dir.
-    SegWriter_Prep_Seg_Dir(self->seg_writer);
+    SegWriter_Prep_Seg_Dir(ivars->seg_writer);
 
     // Consolidate segments.
     for (uint32_t i = 0, max = num_to_merge; i < max; i++) {
         SegReader *seg_reader = (SegReader*)VA_Fetch(to_merge, i);
         CharBuf   *seg_name   = SegReader_Get_Seg_Name(seg_reader);
-        int64_t    doc_count  = Seg_Get_Count(self->segment);
+        int64_t    doc_count  = Seg_Get_Count(ivars->segment);
         Matcher *deletions
-            = DelWriter_Seg_Deletions(self->del_writer, seg_reader);
+            = DelWriter_Seg_Deletions(ivars->del_writer, seg_reader);
         I32Array *doc_map = DelWriter_Generate_Doc_Map(
-                                self->del_writer, deletions,
+                                ivars->del_writer, deletions,
                                 SegReader_Doc_Max(seg_reader),
                                 (int32_t)doc_count);
 
-        Hash_Store(self->doc_maps, (Obj*)seg_name, (Obj*)doc_map);
-        SegWriter_Merge_Segment(self->seg_writer, seg_reader, doc_map);
+        Hash_Store(ivars->doc_maps, (Obj*)seg_name, (Obj*)doc_map);
+        SegWriter_Merge_Segment(ivars->seg_writer, seg_reader, doc_map);
         DECREF(deletions);
     }
 
@@ -246,14 +249,15 @@ S_maybe_merge(BackgroundMerger *self) {
 
 static bool
 S_merge_updated_deletions(BackgroundMerger *self) {
+    BackgroundMergerIVARS *const ivars = BGMerger_IVARS(self);
     Hash *updated_deletions = NULL;
 
     PolyReader *new_polyreader
-        = PolyReader_open((Obj*)self->folder, NULL, NULL);
+        = PolyReader_open((Obj*)ivars->folder, NULL, NULL);
     VArray *new_seg_readers
         = PolyReader_Get_Seg_Readers(new_polyreader);
     VArray *old_seg_readers
-        = PolyReader_Get_Seg_Readers(self->polyreader);
+        = PolyReader_Get_Seg_Readers(ivars->polyreader);
     Hash *new_segs = Hash_new(VA_Get_Size(new_seg_readers));
 
     for (uint32_t i = 0, max = VA_Get_Size(new_seg_readers); i < max; i++) {
@@ -267,7 +271,7 @@ S_merge_updated_deletions(BackgroundMerger *self) {
         CharBuf   *seg_name   = SegReader_Get_Seg_Name(seg_reader);
 
         // If this segment was merged away...
-        if (Hash_Fetch(self->doc_maps, (Obj*)seg_name)) {
+        if (Hash_Fetch(ivars->doc_maps, (Obj*)seg_name)) {
             SegReader *new_seg_reader
                 = (SegReader*)CERTIFY(
                       Hash_Fetch(new_segs, (Obj*)seg_name),
@@ -297,18 +301,18 @@ S_merge_updated_deletions(BackgroundMerger *self) {
     }
     else {
         PolyReader *merge_polyreader
-            = PolyReader_open((Obj*)self->folder, self->snapshot, NULL);
+            = PolyReader_open((Obj*)ivars->folder, ivars->snapshot, NULL);
         VArray *merge_seg_readers
             = PolyReader_Get_Seg_Readers(merge_polyreader);
         Snapshot *latest_snapshot
-            = Snapshot_Read_File(Snapshot_new(), self->folder, NULL);
+            = Snapshot_Read_File(Snapshot_new(), ivars->folder, NULL);
         int64_t new_seg_num
-            = IxManager_Highest_Seg_Num(self->manager, latest_snapshot) + 1;
+            = IxManager_Highest_Seg_Num(ivars->manager, latest_snapshot) + 1;
         Segment   *new_segment = Seg_new(new_seg_num);
-        SegWriter *seg_writer  = SegWriter_new(self->schema, self->snapshot,
+        SegWriter *seg_writer  = SegWriter_new(ivars->schema, ivars->snapshot,
                                                new_segment, merge_polyreader);
         DeletionsWriter *del_writer = SegWriter_Get_Del_Writer(seg_writer);
-        int64_t  merge_seg_num = Seg_Get_Number(self->segment);
+        int64_t  merge_seg_num = Seg_Get_Number(ivars->segment);
         uint32_t seg_tick      = INT32_MAX;
         int32_t  offset        = INT32_MAX;
         CharBuf *seg_name      = NULL;
@@ -334,7 +338,7 @@ S_merge_updated_deletions(BackgroundMerger *self) {
               ) {
             I32Array *doc_map
                 = (I32Array*)CERTIFY(
-                      Hash_Fetch(self->doc_maps, (Obj*)seg_name),
+                      Hash_Fetch(ivars->doc_maps, (Obj*)seg_name),
                       I32ARRAY);
             int32_t del;
             while (0 != (del = Matcher_Next(deletions))) {
@@ -365,11 +369,12 @@ S_merge_updated_deletions(BackgroundMerger *self) {
 
 void
 BGMerger_prepare_commit(BackgroundMerger *self) {
-    VArray   *seg_readers     = PolyReader_Get_Seg_Readers(self->polyreader);
+    BackgroundMergerIVARS *const ivars = BGMerger_IVARS(self);
+    VArray   *seg_readers     = PolyReader_Get_Seg_Readers(ivars->polyreader);
     uint32_t  num_seg_readers = VA_Get_Size(seg_readers);
     uint32_t  segs_merged     = 0;
 
-    if (self->prepared) {
+    if (ivars->prepared) {
         THROW(ERR, "Can't call Prepare_Commit() more than once");
     }
 
@@ -379,46 +384,46 @@ BGMerger_prepare_commit(BackgroundMerger *self) {
     }
 
     if (!segs_merged) {
-        // Nothing merged.  Leave self->needs_commit false and bail out.
-        self->prepared = true;
+        // Nothing merged.  Leave `needs_commit` false and bail out.
+        ivars->prepared = true;
         return;
     }
     // Finish the segment and write a new snapshot file.
     else {
-        Folder   *folder   = self->folder;
-        Snapshot *snapshot = self->snapshot;
+        Folder   *folder   = ivars->folder;
+        Snapshot *snapshot = ivars->snapshot;
 
         // Write out new deletions.
-        if (DelWriter_Updated(self->del_writer)) {
+        if (DelWriter_Updated(ivars->del_writer)) {
             // Only write out if they haven't all been applied.
             if (segs_merged != num_seg_readers) {
-                DelWriter_Finish(self->del_writer);
+                DelWriter_Finish(ivars->del_writer);
             }
         }
 
         // Finish the segment.
-        SegWriter_Finish(self->seg_writer);
+        SegWriter_Finish(ivars->seg_writer);
 
         // Grab the write lock.
         S_obtain_write_lock(self);
-        if (!self->write_lock) {
+        if (!ivars->write_lock) {
             RETHROW(INCREF(Err_get_error()));
         }
 
         // Write temporary snapshot file.
-        DECREF(self->snapfile);
-        self->snapfile = IxManager_Make_Snapshot_Filename(self->manager);
-        CB_Cat_Trusted_Str(self->snapfile, ".temp", 5);
-        Folder_Delete(folder, self->snapfile);
-        Snapshot_Write_File(snapshot, folder, self->snapfile);
+        DECREF(ivars->snapfile);
+        ivars->snapfile = IxManager_Make_Snapshot_Filename(ivars->manager);
+        CB_Cat_Trusted_Str(ivars->snapfile, ".temp", 5);
+        Folder_Delete(folder, ivars->snapfile);
+        Snapshot_Write_File(snapshot, folder, ivars->snapfile);
 
         // Determine whether the index has been updated while this background
         // merge process was running.
 
         CharBuf *start_snapfile
-            = Snapshot_Get_Path(PolyReader_Get_Snapshot(self->polyreader));
+            = Snapshot_Get_Path(PolyReader_Get_Snapshot(ivars->polyreader));
         Snapshot *latest_snapshot
-            = Snapshot_Read_File(Snapshot_new(), self->folder, NULL);
+            = Snapshot_Read_File(Snapshot_new(), ivars->folder, NULL);
         CharBuf *latest_snapfile = Snapshot_Get_Path(latest_snapshot);
         bool index_updated
             = !CB_Equals(start_snapfile, (Obj*)latest_snapfile);
@@ -440,56 +445,58 @@ BGMerger_prepare_commit(BackgroundMerger *self) {
                 CharBuf *file = (CharBuf*)VA_Fetch(files, i);
                 if (CB_Starts_With_Str(file, "seg_", 4)) {
                     int64_t gen = (int64_t)IxFileNames_extract_gen(file);
-                    if (gen > self->cutoff) {
-                        Snapshot_Add_Entry(self->snapshot, file);
+                    if (gen > ivars->cutoff) {
+                        Snapshot_Add_Entry(ivars->snapshot, file);
                     }
                 }
             }
             DECREF(files);
 
             // Since the snapshot content has changed, we need to rewrite it.
-            Folder_Delete(folder, self->snapfile);
-            Snapshot_Write_File(snapshot, folder, self->snapfile);
+            Folder_Delete(folder, ivars->snapfile);
+            Snapshot_Write_File(snapshot, folder, ivars->snapfile);
         }
 
         DECREF(latest_snapshot);
 
-        self->needs_commit = true;
+        ivars->needs_commit = true;
     }
 
     // Close reader, so that we can delete its files if appropriate.
-    PolyReader_Close(self->polyreader);
+    PolyReader_Close(ivars->polyreader);
 
-    self->prepared = true;
+    ivars->prepared = true;
 }
 
 void
 BGMerger_commit(BackgroundMerger *self) {
+    BackgroundMergerIVARS *const ivars = BGMerger_IVARS(self);
+
     // Safety check.
-    if (!self->merge_lock) {
+    if (!ivars->merge_lock) {
         THROW(ERR, "Can't call commit() more than once");
     }
 
-    if (!self->prepared) {
+    if (!ivars->prepared) {
         BGMerger_Prepare_Commit(self);
     }
 
-    if (self->needs_commit) {
+    if (ivars->needs_commit) {
         bool success = false;
-        CharBuf *temp_snapfile = CB_Clone(self->snapfile);
+        CharBuf *temp_snapfile = CB_Clone(ivars->snapfile);
 
         // Rename temp snapshot file.
-        CB_Chop(self->snapfile, sizeof(".temp") - 1);
-        success = Folder_Hard_Link(self->folder, temp_snapfile,
-                                   self->snapfile);
-        Snapshot_Set_Path(self->snapshot, self->snapfile);
+        CB_Chop(ivars->snapfile, sizeof(".temp") - 1);
+        success = Folder_Hard_Link(ivars->folder, temp_snapfile,
+                                   ivars->snapfile);
+        Snapshot_Set_Path(ivars->snapshot, ivars->snapfile);
         if (!success) {
             CharBuf *mess = CB_newf("Can't create hard link from %o to %o",
-                                    temp_snapfile, self->snapfile);
+                                    temp_snapfile, ivars->snapfile);
             DECREF(temp_snapfile);
             Err_throw_mess(ERR, mess);
         }
-        if (!Folder_Delete(self->folder, temp_snapfile)) {
+        if (!Folder_Delete(ivars->folder, temp_snapfile)) {
             CharBuf *mess = CB_newf("Can't delete %o", temp_snapfile);
             DECREF(temp_snapfile);
             Err_throw_mess(ERR, mess);
@@ -499,11 +506,11 @@ BGMerger_commit(BackgroundMerger *self) {
 
     // Release the merge lock and remove the merge data file.
     S_release_merge_lock(self);
-    IxManager_Remove_Merge_Data(self->manager);
+    IxManager_Remove_Merge_Data(ivars->manager);
 
-    if (self->needs_commit) {
+    if (ivars->needs_commit) {
         // Purge obsolete files.
-        FilePurger_Purge(self->file_purger);
+        FilePurger_Purge(ivars->file_purger);
     }
 
     // Release the write lock.
@@ -512,11 +519,12 @@ BGMerger_commit(BackgroundMerger *self) {
 
 static void
 S_obtain_write_lock(BackgroundMerger *self) {
-    Lock *write_lock = IxManager_Make_Write_Lock(self->manager);
+    BackgroundMergerIVARS *const ivars = BGMerger_IVARS(self);
+    Lock *write_lock = IxManager_Make_Write_Lock(ivars->manager);
     Lock_Clear_Stale(write_lock);
     if (Lock_Obtain(write_lock)) {
         // Only assign if successful, otherwise DESTROY unlocks -- bad!
-        self->write_lock = write_lock;
+        ivars->write_lock = write_lock;
     }
     else {
         DECREF(write_lock);
@@ -525,11 +533,12 @@ S_obtain_write_lock(BackgroundMerger *self) {
 
 static void
 S_obtain_merge_lock(BackgroundMerger *self) {
-    Lock *merge_lock = IxManager_Make_Merge_Lock(self->manager);
+    BackgroundMergerIVARS *const ivars = BGMerger_IVARS(self);
+    Lock *merge_lock = IxManager_Make_Merge_Lock(ivars->manager);
     Lock_Clear_Stale(merge_lock);
     if (Lock_Obtain(merge_lock)) {
         // Only assign if successful, same rationale as above.
-        self->merge_lock = merge_lock;
+        ivars->merge_lock = merge_lock;
     }
     else {
         // We can't get the merge lock, so it seems there must be another
@@ -540,19 +549,21 @@ S_obtain_merge_lock(BackgroundMerger *self) {
 
 static void
 S_release_write_lock(BackgroundMerger *self) {
-    if (self->write_lock) {
-        Lock_Release(self->write_lock);
-        DECREF(self->write_lock);
-        self->write_lock = NULL;
+    BackgroundMergerIVARS *const ivars = BGMerger_IVARS(self);
+    if (ivars->write_lock) {
+        Lock_Release(ivars->write_lock);
+        DECREF(ivars->write_lock);
+        ivars->write_lock = NULL;
     }
 }
 
 static void
 S_release_merge_lock(BackgroundMerger *self) {
-    if (self->merge_lock) {
-        Lock_Release(self->merge_lock);
-        DECREF(self->merge_lock);
-        self->merge_lock = NULL;
+    BackgroundMergerIVARS *const ivars = BGMerger_IVARS(self);
+    if (ivars->merge_lock) {
+        Lock_Release(ivars->merge_lock);
+        DECREF(ivars->merge_lock);
+        ivars->merge_lock = NULL;
     }
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/BitVecDelDocs.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/BitVecDelDocs.c b/core/Lucy/Index/BitVecDelDocs.c
index 690e6d5..e0dac0e 100644
--- a/core/Lucy/Index/BitVecDelDocs.c
+++ b/core/Lucy/Index/BitVecDelDocs.c
@@ -30,30 +30,30 @@ BitVecDelDocs_new(Folder *folder, const CharBuf *filename) {
 BitVecDelDocs*
 BitVecDelDocs_init(BitVecDelDocs *self, Folder *folder,
                    const CharBuf *filename) {
-    int32_t len;
-
     BitVec_init((BitVector*)self, 0);
-    self->filename = CB_Clone(filename);
-    self->instream = Folder_Open_In(folder, filename);
-    if (!self->instream) {
+    BitVecDelDocsIVARS *const ivars = BitVecDelDocs_IVARS(self);
+    ivars->filename = CB_Clone(filename);
+    ivars->instream = Folder_Open_In(folder, filename);
+    if (!ivars->instream) {
         Err *error = (Err*)INCREF(Err_get_error());
         DECREF(self);
         RETHROW(error);
     }
-    len            = (int32_t)InStream_Length(self->instream);
-    self->bits     = (uint8_t*)InStream_Buf(self->instream, len);
-    self->cap      = (uint32_t)(len * 8);
+    int32_t len    = (int32_t)InStream_Length(ivars->instream);
+    ivars->bits    = (uint8_t*)InStream_Buf(ivars->instream, len);
+    ivars->cap     = (uint32_t)(len * 8);
     return self;
 }
 
 void
 BitVecDelDocs_destroy(BitVecDelDocs *self) {
-    DECREF(self->filename);
-    if (self->instream) {
-        InStream_Close(self->instream);
-        DECREF(self->instream);
+    BitVecDelDocsIVARS *const ivars = BitVecDelDocs_IVARS(self);
+    DECREF(ivars->filename);
+    if (ivars->instream) {
+        InStream_Close(ivars->instream);
+        DECREF(ivars->instream);
     }
-    self->bits = NULL;
+    ivars->bits = NULL;
     SUPER_DESTROY(self, BITVECDELDOCS);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/DataReader.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/DataReader.c b/core/Lucy/Index/DataReader.c
index f8df36f..3404dcf 100644
--- a/core/Lucy/Index/DataReader.c
+++ b/core/Lucy/Index/DataReader.c
@@ -26,11 +26,12 @@
 DataReader*
 DataReader_init(DataReader *self, Schema *schema, Folder *folder,
                 Snapshot *snapshot, VArray *segments, int32_t seg_tick) {
-    self->schema   = (Schema*)INCREF(schema);
-    self->folder   = (Folder*)INCREF(folder);
-    self->snapshot = (Snapshot*)INCREF(snapshot);
-    self->segments = (VArray*)INCREF(segments);
-    self->seg_tick = seg_tick;
+    DataReaderIVARS *const ivars = DataReader_IVARS(self);
+    ivars->schema   = (Schema*)INCREF(schema);
+    ivars->folder   = (Folder*)INCREF(folder);
+    ivars->snapshot = (Snapshot*)INCREF(snapshot);
+    ivars->segments = (VArray*)INCREF(segments);
+    ivars->seg_tick = seg_tick;
     if (seg_tick != -1) {
         if (!segments) {
             THROW(ERR, "No segments array provided, but seg_tick is %i32",
@@ -41,11 +42,11 @@ DataReader_init(DataReader *self, Schema *schema, Folder *folder,
             if (!segment) {
                 THROW(ERR, "No segment at seg_tick %i32", seg_tick);
             }
-            self->segment = (Segment*)INCREF(segment);
+            ivars->segment = (Segment*)INCREF(segment);
         }
     }
     else {
-        self->segment = NULL;
+        ivars->segment = NULL;
     }
 
     ABSTRACT_CLASS_CHECK(self, DATAREADER);
@@ -54,42 +55,43 @@ DataReader_init(DataReader *self, Schema *schema, Folder *folder,
 
 void
 DataReader_destroy(DataReader *self) {
-    DECREF(self->schema);
-    DECREF(self->folder);
-    DECREF(self->snapshot);
-    DECREF(self->segments);
-    DECREF(self->segment);
+    DataReaderIVARS *const ivars = DataReader_IVARS(self);
+    DECREF(ivars->schema);
+    DECREF(ivars->folder);
+    DECREF(ivars->snapshot);
+    DECREF(ivars->segments);
+    DECREF(ivars->segment);
     SUPER_DESTROY(self, DATAREADER);
 }
 
 Schema*
 DataReader_get_schema(DataReader *self) {
-    return self->schema;
+    return DataReader_IVARS(self)->schema;
 }
 
 Folder*
 DataReader_get_folder(DataReader *self) {
-    return self->folder;
+    return DataReader_IVARS(self)->folder;
 }
 
 Snapshot*
 DataReader_get_snapshot(DataReader *self) {
-    return self->snapshot;
+    return DataReader_IVARS(self)->snapshot;
 }
 
 VArray*
 DataReader_get_segments(DataReader *self) {
-    return self->segments;
+    return DataReader_IVARS(self)->segments;
 }
 
 int32_t
 DataReader_get_seg_tick(DataReader *self) {
-    return self->seg_tick;
+    return DataReader_IVARS(self)->seg_tick;
 }
 
 Segment*
 DataReader_get_segment(DataReader *self) {
-    return self->segment;
+    return DataReader_IVARS(self)->segment;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/DataWriter.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/DataWriter.c b/core/Lucy/Index/DataWriter.c
index bddc287..3177ed6 100644
--- a/core/Lucy/Index/DataWriter.c
+++ b/core/Lucy/Index/DataWriter.c
@@ -29,48 +29,50 @@
 DataWriter*
 DataWriter_init(DataWriter *self, Schema *schema, Snapshot *snapshot,
                 Segment *segment, PolyReader *polyreader) {
-    self->snapshot   = (Snapshot*)INCREF(snapshot);
-    self->segment    = (Segment*)INCREF(segment);
-    self->polyreader = (PolyReader*)INCREF(polyreader);
-    self->schema     = (Schema*)INCREF(schema);
-    self->folder     = (Folder*)INCREF(PolyReader_Get_Folder(polyreader));
+    DataWriterIVARS *const ivars = DataWriter_IVARS(self);
+    ivars->snapshot   = (Snapshot*)INCREF(snapshot);
+    ivars->segment    = (Segment*)INCREF(segment);
+    ivars->polyreader = (PolyReader*)INCREF(polyreader);
+    ivars->schema     = (Schema*)INCREF(schema);
+    ivars->folder     = (Folder*)INCREF(PolyReader_Get_Folder(polyreader));
     ABSTRACT_CLASS_CHECK(self, DATAWRITER);
     return self;
 }
 
 void
 DataWriter_destroy(DataWriter *self) {
-    DECREF(self->snapshot);
-    DECREF(self->segment);
-    DECREF(self->polyreader);
-    DECREF(self->schema);
-    DECREF(self->folder);
+    DataWriterIVARS *const ivars = DataWriter_IVARS(self);
+    DECREF(ivars->snapshot);
+    DECREF(ivars->segment);
+    DECREF(ivars->polyreader);
+    DECREF(ivars->schema);
+    DECREF(ivars->folder);
     SUPER_DESTROY(self, DATAWRITER);
 }
 
 Snapshot*
 DataWriter_get_snapshot(DataWriter *self) {
-    return self->snapshot;
+    return DataWriter_IVARS(self)->snapshot;
 }
 
 Segment*
 DataWriter_get_segment(DataWriter *self) {
-    return self->segment;
+    return DataWriter_IVARS(self)->segment;
 }
 
 PolyReader*
 DataWriter_get_polyreader(DataWriter *self) {
-    return self->polyreader;
+    return DataWriter_IVARS(self)->polyreader;
 }
 
 Schema*
 DataWriter_get_schema(DataWriter *self) {
-    return self->schema;
+    return DataWriter_IVARS(self)->schema;
 }
 
 Folder*
 DataWriter_get_folder(DataWriter *self) {
-    return self->folder;
+    return DataWriter_IVARS(self)->folder;
 }
 
 void

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/DeletionsReader.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/DeletionsReader.c b/core/Lucy/Index/DeletionsReader.c
index 391bf63..ef45ebd 100644
--- a/core/Lucy/Index/DeletionsReader.c
+++ b/core/Lucy/Index/DeletionsReader.c
@@ -58,54 +58,58 @@ PolyDeletionsReader*
 PolyDelReader_init(PolyDeletionsReader *self, VArray *readers,
                    I32Array *offsets) {
     DelReader_init((DeletionsReader*)self, NULL, NULL, NULL, NULL, -1);
-    self->del_count = 0;
+    PolyDeletionsReaderIVARS *const ivars = PolyDelReader_IVARS(self);
+    ivars->del_count = 0;
     for (uint32_t i = 0, max = VA_Get_Size(readers); i < max; i++) {
         DeletionsReader *reader = (DeletionsReader*)CERTIFY(
                                       VA_Fetch(readers, i), DELETIONSREADER);
-        self->del_count += DelReader_Del_Count(reader);
+        ivars->del_count += DelReader_Del_Count(reader);
     }
-    self->readers = (VArray*)INCREF(readers);
-    self->offsets = (I32Array*)INCREF(offsets);
+    ivars->readers = (VArray*)INCREF(readers);
+    ivars->offsets = (I32Array*)INCREF(offsets);
     return self;
 }
 
 void
 PolyDelReader_close(PolyDeletionsReader *self) {
-    if (self->readers) {
-        for (uint32_t i = 0, max = VA_Get_Size(self->readers); i < max; i++) {
+    PolyDeletionsReaderIVARS *const ivars = PolyDelReader_IVARS(self);
+    if (ivars->readers) {
+        for (uint32_t i = 0, max = VA_Get_Size(ivars->readers); i < max; i++) {
             DeletionsReader *reader
-                = (DeletionsReader*)VA_Fetch(self->readers, i);
+                = (DeletionsReader*)VA_Fetch(ivars->readers, i);
             if (reader) { DelReader_Close(reader); }
         }
-        VA_Clear(self->readers);
+        VA_Clear(ivars->readers);
     }
 }
 
 void
 PolyDelReader_destroy(PolyDeletionsReader *self) {
-    DECREF(self->readers);
-    DECREF(self->offsets);
+    PolyDeletionsReaderIVARS *const ivars = PolyDelReader_IVARS(self);
+    DECREF(ivars->readers);
+    DECREF(ivars->offsets);
     SUPER_DESTROY(self, POLYDELETIONSREADER);
 }
 
 int32_t
 PolyDelReader_del_count(PolyDeletionsReader *self) {
-    return self->del_count;
+    return PolyDelReader_IVARS(self)->del_count;
 }
 
 Matcher*
 PolyDelReader_iterator(PolyDeletionsReader *self) {
+    PolyDeletionsReaderIVARS *const ivars = PolyDelReader_IVARS(self);
     SeriesMatcher *deletions = NULL;
-    if (self->del_count) {
-        uint32_t num_readers = VA_Get_Size(self->readers);
+    if (ivars->del_count) {
+        uint32_t num_readers = VA_Get_Size(ivars->readers);
         VArray *matchers = VA_new(num_readers);
         for (uint32_t i = 0; i < num_readers; i++) {
             DeletionsReader *reader
-                = (DeletionsReader*)VA_Fetch(self->readers, i);
+                = (DeletionsReader*)VA_Fetch(ivars->readers, i);
             Matcher *matcher = DelReader_Iterator(reader);
             if (matcher) { VA_Store(matchers, i, (Obj*)matcher); }
         }
-        deletions = SeriesMatcher_new(matchers, self->offsets);
+        deletions = SeriesMatcher_new(matchers, ivars->offsets);
         DECREF(matchers);
     }
     return (Matcher*)deletions;
@@ -126,28 +130,32 @@ DefDelReader_init(DefaultDeletionsReader *self, Schema *schema,
                   int32_t seg_tick) {
     DelReader_init((DeletionsReader*)self, schema, folder, snapshot, segments,
                    seg_tick);
+    DefaultDeletionsReaderIVARS *const ivars = DefDelReader_IVARS(self);
     DefDelReader_Read_Deletions(self);
-    if (!self->deldocs) {
-        self->del_count = 0;
-        self->deldocs   = BitVec_new(0);
+    if (!ivars->deldocs) {
+        ivars->del_count = 0;
+        ivars->deldocs   = BitVec_new(0);
     }
     return self;
 }
 
 void
 DefDelReader_close(DefaultDeletionsReader *self) {
-    DECREF(self->deldocs);
-    self->deldocs = NULL;
+    DefaultDeletionsReaderIVARS *const ivars = DefDelReader_IVARS(self);
+    DECREF(ivars->deldocs);
+    ivars->deldocs = NULL;
 }
 
 void
 DefDelReader_destroy(DefaultDeletionsReader *self) {
-    DECREF(self->deldocs);
+    DefaultDeletionsReaderIVARS *const ivars = DefDelReader_IVARS(self);
+    DECREF(ivars->deldocs);
     SUPER_DESTROY(self, DEFAULTDELETIONSREADER);
 }
 
 BitVector*
 DefDelReader_read_deletions(DefaultDeletionsReader *self) {
+    DefaultDeletionsReaderIVARS *const ivars = DefDelReader_IVARS(self);
     VArray  *segments    = DefDelReader_Get_Segments(self);
     Segment *segment     = DefDelReader_Get_Segment(self);
     CharBuf *my_seg_name = Seg_Get_Name(segment);
@@ -179,27 +187,28 @@ DefDelReader_read_deletions(DefaultDeletionsReader *self) {
         }
     }
 
-    DECREF(self->deldocs);
+    DECREF(ivars->deldocs);
     if (del_file) {
-        self->deldocs = (BitVector*)BitVecDelDocs_new(self->folder, del_file);
-        self->del_count = del_count;
+        ivars->deldocs = (BitVector*)BitVecDelDocs_new(ivars->folder, del_file);
+        ivars->del_count = del_count;
     }
     else {
-        self->deldocs = NULL;
-        self->del_count = 0;
+        ivars->deldocs = NULL;
+        ivars->del_count = 0;
     }
 
-    return self->deldocs;
+    return ivars->deldocs;
 }
 
 Matcher*
 DefDelReader_iterator(DefaultDeletionsReader *self) {
-    return (Matcher*)BitVecMatcher_new(self->deldocs);
+    DefaultDeletionsReaderIVARS *const ivars = DefDelReader_IVARS(self);
+    return (Matcher*)BitVecMatcher_new(ivars->deldocs);
 }
 
 int32_t
 DefDelReader_del_count(DefaultDeletionsReader *self) {
-    return self->del_count;
+    return DefDelReader_IVARS(self)->del_count;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/DeletionsWriter.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/DeletionsWriter.c b/core/Lucy/Index/DeletionsWriter.c
index 9dc34d2..759c6de 100644
--- a/core/Lucy/Index/DeletionsWriter.c
+++ b/core/Lucy/Index/DeletionsWriter.c
@@ -82,17 +82,18 @@ DefDelWriter_init(DefaultDeletionsWriter *self, Schema *schema,
                   PolyReader *polyreader) {
 
     DataWriter_init((DataWriter*)self, schema, snapshot, segment, polyreader);
-    self->seg_readers           = PolyReader_Seg_Readers(polyreader);
-    uint32_t num_seg_readers    = VA_Get_Size(self->seg_readers);
-    self->seg_starts            = PolyReader_Offsets(polyreader);
-    self->bit_vecs              = VA_new(num_seg_readers);
-    self->updated               = (bool*)CALLOCATE(num_seg_readers, sizeof(bool));
-    self->searcher              = IxSearcher_new((Obj*)polyreader);
-    self->name_to_tick          = Hash_new(num_seg_readers);
+    DefaultDeletionsWriterIVARS *const ivars = DefDelWriter_IVARS(self);
+    ivars->seg_readers          = PolyReader_Seg_Readers(polyreader);
+    uint32_t num_seg_readers    = VA_Get_Size(ivars->seg_readers);
+    ivars->seg_starts           = PolyReader_Offsets(polyreader);
+    ivars->bit_vecs             = VA_new(num_seg_readers);
+    ivars->updated              = (bool*)CALLOCATE(num_seg_readers, sizeof(bool));
+    ivars->searcher             = IxSearcher_new((Obj*)polyreader);
+    ivars->name_to_tick         = Hash_new(num_seg_readers);
 
     // Materialize a BitVector of deletions for each segment.
     for (uint32_t i = 0; i < num_seg_readers; i++) {
-        SegReader *seg_reader = (SegReader*)VA_Fetch(self->seg_readers, i);
+        SegReader *seg_reader = (SegReader*)VA_Fetch(ivars->seg_readers, i);
         BitVector *bit_vec    = BitVec_new(SegReader_Doc_Max(seg_reader));
         DeletionsReader *del_reader
             = (DeletionsReader*)SegReader_Fetch(
@@ -108,8 +109,8 @@ DefDelWriter_init(DefaultDeletionsWriter *self, Schema *schema,
             }
             DECREF(seg_dels);
         }
-        VA_Store(self->bit_vecs, i, (Obj*)bit_vec);
-        Hash_Store(self->name_to_tick,
+        VA_Store(ivars->bit_vecs, i, (Obj*)bit_vec);
+        Hash_Store(ivars->name_to_tick,
                    (Obj*)SegReader_Get_Seg_Name(seg_reader),
                    (Obj*)Int32_new(i));
     }
@@ -119,30 +120,33 @@ DefDelWriter_init(DefaultDeletionsWriter *self, Schema *schema,
 
 void
 DefDelWriter_destroy(DefaultDeletionsWriter *self) {
-    DECREF(self->seg_readers);
-    DECREF(self->seg_starts);
-    DECREF(self->bit_vecs);
-    DECREF(self->searcher);
-    DECREF(self->name_to_tick);
-    FREEMEM(self->updated);
+    DefaultDeletionsWriterIVARS *const ivars = DefDelWriter_IVARS(self);
+    DECREF(ivars->seg_readers);
+    DECREF(ivars->seg_starts);
+    DECREF(ivars->bit_vecs);
+    DECREF(ivars->searcher);
+    DECREF(ivars->name_to_tick);
+    FREEMEM(ivars->updated);
     SUPER_DESTROY(self, DEFAULTDELETIONSWRITER);
 }
 
 static CharBuf*
 S_del_filename(DefaultDeletionsWriter *self, SegReader *target_reader) {
+    DefaultDeletionsWriterIVARS *const ivars = DefDelWriter_IVARS(self);
     Segment *target_seg = SegReader_Get_Segment(target_reader);
-    return CB_newf("%o/deletions-%o.bv", Seg_Get_Name(self->segment),
+    return CB_newf("%o/deletions-%o.bv", Seg_Get_Name(ivars->segment),
                    Seg_Get_Name(target_seg));
 }
 
 void
 DefDelWriter_finish(DefaultDeletionsWriter *self) {
-    Folder *const folder = self->folder;
+    DefaultDeletionsWriterIVARS *const ivars = DefDelWriter_IVARS(self);
+    Folder *const folder = ivars->folder;
 
-    for (uint32_t i = 0, max = VA_Get_Size(self->seg_readers); i < max; i++) {
-        SegReader *seg_reader = (SegReader*)VA_Fetch(self->seg_readers, i);
-        if (self->updated[i]) {
-            BitVector *deldocs   = (BitVector*)VA_Fetch(self->bit_vecs, i);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->seg_readers); i < max; i++) {
+        SegReader *seg_reader = (SegReader*)VA_Fetch(ivars->seg_readers, i);
+        if (ivars->updated[i]) {
+            BitVector *deldocs   = (BitVector*)VA_Fetch(ivars->bit_vecs, i);
             int32_t    doc_max   = SegReader_Doc_Max(seg_reader);
             double     used      = (doc_max + 1) / 8.0;
             uint32_t   byte_size = (uint32_t)ceil(used);
@@ -164,19 +168,20 @@ DefDelWriter_finish(DefaultDeletionsWriter *self) {
         }
     }
 
-    Seg_Store_Metadata_Str(self->segment, "deletions", 9,
+    Seg_Store_Metadata_Str(ivars->segment, "deletions", 9,
                            (Obj*)DefDelWriter_Metadata(self));
 }
 
 Hash*
 DefDelWriter_metadata(DefaultDeletionsWriter *self) {
+    DefaultDeletionsWriterIVARS *const ivars = DefDelWriter_IVARS(self);
     Hash    *const metadata = DataWriter_metadata((DataWriter*)self);
     Hash    *const files    = Hash_new(0);
 
-    for (uint32_t i = 0, max = VA_Get_Size(self->seg_readers); i < max; i++) {
-        SegReader *seg_reader = (SegReader*)VA_Fetch(self->seg_readers, i);
-        if (self->updated[i]) {
-            BitVector *deldocs   = (BitVector*)VA_Fetch(self->bit_vecs, i);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->seg_readers); i < max; i++) {
+        SegReader *seg_reader = (SegReader*)VA_Fetch(ivars->seg_readers, i);
+        if (ivars->updated[i]) {
+            BitVector *deldocs   = (BitVector*)VA_Fetch(ivars->bit_vecs, i);
             Segment   *segment   = SegReader_Get_Segment(seg_reader);
             Hash      *mini_meta = Hash_new(2);
             Hash_Store_Str(mini_meta, "count", 5,
@@ -200,22 +205,23 @@ DefDelWriter_format(DefaultDeletionsWriter *self) {
 Matcher*
 DefDelWriter_seg_deletions(DefaultDeletionsWriter *self,
                            SegReader *seg_reader) {
+    DefaultDeletionsWriterIVARS *const ivars = DefDelWriter_IVARS(self);
     Matcher *deletions    = NULL;
     Segment *segment      = SegReader_Get_Segment(seg_reader);
     CharBuf *seg_name     = Seg_Get_Name(segment);
-    Integer32 *tick_obj   = (Integer32*)Hash_Fetch(self->name_to_tick,
+    Integer32 *tick_obj   = (Integer32*)Hash_Fetch(ivars->name_to_tick,
                                                    (Obj*)seg_name);
     int32_t tick          = tick_obj ? Int32_Get_Value(tick_obj) : 0;
     SegReader *candidate  = tick_obj
-                            ? (SegReader*)VA_Fetch(self->seg_readers, tick)
+                            ? (SegReader*)VA_Fetch(ivars->seg_readers, tick)
                             : NULL;
 
     if (tick_obj) {
         DeletionsReader *del_reader
             = (DeletionsReader*)SegReader_Obtain(
                   candidate, VTable_Get_Name(DELETIONSREADER));
-        if (self->updated[tick] || DelReader_Del_Count(del_reader)) {
-            BitVector *deldocs = (BitVector*)VA_Fetch(self->bit_vecs, tick);
+        if (ivars->updated[tick] || DelReader_Del_Count(del_reader)) {
+            BitVector *deldocs = (BitVector*)VA_Fetch(ivars->bit_vecs, tick);
             deletions = (Matcher*)BitVecMatcher_new(deldocs);
         }
     }
@@ -229,10 +235,11 @@ DefDelWriter_seg_deletions(DefaultDeletionsWriter *self,
 int32_t
 DefDelWriter_seg_del_count(DefaultDeletionsWriter *self,
                            const CharBuf *seg_name) {
+    DefaultDeletionsWriterIVARS *const ivars = DefDelWriter_IVARS(self);
     Integer32 *tick
-        = (Integer32*)Hash_Fetch(self->name_to_tick, (Obj*)seg_name);
+        = (Integer32*)Hash_Fetch(ivars->name_to_tick, (Obj*)seg_name);
     BitVector *deldocs = tick
-                         ? (BitVector*)VA_Fetch(self->bit_vecs, Int32_Get_Value(tick))
+                         ? (BitVector*)VA_Fetch(ivars->bit_vecs, Int32_Get_Value(tick))
                          : NULL;
     return deldocs ? BitVec_Count(deldocs) : 0;
 }
@@ -240,12 +247,13 @@ DefDelWriter_seg_del_count(DefaultDeletionsWriter *self,
 void
 DefDelWriter_delete_by_term(DefaultDeletionsWriter *self,
                             const CharBuf *field, Obj *term) {
-    for (uint32_t i = 0, max = VA_Get_Size(self->seg_readers); i < max; i++) {
-        SegReader *seg_reader = (SegReader*)VA_Fetch(self->seg_readers, i);
+    DefaultDeletionsWriterIVARS *const ivars = DefDelWriter_IVARS(self);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->seg_readers); i < max; i++) {
+        SegReader *seg_reader = (SegReader*)VA_Fetch(ivars->seg_readers, i);
         PostingListReader *plist_reader
             = (PostingListReader*)SegReader_Fetch(
                   seg_reader, VTable_Get_Name(POSTINGLISTREADER));
-        BitVector *bit_vec = (BitVector*)VA_Fetch(self->bit_vecs, i);
+        BitVector *bit_vec = (BitVector*)VA_Fetch(ivars->bit_vecs, i);
         PostingList *plist = plist_reader
                              ? PListReader_Posting_List(plist_reader, field, term)
                              : NULL;
@@ -258,7 +266,7 @@ DefDelWriter_delete_by_term(DefaultDeletionsWriter *self,
                 num_zapped += !BitVec_Get(bit_vec, doc_id);
                 BitVec_Set(bit_vec, doc_id);
             }
-            if (num_zapped) { self->updated[i] = true; }
+            if (num_zapped) { ivars->updated[i] = true; }
             DECREF(plist);
         }
     }
@@ -266,12 +274,13 @@ DefDelWriter_delete_by_term(DefaultDeletionsWriter *self,
 
 void
 DefDelWriter_delete_by_query(DefaultDeletionsWriter *self, Query *query) {
-    Compiler *compiler = Query_Make_Compiler(query, (Searcher*)self->searcher,
+    DefaultDeletionsWriterIVARS *const ivars = DefDelWriter_IVARS(self);
+    Compiler *compiler = Query_Make_Compiler(query, (Searcher*)ivars->searcher,
                                              Query_Get_Boost(query), false);
 
-    for (uint32_t i = 0, max = VA_Get_Size(self->seg_readers); i < max; i++) {
-        SegReader *seg_reader = (SegReader*)VA_Fetch(self->seg_readers, i);
-        BitVector *bit_vec = (BitVector*)VA_Fetch(self->bit_vecs, i);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->seg_readers); i < max; i++) {
+        SegReader *seg_reader = (SegReader*)VA_Fetch(ivars->seg_readers, i);
+        BitVector *bit_vec = (BitVector*)VA_Fetch(ivars->bit_vecs, i);
         Matcher *matcher = Compiler_Make_Matcher(compiler, seg_reader, false);
 
         if (matcher) {
@@ -283,7 +292,7 @@ DefDelWriter_delete_by_query(DefaultDeletionsWriter *self, Query *query) {
                 num_zapped += !BitVec_Get(bit_vec, doc_id);
                 BitVec_Set(bit_vec, doc_id);
             }
-            if (num_zapped) { self->updated[i] = true; }
+            if (num_zapped) { ivars->updated[i] = true; }
 
             DECREF(matcher);
         }
@@ -294,21 +303,23 @@ DefDelWriter_delete_by_query(DefaultDeletionsWriter *self, Query *query) {
 
 void
 DefDelWriter_delete_by_doc_id(DefaultDeletionsWriter *self, int32_t doc_id) {
-    uint32_t   sub_tick   = PolyReader_sub_tick(self->seg_starts, doc_id);
-    BitVector *bit_vec    = (BitVector*)VA_Fetch(self->bit_vecs, sub_tick);
-    uint32_t   offset     = I32Arr_Get(self->seg_starts, sub_tick);
+    DefaultDeletionsWriterIVARS *const ivars = DefDelWriter_IVARS(self);
+    uint32_t   sub_tick   = PolyReader_sub_tick(ivars->seg_starts, doc_id);
+    BitVector *bit_vec    = (BitVector*)VA_Fetch(ivars->bit_vecs, sub_tick);
+    uint32_t   offset     = I32Arr_Get(ivars->seg_starts, sub_tick);
     int32_t    seg_doc_id = doc_id - offset;
 
     if (!BitVec_Get(bit_vec, seg_doc_id)) {
-        self->updated[sub_tick] = true;
+        ivars->updated[sub_tick] = true;
         BitVec_Set(bit_vec, seg_doc_id);
     }
 }
 
 bool
 DefDelWriter_updated(DefaultDeletionsWriter *self) {
-    for (uint32_t i = 0, max = VA_Get_Size(self->seg_readers); i < max; i++) {
-        if (self->updated[i]) { return true; }
+    DefaultDeletionsWriterIVARS *const ivars = DefDelWriter_IVARS(self);
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->seg_readers); i < max; i++) {
+        if (ivars->updated[i]) { return true; }
     }
     return false;
 }
@@ -327,12 +338,13 @@ DefDelWriter_add_segment(DefaultDeletionsWriter *self, SegReader *reader,
 void
 DefDelWriter_merge_segment(DefaultDeletionsWriter *self, SegReader *reader,
                            I32Array *doc_map) {
+    DefaultDeletionsWriterIVARS *const ivars = DefDelWriter_IVARS(self);
     UNUSED_VAR(doc_map);
     Segment *segment = SegReader_Get_Segment(reader);
     Hash *del_meta = (Hash*)Seg_Fetch_Metadata_Str(segment, "deletions", 9);
 
     if (del_meta) {
-        VArray *seg_readers = self->seg_readers;
+        VArray *seg_readers = ivars->seg_readers;
         Hash   *files = (Hash*)Hash_Fetch_Str(del_meta, "files", 5);
         if (files) {
             CharBuf *seg;
@@ -360,7 +372,7 @@ DefDelWriter_merge_segment(DefaultDeletionsWriter *self, SegReader *reader,
                             = (DeletionsReader*)SegReader_Obtain(
                                   candidate, VTable_Get_Name(DELETIONSREADER));
                         if (count == DelReader_Del_Count(del_reader)) {
-                            self->updated[i] = true;
+                            ivars->updated[i] = true;
                         }
                         break;
                     }

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/DocReader.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/DocReader.c b/core/Lucy/Index/DocReader.c
index 934969b..24c8052 100644
--- a/core/Lucy/Index/DocReader.c
+++ b/core/Lucy/Index/DocReader.c
@@ -51,37 +51,41 @@ PolyDocReader_new(VArray *readers, I32Array *offsets) {
 PolyDocReader*
 PolyDocReader_init(PolyDocReader *self, VArray *readers, I32Array *offsets) {
     DocReader_init((DocReader*)self, NULL, NULL, NULL, NULL, -1);
+    PolyDocReaderIVARS *const ivars = PolyDocReader_IVARS(self);
     for (uint32_t i = 0, max = VA_Get_Size(readers); i < max; i++) {
         CERTIFY(VA_Fetch(readers, i), DOCREADER);
     }
-    self->readers = (VArray*)INCREF(readers);
-    self->offsets = (I32Array*)INCREF(offsets);
+    ivars->readers = (VArray*)INCREF(readers);
+    ivars->offsets = (I32Array*)INCREF(offsets);
     return self;
 }
 
 void
 PolyDocReader_close(PolyDocReader *self) {
-    if (self->readers) {
-        for (uint32_t i = 0, max = VA_Get_Size(self->readers); i < max; i++) {
-            DocReader *reader = (DocReader*)VA_Fetch(self->readers, i);
+    PolyDocReaderIVARS *const ivars = PolyDocReader_IVARS(self);
+    if (ivars->readers) {
+        for (uint32_t i = 0, max = VA_Get_Size(ivars->readers); i < max; i++) {
+            DocReader *reader = (DocReader*)VA_Fetch(ivars->readers, i);
             if (reader) { DocReader_Close(reader); }
         }
-        VA_Clear(self->readers);
+        VA_Clear(ivars->readers);
     }
 }
 
 void
 PolyDocReader_destroy(PolyDocReader *self) {
-    DECREF(self->readers);
-    DECREF(self->offsets);
+    PolyDocReaderIVARS *const ivars = PolyDocReader_IVARS(self);
+    DECREF(ivars->readers);
+    DECREF(ivars->offsets);
     SUPER_DESTROY(self, POLYDOCREADER);
 }
 
 HitDoc*
 PolyDocReader_fetch_doc(PolyDocReader *self, int32_t doc_id) {
-    uint32_t seg_tick = PolyReader_sub_tick(self->offsets, doc_id);
-    int32_t  offset   = I32Arr_Get(self->offsets, seg_tick);
-    DocReader *doc_reader = (DocReader*)VA_Fetch(self->readers, seg_tick);
+    PolyDocReaderIVARS *const ivars = PolyDocReader_IVARS(self);
+    uint32_t seg_tick = PolyReader_sub_tick(ivars->offsets, doc_id);
+    int32_t  offset   = I32Arr_Get(ivars->offsets, seg_tick);
+    DocReader *doc_reader = (DocReader*)VA_Fetch(ivars->readers, seg_tick);
     HitDoc *hit_doc = NULL;
     if (!doc_reader) {
         THROW(ERR, "Invalid doc_id: %i32", doc_id);
@@ -104,22 +108,24 @@ DefDocReader_new(Schema *schema, Folder *folder, Snapshot *snapshot,
 
 void
 DefDocReader_close(DefaultDocReader *self) {
-    if (self->dat_in != NULL) {
-        InStream_Close(self->dat_in);
-        DECREF(self->dat_in);
-        self->dat_in = NULL;
+    DefaultDocReaderIVARS *const ivars = DefDocReader_IVARS(self);
+    if (ivars->dat_in != NULL) {
+        InStream_Close(ivars->dat_in);
+        DECREF(ivars->dat_in);
+        ivars->dat_in = NULL;
     }
-    if (self->ix_in != NULL) {
-        InStream_Close(self->ix_in);
-        DECREF(self->ix_in);
-        self->ix_in = NULL;
+    if (ivars->ix_in != NULL) {
+        InStream_Close(ivars->ix_in);
+        DECREF(ivars->ix_in);
+        ivars->ix_in = NULL;
     }
 }
 
 void
 DefDocReader_destroy(DefaultDocReader *self) {
-    DECREF(self->ix_in);
-    DECREF(self->dat_in);
+    DefaultDocReaderIVARS *const ivars = DefDocReader_IVARS(self);
+    DECREF(ivars->ix_in);
+    DECREF(ivars->dat_in);
     SUPER_DESTROY(self, DEFAULTDOCREADER);
 }
 
@@ -130,6 +136,7 @@ DefDocReader_init(DefaultDocReader *self, Schema *schema, Folder *folder,
     Segment *segment;
     DocReader_init((DocReader*)self, schema, folder, snapshot, segments,
                    seg_tick);
+    DefaultDocReaderIVARS *const ivars = DefDocReader_IVARS(self);
     segment = DefDocReader_Get_Segment(self);
     metadata = (Hash*)Seg_Fetch_Metadata_Str(segment, "documents", 9);
 
@@ -154,16 +161,16 @@ DefDocReader_init(DefaultDocReader *self, Schema *schema, Folder *folder,
 
         // Get streams.
         if (Folder_Exists(folder, ix_file)) {
-            self->ix_in = Folder_Open_In(folder, ix_file);
-            if (!self->ix_in) {
+            ivars->ix_in = Folder_Open_In(folder, ix_file);
+            if (!ivars->ix_in) {
                 Err *error = (Err*)INCREF(Err_get_error());
                 DECREF(ix_file);
                 DECREF(dat_file);
                 DECREF(self);
                 RETHROW(error);
             }
-            self->dat_in = Folder_Open_In(folder, dat_file);
-            if (!self->dat_in) {
+            ivars->dat_in = Folder_Open_In(folder, dat_file);
+            if (!ivars->dat_in) {
                 Err *error = (Err*)INCREF(Err_get_error());
                 DECREF(ix_file);
                 DECREF(dat_file);
@@ -181,16 +188,18 @@ DefDocReader_init(DefaultDocReader *self, Schema *schema, Folder *folder,
 void
 DefDocReader_read_record(DefaultDocReader *self, ByteBuf *buffer,
                          int32_t doc_id) {
+    DefaultDocReaderIVARS *const ivars = DefDocReader_IVARS(self);
+
     // Find start and length of variable length record.
-    InStream_Seek(self->ix_in, (int64_t)doc_id * 8);
-    int64_t start = InStream_Read_I64(self->ix_in);
-    int64_t end   = InStream_Read_I64(self->ix_in);
+    InStream_Seek(ivars->ix_in, (int64_t)doc_id * 8);
+    int64_t start = InStream_Read_I64(ivars->ix_in);
+    int64_t end   = InStream_Read_I64(ivars->ix_in);
     size_t size  = (size_t)(end - start);
 
     // Read in the record.
     char *buf = BB_Grow(buffer, size);
-    InStream_Seek(self->dat_in, start);
-    InStream_Read_Bytes(self->dat_in, buf, size);
+    InStream_Seek(ivars->dat_in, start);
+    InStream_Read_Bytes(ivars->dat_in, buf, size);
     BB_Set_Size(buffer, size);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/DocVector.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/DocVector.c b/core/Lucy/Index/DocVector.c
index 609c43b..131aaf4 100644
--- a/core/Lucy/Index/DocVector.c
+++ b/core/Lucy/Index/DocVector.c
@@ -41,62 +41,70 @@ DocVec_new() {
 
 DocVector*
 DocVec_init(DocVector *self) {
-    self->field_bufs    = Hash_new(0);
-    self->field_vectors = Hash_new(0);
+    DocVectorIVARS *const ivars = DocVec_IVARS(self);
+    ivars->field_bufs    = Hash_new(0);
+    ivars->field_vectors = Hash_new(0);
     return self;
 }
 
 void
 DocVec_serialize(DocVector *self, OutStream *outstream) {
-    Freezer_serialize_hash(self->field_bufs, outstream);
-    Freezer_serialize_hash(self->field_vectors, outstream);
+    DocVectorIVARS *const ivars = DocVec_IVARS(self);
+    Freezer_serialize_hash(ivars->field_bufs, outstream);
+    Freezer_serialize_hash(ivars->field_vectors, outstream);
 }
 
 DocVector*
 DocVec_deserialize(DocVector *self, InStream *instream) {
-    self->field_bufs    = Freezer_read_hash(instream);
-    self->field_vectors = Freezer_read_hash(instream);
+    DocVectorIVARS *const ivars = DocVec_IVARS(self);
+    ivars->field_bufs    = Freezer_read_hash(instream);
+    ivars->field_vectors = Freezer_read_hash(instream);
     return self;
 }
 
 void
 DocVec_destroy(DocVector *self) {
-    DECREF(self->field_bufs);
-    DECREF(self->field_vectors);
+    DocVectorIVARS *const ivars = DocVec_IVARS(self);
+    DECREF(ivars->field_bufs);
+    DECREF(ivars->field_vectors);
     SUPER_DESTROY(self, DOCVECTOR);
 }
 
 void
 DocVec_add_field_buf(DocVector *self, const CharBuf *field,
                      ByteBuf *field_buf) {
-    Hash_Store(self->field_bufs, (Obj*)field, INCREF(field_buf));
+    DocVectorIVARS *const ivars = DocVec_IVARS(self);
+    Hash_Store(ivars->field_bufs, (Obj*)field, INCREF(field_buf));
 }
 
 ByteBuf*
 DocVec_field_buf(DocVector *self, const CharBuf *field) {
-    return (ByteBuf*)Hash_Fetch(self->field_bufs, (Obj*)field);
+    DocVectorIVARS *const ivars = DocVec_IVARS(self);
+    return (ByteBuf*)Hash_Fetch(ivars->field_bufs, (Obj*)field);
 }
 
 VArray*
 DocVec_field_names(DocVector *self) {
-    return Hash_Keys(self->field_bufs);
+    DocVectorIVARS *const ivars = DocVec_IVARS(self);
+    return Hash_Keys(ivars->field_bufs);
 }
 
 TermVector*
 DocVec_term_vector(DocVector *self, const CharBuf *field,
                    const CharBuf *term_text) {
-    Hash *field_vector = (Hash*)Hash_Fetch(self->field_vectors, (Obj*)field);
+    DocVectorIVARS *const ivars = DocVec_IVARS(self);
+    Hash *field_vector = (Hash*)Hash_Fetch(ivars->field_vectors, (Obj*)field);
 
     // If no cache hit, try to fill cache.
     if (field_vector == NULL) {
         ByteBuf *field_buf
-            = (ByteBuf*)Hash_Fetch(self->field_bufs, (Obj*)field);
+            = (ByteBuf*)Hash_Fetch(ivars->field_bufs, (Obj*)field);
 
         // Bail if there's no content or the field isn't highlightable.
         if (field_buf == NULL) { return NULL; }
 
         field_vector = S_extract_tv_cache(field_buf);
-        Hash_Store(self->field_vectors, (Obj*)field, (Obj*)field_vector);
+        Hash_Store(ivars->field_vectors, (Obj*)field, (Obj*)field_vector);
     }
 
     // Get a buf for the term text or bail.

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/DocWriter.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/DocWriter.c b/core/Lucy/Index/DocWriter.c
index 06355f0..0299de2 100644
--- a/core/Lucy/Index/DocWriter.c
+++ b/core/Lucy/Index/DocWriter.c
@@ -52,39 +52,42 @@ DocWriter_init(DocWriter *self, Schema *schema, Snapshot *snapshot,
 
 void
 DocWriter_destroy(DocWriter *self) {
-    DECREF(self->dat_out);
-    DECREF(self->ix_out);
+    DocWriterIVARS *const ivars = DocWriter_IVARS(self);
+    DECREF(ivars->dat_out);
+    DECREF(ivars->ix_out);
     SUPER_DESTROY(self, DOCWRITER);
 }
 
 static OutStream*
 S_lazy_init(DocWriter *self) {
-    if (!self->dat_out) {
-        Folder  *folder   = self->folder;
-        CharBuf *seg_name = Seg_Get_Name(self->segment);
+    DocWriterIVARS *const ivars = DocWriter_IVARS(self);
+    if (!ivars->dat_out) {
+        Folder  *folder   = ivars->folder;
+        CharBuf *seg_name = Seg_Get_Name(ivars->segment);
 
         // Get streams.
         CharBuf *ix_file = CB_newf("%o/documents.ix", seg_name);
-        self->ix_out = Folder_Open_Out(folder, ix_file);
+        ivars->ix_out = Folder_Open_Out(folder, ix_file);
         DECREF(ix_file);
-        if (!self->ix_out) { RETHROW(INCREF(Err_get_error())); }
+        if (!ivars->ix_out) { RETHROW(INCREF(Err_get_error())); }
         CharBuf *dat_file = CB_newf("%o/documents.dat", seg_name);
-        self->dat_out = Folder_Open_Out(folder, dat_file);
+        ivars->dat_out = Folder_Open_Out(folder, dat_file);
         DECREF(dat_file);
-        if (!self->dat_out) { RETHROW(INCREF(Err_get_error())); }
+        if (!ivars->dat_out) { RETHROW(INCREF(Err_get_error())); }
 
         // Go past non-doc #0.
-        OutStream_Write_I64(self->ix_out, 0);
+        OutStream_Write_I64(ivars->ix_out, 0);
     }
 
-    return self->dat_out;
+    return ivars->dat_out;
 }
 
 void
 DocWriter_add_inverted_doc(DocWriter *self, Inverter *inverter,
                            int32_t doc_id) {
+    DocWriterIVARS *const ivars = DocWriter_IVARS(self);
     OutStream *dat_out    = S_lazy_init(self);
-    OutStream *ix_out     = self->ix_out;
+    OutStream *ix_out     = ivars->ix_out;
     uint32_t   num_stored = 0;
     int64_t    start      = OutStream_Tell(dat_out);
     int64_t    expected   = OutStream_Tell(ix_out) / 8;
@@ -158,6 +161,7 @@ DocWriter_add_inverted_doc(DocWriter *self, Inverter *inverter,
 void
 DocWriter_add_segment(DocWriter *self, SegReader *reader,
                       I32Array *doc_map) {
+    DocWriterIVARS *const ivars = DocWriter_IVARS(self);
     int32_t doc_max = SegReader_Doc_Max(reader);
 
     if (doc_max == 0) {
@@ -166,7 +170,7 @@ DocWriter_add_segment(DocWriter *self, SegReader *reader,
     }
     else {
         OutStream *const dat_out = S_lazy_init(self);
-        OutStream *const ix_out  = self->ix_out;
+        OutStream *const ix_out  = ivars->ix_out;
         ByteBuf   *const buffer  = BB_new(0);
         DefaultDocReader *const doc_reader
             = (DefaultDocReader*)CERTIFY(
@@ -194,16 +198,17 @@ DocWriter_add_segment(DocWriter *self, SegReader *reader,
 
 void
 DocWriter_finish(DocWriter *self) {
-    if (self->dat_out) {
+    DocWriterIVARS *const ivars = DocWriter_IVARS(self);
+    if (ivars->dat_out) {
         // Write one final file pointer, so that we can derive the length of
         // the last record.
-        int64_t end = OutStream_Tell(self->dat_out);
-        OutStream_Write_I64(self->ix_out, end);
+        int64_t end = OutStream_Tell(ivars->dat_out);
+        OutStream_Write_I64(ivars->ix_out, end);
 
         // Close down output streams.
-        OutStream_Close(self->dat_out);
-        OutStream_Close(self->ix_out);
-        Seg_Store_Metadata_Str(self->segment, "documents", 9,
+        OutStream_Close(ivars->dat_out);
+        OutStream_Close(ivars->ix_out);
+        Seg_Store_Metadata_Str(ivars->segment, "documents", 9,
                                (Obj*)DocWriter_Metadata(self));
     }
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/FilePurger.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/FilePurger.c b/core/Lucy/Index/FilePurger.c
index 70e2ef8..35283ee 100644
--- a/core/Lucy/Index/FilePurger.c
+++ b/core/Lucy/Index/FilePurger.c
@@ -50,37 +50,40 @@ FilePurger_new(Folder *folder, Snapshot *snapshot, IndexManager *manager) {
 FilePurger*
 FilePurger_init(FilePurger *self, Folder *folder, Snapshot *snapshot,
                 IndexManager *manager) {
-    self->folder       = (Folder*)INCREF(folder);
-    self->snapshot     = (Snapshot*)INCREF(snapshot);
-    self->manager      = manager
+    FilePurgerIVARS *const ivars = FilePurger_IVARS(self);
+    ivars->folder       = (Folder*)INCREF(folder);
+    ivars->snapshot     = (Snapshot*)INCREF(snapshot);
+    ivars->manager      = manager
                          ? (IndexManager*)INCREF(manager)
                          : IxManager_new(NULL, NULL);
-    IxManager_Set_Folder(self->manager, folder);
+    IxManager_Set_Folder(ivars->manager, folder);
 
     // Don't allow the locks directory to be zapped.
-    self->disallowed = Hash_new(0);
-    Hash_Store_Str(self->disallowed, "locks", 5, (Obj*)CFISH_TRUE);
+    ivars->disallowed = Hash_new(0);
+    Hash_Store_Str(ivars->disallowed, "locks", 5, (Obj*)CFISH_TRUE);
 
     return self;
 }
 
 void
 FilePurger_destroy(FilePurger *self) {
-    DECREF(self->folder);
-    DECREF(self->snapshot);
-    DECREF(self->manager);
-    DECREF(self->disallowed);
+    FilePurgerIVARS *const ivars = FilePurger_IVARS(self);
+    DECREF(ivars->folder);
+    DECREF(ivars->snapshot);
+    DECREF(ivars->manager);
+    DECREF(ivars->disallowed);
     SUPER_DESTROY(self, FILEPURGER);
 }
 
 void
 FilePurger_purge(FilePurger *self) {
-    Lock *deletion_lock = IxManager_Make_Deletion_Lock(self->manager);
+    FilePurgerIVARS *const ivars = FilePurger_IVARS(self);
+    Lock *deletion_lock = IxManager_Make_Deletion_Lock(ivars->manager);
 
     // Obtain deletion lock, purge files, release deletion lock.
     Lock_Clear_Stale(deletion_lock);
     if (Lock_Obtain(deletion_lock)) {
-        Folder *folder   = self->folder;
+        Folder *folder   = ivars->folder;
         Hash   *failures = Hash_new(0);
         VArray *purgables;
         VArray *snapshots;
@@ -93,7 +96,7 @@ FilePurger_purge(FilePurger *self) {
         VA_Sort(purgables, NULL, NULL);
         for (uint32_t i = VA_Get_Size(purgables); i--;) {
             CharBuf *entry = (CharBuf*)VA_Fetch(purgables, i);
-            if (Hash_Fetch(self->disallowed, (Obj*)entry)) { continue; }
+            if (Hash_Fetch(ivars->disallowed, (Obj*)entry)) { continue; }
             if (!Folder_Delete(folder, entry)) {
                 if (Folder_Exists(folder, entry)) {
                     Hash_Store(failures, (Obj*)entry, (Obj*)CFISH_TRUE);
@@ -138,7 +141,8 @@ FilePurger_purge(FilePurger *self) {
 
 static void
 S_zap_dead_merge(FilePurger *self, Hash *candidates) {
-    IndexManager *manager    = self->manager;
+    FilePurgerIVARS *const ivars = FilePurger_IVARS(self);
+    IndexManager *manager    = ivars->manager;
     Lock         *merge_lock = IxManager_Make_Merge_Lock(manager);
 
     Lock_Clear_Stale(merge_lock);
@@ -150,9 +154,9 @@ S_zap_dead_merge(FilePurger *self, Hash *candidates) {
 
         if (cutoff) {
             CharBuf *cutoff_seg = Seg_num_to_name(Obj_To_I64(cutoff));
-            if (Folder_Exists(self->folder, cutoff_seg)) {
+            if (Folder_Exists(ivars->folder, cutoff_seg)) {
                 ZombieCharBuf *merge_json = ZCB_WRAP_STR("merge.json", 10);
-                DirHandle *dh = Folder_Open_Dir(self->folder, cutoff_seg);
+                DirHandle *dh = Folder_Open_Dir(ivars->folder, cutoff_seg);
                 CharBuf *entry = dh ? DH_Get_Entry(dh) : NULL;
                 CharBuf *filepath = CB_new(32);
 
@@ -183,7 +187,8 @@ S_zap_dead_merge(FilePurger *self, Hash *candidates) {
 static void
 S_discover_unused(FilePurger *self, VArray **purgables_ptr,
                   VArray **snapshots_ptr) {
-    Folder      *folder       = self->folder;
+    FilePurgerIVARS *const ivars = FilePurger_IVARS(self);
+    Folder      *folder       = ivars->folder;
     DirHandle   *dh           = Folder_Open_Dir(folder, NULL);
     if (!dh) { RETHROW(INCREF(Err_get_error())); }
     VArray      *spared       = VA_new(1);
@@ -191,13 +196,13 @@ S_discover_unused(FilePurger *self, VArray **purgables_ptr,
     CharBuf     *snapfile     = NULL;
 
     // Start off with the list of files in the current snapshot.
-    if (self->snapshot) {
-        VArray *entries    = Snapshot_List(self->snapshot);
+    if (ivars->snapshot) {
+        VArray *entries    = Snapshot_List(ivars->snapshot);
         VArray *referenced = S_find_all_referenced(folder, entries);
         VA_Push_VArray(spared, referenced);
         DECREF(entries);
         DECREF(referenced);
-        snapfile = Snapshot_Get_Path(self->snapshot);
+        snapfile = Snapshot_Get_Path(ivars->snapshot);
         if (snapfile) { VA_Push(spared, INCREF(snapfile)); }
     }
 
@@ -211,7 +216,7 @@ S_discover_unused(FilePurger *self, VArray **purgables_ptr,
             Snapshot *snapshot
                 = Snapshot_Read_File(Snapshot_new(), folder, entry);
             Lock *lock
-                = IxManager_Make_Snapshot_Read_Lock(self->manager, entry);
+                = IxManager_Make_Snapshot_Read_Lock(ivars->manager, entry);
             VArray *snap_list  = Snapshot_List(snapshot);
             VArray *referenced = S_find_all_referenced(folder, snap_list);
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/HighlightReader.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/HighlightReader.c b/core/Lucy/Index/HighlightReader.c
index 8f4b1d6..655a5e4 100644
--- a/core/Lucy/Index/HighlightReader.c
+++ b/core/Lucy/Index/HighlightReader.c
@@ -58,42 +58,46 @@ PolyHighlightReader*
 PolyHLReader_init(PolyHighlightReader *self, VArray *readers,
                   I32Array *offsets) {
     HLReader_init((HighlightReader*)self, NULL, NULL, NULL, NULL, -1);
+    PolyHighlightReaderIVARS *const ivars = PolyHLReader_IVARS(self);
     for (uint32_t i = 0, max = VA_Get_Size(readers); i < max; i++) {
         CERTIFY(VA_Fetch(readers, i), HIGHLIGHTREADER);
     }
-    self->readers = (VArray*)INCREF(readers);
-    self->offsets = (I32Array*)INCREF(offsets);
+    ivars->readers = (VArray*)INCREF(readers);
+    ivars->offsets = (I32Array*)INCREF(offsets);
     return self;
 }
 
 void
 PolyHLReader_close(PolyHighlightReader *self) {
-    if (self->readers) {
-        for (uint32_t i = 0, max = VA_Get_Size(self->readers); i < max; i++) {
+    PolyHighlightReaderIVARS *const ivars = PolyHLReader_IVARS(self);
+    if (ivars->readers) {
+        for (uint32_t i = 0, max = VA_Get_Size(ivars->readers); i < max; i++) {
             HighlightReader *sub_reader
-                = (HighlightReader*)VA_Fetch(self->readers, i);
+                = (HighlightReader*)VA_Fetch(ivars->readers, i);
             if (sub_reader) { HLReader_Close(sub_reader); }
         }
-        DECREF(self->readers);
-        DECREF(self->offsets);
-        self->readers = NULL;
-        self->offsets = NULL;
+        DECREF(ivars->readers);
+        DECREF(ivars->offsets);
+        ivars->readers = NULL;
+        ivars->offsets = NULL;
     }
 }
 
 void
 PolyHLReader_destroy(PolyHighlightReader *self) {
-    DECREF(self->readers);
-    DECREF(self->offsets);
+    PolyHighlightReaderIVARS *const ivars = PolyHLReader_IVARS(self);
+    DECREF(ivars->readers);
+    DECREF(ivars->offsets);
     SUPER_DESTROY(self, POLYHIGHLIGHTREADER);
 }
 
 DocVector*
 PolyHLReader_fetch_doc_vec(PolyHighlightReader *self, int32_t doc_id) {
-    uint32_t seg_tick = PolyReader_sub_tick(self->offsets, doc_id);
-    int32_t  offset   = I32Arr_Get(self->offsets, seg_tick);
+    PolyHighlightReaderIVARS *const ivars = PolyHLReader_IVARS(self);
+    uint32_t seg_tick = PolyReader_sub_tick(ivars->offsets, doc_id);
+    int32_t  offset   = I32Arr_Get(ivars->offsets, seg_tick);
     HighlightReader *sub_reader
-        = (HighlightReader*)VA_Fetch(self->readers, seg_tick);
+        = (HighlightReader*)VA_Fetch(ivars->readers, seg_tick);
     if (!sub_reader) { THROW(ERR, "Invalid doc_id: %i32", doc_id); }
     return HLReader_Fetch_Doc_Vec(sub_reader, doc_id - offset);
 }
@@ -113,6 +117,7 @@ DefHLReader_init(DefaultHighlightReader *self, Schema *schema,
                  int32_t seg_tick) {
     HLReader_init((HighlightReader*)self, schema, folder, snapshot,
                   segments, seg_tick);
+    DefaultHighlightReaderIVARS *const ivars = DefHLReader_IVARS(self);
     Segment *segment    = DefHLReader_Get_Segment(self);
     Hash *metadata      = (Hash*)Seg_Fetch_Metadata_Str(segment, "highlight", 9);
     if (!metadata) {
@@ -136,16 +141,16 @@ DefHLReader_init(DefaultHighlightReader *self, Schema *schema,
     CharBuf *ix_file  = CB_newf("%o/highlight.ix", seg_name);
     CharBuf *dat_file = CB_newf("%o/highlight.dat", seg_name);
     if (Folder_Exists(folder, ix_file)) {
-        self->ix_in = Folder_Open_In(folder, ix_file);
-        if (!self->ix_in) {
+        ivars->ix_in = Folder_Open_In(folder, ix_file);
+        if (!ivars->ix_in) {
             Err *error = (Err*)INCREF(Err_get_error());
             DECREF(ix_file);
             DECREF(dat_file);
             DECREF(self);
             RETHROW(error);
         }
-        self->dat_in = Folder_Open_In(folder, dat_file);
-        if (!self->dat_in) {
+        ivars->dat_in = Folder_Open_In(folder, dat_file);
+        if (!ivars->dat_in) {
             Err *error = (Err*)INCREF(Err_get_error());
             DECREF(ix_file);
             DECREF(dat_file);
@@ -161,29 +166,32 @@ DefHLReader_init(DefaultHighlightReader *self, Schema *schema,
 
 void
 DefHLReader_close(DefaultHighlightReader *self) {
-    if (self->dat_in != NULL) {
-        InStream_Close(self->dat_in);
-        DECREF(self->dat_in);
-        self->dat_in = NULL;
+    DefaultHighlightReaderIVARS *const ivars = DefHLReader_IVARS(self);
+    if (ivars->dat_in != NULL) {
+        InStream_Close(ivars->dat_in);
+        DECREF(ivars->dat_in);
+        ivars->dat_in = NULL;
     }
-    if (self->ix_in != NULL) {
-        InStream_Close(self->ix_in);
-        DECREF(self->ix_in);
-        self->ix_in = NULL;
+    if (ivars->ix_in != NULL) {
+        InStream_Close(ivars->ix_in);
+        DECREF(ivars->ix_in);
+        ivars->ix_in = NULL;
     }
 }
 
 void
 DefHLReader_destroy(DefaultHighlightReader *self) {
-    DECREF(self->ix_in);
-    DECREF(self->dat_in);
+    DefaultHighlightReaderIVARS *const ivars = DefHLReader_IVARS(self);
+    DECREF(ivars->ix_in);
+    DECREF(ivars->dat_in);
     SUPER_DESTROY(self, DEFAULTHIGHLIGHTREADER);
 }
 
 DocVector*
 DefHLReader_fetch_doc_vec(DefaultHighlightReader *self, int32_t doc_id) {
-    InStream *const ix_in  = self->ix_in;
-    InStream *const dat_in = self->dat_in;
+    DefaultHighlightReaderIVARS *const ivars = DefHLReader_IVARS(self);
+    InStream *const ix_in  = ivars->ix_in;
+    InStream *const dat_in = ivars->dat_in;
     DocVector *doc_vec = DocVec_new();
 
     InStream_Seek(ix_in, doc_id * 8);
@@ -205,8 +213,9 @@ DefHLReader_fetch_doc_vec(DefaultHighlightReader *self, int32_t doc_id) {
 void
 DefHLReader_read_record(DefaultHighlightReader *self, int32_t doc_id,
                         ByteBuf *target) {
-    InStream *dat_in = self->dat_in;
-    InStream *ix_in  = self->ix_in;
+    DefaultHighlightReaderIVARS *const ivars = DefHLReader_IVARS(self);
+    InStream *dat_in = ivars->dat_in;
+    InStream *ix_in  = ivars->ix_in;
 
     InStream_Seek(ix_in, doc_id * 8);
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/HighlightWriter.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/HighlightWriter.c b/core/Lucy/Index/HighlightWriter.c
index 175e165..d1ce83a 100644
--- a/core/Lucy/Index/HighlightWriter.c
+++ b/core/Lucy/Index/HighlightWriter.c
@@ -60,41 +60,44 @@ HLWriter_init(HighlightWriter *self, Schema *schema, Snapshot *snapshot,
 
 void
 HLWriter_destroy(HighlightWriter *self) {
-    DECREF(self->dat_out);
-    DECREF(self->ix_out);
+    HighlightWriterIVARS *const ivars = HLWriter_IVARS(self);
+    DECREF(ivars->dat_out);
+    DECREF(ivars->ix_out);
     SUPER_DESTROY(self, HIGHLIGHTWRITER);
 }
 
 static OutStream*
 S_lazy_init(HighlightWriter *self) {
-    if (!self->dat_out) {
-        Segment  *segment  = self->segment;
-        Folder   *folder   = self->folder;
+    HighlightWriterIVARS *const ivars = HLWriter_IVARS(self);
+    if (!ivars->dat_out) {
+        Segment  *segment  = ivars->segment;
+        Folder   *folder   = ivars->folder;
         CharBuf  *seg_name = Seg_Get_Name(segment);
 
         // Open outstreams.
         CharBuf *ix_file = CB_newf("%o/highlight.ix", seg_name);
-        self->ix_out = Folder_Open_Out(folder, ix_file);
+        ivars->ix_out = Folder_Open_Out(folder, ix_file);
         DECREF(ix_file);
-        if (!self->ix_out) { RETHROW(INCREF(Err_get_error())); }
+        if (!ivars->ix_out) { RETHROW(INCREF(Err_get_error())); }
 
         CharBuf *dat_file = CB_newf("%o/highlight.dat", seg_name);
-        self->dat_out = Folder_Open_Out(folder, dat_file);
+        ivars->dat_out = Folder_Open_Out(folder, dat_file);
         DECREF(dat_file);
-        if (!self->dat_out) { RETHROW(INCREF(Err_get_error())); }
+        if (!ivars->dat_out) { RETHROW(INCREF(Err_get_error())); }
 
         // Go past invalid doc 0.
-        OutStream_Write_I64(self->ix_out, 0);
+        OutStream_Write_I64(ivars->ix_out, 0);
     }
 
-    return self->dat_out;
+    return ivars->dat_out;
 }
 
 void
 HLWriter_add_inverted_doc(HighlightWriter *self, Inverter *inverter,
                           int32_t doc_id) {
+    HighlightWriterIVARS *const ivars = HLWriter_IVARS(self);
     OutStream *dat_out = S_lazy_init(self);
-    OutStream *ix_out  = self->ix_out;
+    OutStream *ix_out  = ivars->ix_out;
     int64_t    filepos = OutStream_Tell(dat_out);
     uint32_t num_highlightable = 0;
     int32_t expected = (int32_t)(OutStream_Tell(ix_out) / 8);
@@ -152,15 +155,16 @@ HLWriter_tv_buf(HighlightWriter *self, Inversion *inversion) {
     Inversion_Reset(inversion);
     while ((tokens = Inversion_Next_Cluster(inversion, &freq)) != NULL) {
         Token *token = *tokens;
-        int32_t overlap = StrHelp_overlap(last_text, token->text,
-                                          last_len, token->len);
+        TokenIVARS *token_ivars = Token_IVARS(token);
+        int32_t overlap = StrHelp_overlap(last_text, token_ivars->text,
+                                          last_len, token_ivars->len);
         char *ptr;
         char *orig;
         size_t old_size = BB_Get_Size(tv_buf);
         size_t new_size = old_size
                           + C32_MAX_BYTES      // overlap
                           + C32_MAX_BYTES      // length of string diff
-                          + (token->len - overlap) // diff char data
+                          + (token_ivars->len - overlap) // diff char data
                           + C32_MAX_BYTES                // num prox
                           + (C32_MAX_BYTES * freq * 3);  // pos data
 
@@ -174,22 +178,24 @@ HLWriter_tv_buf(HighlightWriter *self, Inversion *inversion) {
 
         // Append the string diff to the tv_buf.
         NumUtil_encode_c32(overlap, &ptr);
-        NumUtil_encode_c32((token->len - overlap), &ptr);
-        memcpy(ptr, (token->text + overlap), (token->len - overlap));
-        ptr += token->len - overlap;
+        NumUtil_encode_c32((token_ivars->len - overlap), &ptr);
+        memcpy(ptr, (token_ivars->text + overlap),
+               (token_ivars->len - overlap));
+        ptr += token_ivars->len - overlap;
 
         // Save text and text_len for comparison next loop.
-        last_text = token->text;
-        last_len  = token->len;
+        last_text = token_ivars->text;
+        last_len  = token_ivars->len;
 
         // Append the number of positions for this term.
         NumUtil_encode_c32(freq, &ptr);
 
         do {
+            token_ivars = Token_IVARS(token);
             // Add position, start_offset, and end_offset to tv_buf.
-            NumUtil_encode_c32(token->pos, &ptr);
-            NumUtil_encode_c32(token->start_offset, &ptr);
-            NumUtil_encode_c32(token->end_offset, &ptr);
+            NumUtil_encode_c32(token_ivars->pos, &ptr);
+            NumUtil_encode_c32(token_ivars->start_offset, &ptr);
+            NumUtil_encode_c32(token_ivars->end_offset, &ptr);
 
         } while (--freq && (token = *++tokens));
 
@@ -207,6 +213,7 @@ HLWriter_tv_buf(HighlightWriter *self, Inversion *inversion) {
 void
 HLWriter_add_segment(HighlightWriter *self, SegReader *reader,
                      I32Array *doc_map) {
+    HighlightWriterIVARS *const ivars = HLWriter_IVARS(self);
     int32_t doc_max = SegReader_Doc_Max(reader);
 
     if (doc_max == 0) {
@@ -219,7 +226,7 @@ HLWriter_add_segment(HighlightWriter *self, SegReader *reader,
                   SegReader_Obtain(reader, VTable_Get_Name(HIGHLIGHTREADER)),
                   DEFAULTHIGHLIGHTREADER);
         OutStream *dat_out = S_lazy_init(self);
-        OutStream *ix_out  = self->ix_out;
+        OutStream *ix_out  = ivars->ix_out;
         int32_t    orig;
         ByteBuf   *bb = BB_new(0);
 
@@ -244,16 +251,17 @@ HLWriter_add_segment(HighlightWriter *self, SegReader *reader,
 
 void
 HLWriter_finish(HighlightWriter *self) {
-    if (self->dat_out) {
+    HighlightWriterIVARS *const ivars = HLWriter_IVARS(self);
+    if (ivars->dat_out) {
         // Write one final file pointer, so that we can derive the length of
         // the last record.
-        int64_t end = OutStream_Tell(self->dat_out);
-        OutStream_Write_I64(self->ix_out, end);
+        int64_t end = OutStream_Tell(ivars->dat_out);
+        OutStream_Write_I64(ivars->ix_out, end);
 
         // Close down the output streams.
-        OutStream_Close(self->dat_out);
-        OutStream_Close(self->ix_out);
-        Seg_Store_Metadata_Str(self->segment, "highlight", 9,
+        OutStream_Close(ivars->dat_out);
+        OutStream_Close(ivars->ix_out);
+        Seg_Store_Metadata_Str(ivars->segment, "highlight", 9,
                                (Obj*)HLWriter_Metadata(self));
     }
 }


[lucy-commits] [27/34] git commit: refs/heads/master - Add getter for Token pos.

Posted by ma...@apache.org.
Add getter for Token pos.

Add a getter for Token's `pos` field, which only yields a valid value
after position increments have been resolved.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/e894b7c7
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/e894b7c7
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/e894b7c7

Branch: refs/heads/master
Commit: e894b7c7929216eb5ceec68510b2e5799b411f70
Parents: 0a48712
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Sun Jun 30 05:48:58 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 16:08:43 2013 -0700

----------------------------------------------------------------------
 core/Lucy/Analysis/Token.c   | 5 +++++
 core/Lucy/Analysis/Token.cfh | 6 ++++++
 2 files changed, 11 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/e894b7c7/core/Lucy/Analysis/Token.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Analysis/Token.c b/core/Lucy/Analysis/Token.c
index f5fec54..b1b1665 100644
--- a/core/Lucy/Analysis/Token.c
+++ b/core/Lucy/Analysis/Token.c
@@ -99,6 +99,11 @@ Token_get_pos_inc(Token *self) {
     return Token_IVARS(self)->pos_inc;
 }
 
+int32_t
+Token_get_pos(Token *self) {
+    return Token_IVARS(self)->pos;
+}
+
 char*
 Token_get_text(Token *self) {
     return Token_IVARS(self)->text;

http://git-wip-us.apache.org/repos/asf/lucy/blob/e894b7c7/core/Lucy/Analysis/Token.cfh
----------------------------------------------------------------------
diff --git a/core/Lucy/Analysis/Token.cfh b/core/Lucy/Analysis/Token.cfh
index cec0109..0ebfeb5 100644
--- a/core/Lucy/Analysis/Token.cfh
+++ b/core/Lucy/Analysis/Token.cfh
@@ -85,6 +85,12 @@ class Lucy::Analysis::Token inherits Clownfish::Obj {
     int32_t
     Get_Pos_Inc(Token *self);
 
+    /** Accessor for pos.  Only valid after position increments for an array
+     * of tokens have been resolved.
+     */
+    int32_t
+    Get_Pos(Token *self);
+
     char*
     Get_Text(Token *self);
 


[lucy-commits] [10/34] Migrate Lucy's index classes to IVARS.

Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/Snapshot.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/Snapshot.c b/core/Lucy/Index/Snapshot.c
index beca285..4bae50f 100644
--- a/core/Lucy/Index/Snapshot.c
+++ b/core/Lucy/Index/Snapshot.c
@@ -38,10 +38,11 @@ Snapshot_new() {
 
 static void
 S_zero_out(Snapshot *self) {
-    DECREF(self->entries);
-    DECREF(self->path);
-    self->entries  = Hash_new(0);
-    self->path = NULL;
+    SnapshotIVARS *const ivars = Snapshot_IVARS(self);
+    DECREF(ivars->entries);
+    DECREF(ivars->path);
+    ivars->entries  = Hash_new(0);
+    ivars->path = NULL;
 }
 
 Snapshot*
@@ -52,19 +53,22 @@ Snapshot_init(Snapshot *self) {
 
 void
 Snapshot_destroy(Snapshot *self) {
-    DECREF(self->entries);
-    DECREF(self->path);
+    SnapshotIVARS *const ivars = Snapshot_IVARS(self);
+    DECREF(ivars->entries);
+    DECREF(ivars->path);
     SUPER_DESTROY(self, SNAPSHOT);
 }
 
 void
 Snapshot_add_entry(Snapshot *self, const CharBuf *entry) {
-    Hash_Store(self->entries, (Obj*)entry, (Obj*)CFISH_TRUE);
+    SnapshotIVARS *const ivars = Snapshot_IVARS(self);
+    Hash_Store(ivars->entries, (Obj*)entry, (Obj*)CFISH_TRUE);
 }
 
 bool
 Snapshot_delete_entry(Snapshot *self, const CharBuf *entry) {
-    Obj *val = Hash_Delete(self->entries, (Obj*)entry);
+    SnapshotIVARS *const ivars = Snapshot_IVARS(self);
+    Obj *val = Hash_Delete(ivars->entries, (Obj*)entry);
     if (val) {
         Obj_Dec_RefCount(val);
         return true;
@@ -76,34 +80,39 @@ Snapshot_delete_entry(Snapshot *self, const CharBuf *entry) {
 
 VArray*
 Snapshot_list(Snapshot *self) {
-    return Hash_Keys(self->entries);
+    SnapshotIVARS *const ivars = Snapshot_IVARS(self);
+    return Hash_Keys(ivars->entries);
 }
 
 uint32_t
 Snapshot_num_entries(Snapshot *self) {
-    return Hash_Get_Size(self->entries);
+    SnapshotIVARS *const ivars = Snapshot_IVARS(self);
+    return Hash_Get_Size(ivars->entries);
 }
 
 void
 Snapshot_set_path(Snapshot *self, const CharBuf *path) {
-    DECREF(self->path);
-    self->path = path ? CB_Clone(path) : NULL;
+    SnapshotIVARS *const ivars = Snapshot_IVARS(self);
+    DECREF(ivars->path);
+    ivars->path = path ? CB_Clone(path) : NULL;
 }
 
 CharBuf*
 Snapshot_get_path(Snapshot *self) {
-    return self->path;
+    return Snapshot_IVARS(self)->path;
 }
 
 Snapshot*
 Snapshot_read_file(Snapshot *self, Folder *folder, const CharBuf *path) {
+    SnapshotIVARS *const ivars = Snapshot_IVARS(self);
+
     // Eliminate all prior data. Pick a snapshot file.
     S_zero_out(self);
-    self->path = path ? CB_Clone(path) : IxFileNames_latest_snapshot(folder);
+    ivars->path = path ? CB_Clone(path) : IxFileNames_latest_snapshot(folder);
 
-    if (self->path) {
+    if (ivars->path) {
         Hash *snap_data
-            = (Hash*)CERTIFY(Json_slurp_json(folder, self->path), HASH);
+            = (Hash*)CERTIFY(Json_slurp_json(folder, ivars->path), HASH);
         Obj *format_obj
             = CERTIFY(Hash_Fetch_Str(snap_data, "format", 6), OBJ);
         int32_t format = (int32_t)Obj_To_I64(format_obj);
@@ -128,11 +137,11 @@ Snapshot_read_file(Snapshot *self, Folder *folder, const CharBuf *path) {
             DECREF(list);
             list = cleaned;
         }
-        Hash_Clear(self->entries);
+        Hash_Clear(ivars->entries);
         for (uint32_t i = 0, max = VA_Get_Size(list); i < max; i++) {
             CharBuf *entry
                 = (CharBuf*)CERTIFY(VA_Fetch(list, i), CHARBUF);
-            Hash_Store(self->entries, (Obj*)entry, (Obj*)CFISH_TRUE);
+            Hash_Store(ivars->entries, (Obj*)entry, (Obj*)CFISH_TRUE);
         }
 
         DECREF(list);
@@ -163,26 +172,27 @@ S_clean_segment_contents(VArray *orig) {
 
 void
 Snapshot_write_file(Snapshot *self, Folder *folder, const CharBuf *path) {
+    SnapshotIVARS *const ivars = Snapshot_IVARS(self);
     Hash   *all_data = Hash_new(0);
     VArray *list     = Snapshot_List(self);
 
     // Update path.
-    DECREF(self->path);
+    DECREF(ivars->path);
     if (path) {
-        self->path = CB_Clone(path);
+        ivars->path = CB_Clone(path);
     }
     else {
         CharBuf *latest = IxFileNames_latest_snapshot(folder);
         uint64_t gen = latest ? IxFileNames_extract_gen(latest) + 1 : 1;
         char base36[StrHelp_MAX_BASE36_BYTES];
         StrHelp_to_base36(gen, &base36);
-        self->path = CB_newf("snapshot_%s.json", &base36);
+        ivars->path = CB_newf("snapshot_%s.json", &base36);
         DECREF(latest);
     }
 
     // Don't overwrite.
-    if (Folder_Exists(folder, self->path)) {
-        THROW(ERR, "Snapshot file '%o' already exists", self->path);
+    if (Folder_Exists(folder, ivars->path)) {
+        THROW(ERR, "Snapshot file '%o' already exists", ivars->path);
     }
 
     // Sort, then store file names.
@@ -196,7 +206,7 @@ Snapshot_write_file(Snapshot *self, Folder *folder, const CharBuf *path) {
                    (Obj*)CB_newf("%i32", (int32_t)Snapshot_current_file_subformat));
 
     // Write out JSON-ized data to the new file.
-    Json_spew_json((Obj*)all_data, folder, self->path);
+    Json_spew_json((Obj*)all_data, folder, ivars->path);
 
     DECREF(all_data);
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/SortCache.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/SortCache.c b/core/Lucy/Index/SortCache.c
index 00d41b2..31975ad 100644
--- a/core/Lucy/Index/SortCache.c
+++ b/core/Lucy/Index/SortCache.c
@@ -24,20 +24,22 @@ SortCache*
 SortCache_init(SortCache *self, const CharBuf *field, FieldType *type,
                void *ords, int32_t cardinality, int32_t doc_max, int32_t null_ord,
                int32_t ord_width) {
+    SortCacheIVARS *const ivars = SortCache_IVARS(self);
+
     // Init.
-    self->native_ords = false;
+    ivars->native_ords = false;
 
     // Assign.
     if (!FType_Sortable(type)) {
         THROW(ERR, "Non-sortable FieldType for %o", field);
     }
-    self->field       = CB_Clone(field);
-    self->type        = (FieldType*)INCREF(type);
-    self->ords        = ords;
-    self->cardinality = cardinality;
-    self->doc_max     = doc_max;
-    self->null_ord    = null_ord;
-    self->ord_width   = ord_width;
+    ivars->field       = CB_Clone(field);
+    ivars->type        = (FieldType*)INCREF(type);
+    ivars->ords        = ords;
+    ivars->cardinality = cardinality;
+    ivars->doc_max     = doc_max;
+    ivars->null_ord    = null_ord;
+    ivars->ord_width   = ord_width;
 
     ABSTRACT_CLASS_CHECK(self, SORTCACHE);
     return self;
@@ -45,56 +47,58 @@ SortCache_init(SortCache *self, const CharBuf *field, FieldType *type,
 
 void
 SortCache_destroy(SortCache *self) {
-    DECREF(self->field);
-    DECREF(self->type);
+    SortCacheIVARS *const ivars = SortCache_IVARS(self);
+    DECREF(ivars->field);
+    DECREF(ivars->type);
     SUPER_DESTROY(self, SORTCACHE);
 }
 
 bool
 SortCache_get_native_ords(SortCache *self) {
-    return self->native_ords;
+    return SortCache_IVARS(self)->native_ords;
 }
 
 void
 SortCache_set_native_ords(SortCache *self, bool native_ords) {
-    self->native_ords = native_ords;
+    SortCache_IVARS(self)->native_ords = native_ords;
 }
 
 int32_t
 SortCache_ordinal(SortCache *self, int32_t doc_id) {
-    if ((uint32_t)doc_id > (uint32_t)self->doc_max) {
-        THROW(ERR, "Out of range: %i32 > %i32", doc_id, self->doc_max);
+    SortCacheIVARS *const ivars = SortCache_IVARS(self);
+    if ((uint32_t)doc_id > (uint32_t)ivars->doc_max) {
+        THROW(ERR, "Out of range: %i32 > %i32", doc_id, ivars->doc_max);
     }
-    switch (self->ord_width) {
-        case 1: return NumUtil_u1get(self->ords, doc_id);
-        case 2: return NumUtil_u2get(self->ords, doc_id);
-        case 4: return NumUtil_u4get(self->ords, doc_id);
+    switch (ivars->ord_width) {
+        case 1: return NumUtil_u1get(ivars->ords, doc_id);
+        case 2: return NumUtil_u2get(ivars->ords, doc_id);
+        case 4: return NumUtil_u4get(ivars->ords, doc_id);
         case 8: {
-                uint8_t *ints = (uint8_t*)self->ords;
+                uint8_t *ints = (uint8_t*)ivars->ords;
                 return ints[doc_id];
             }
         case 16:
-            if (self->native_ords) {
-                uint16_t *ints = (uint16_t*)self->ords;
+            if (ivars->native_ords) {
+                uint16_t *ints = (uint16_t*)ivars->ords;
                 return ints[doc_id];
             }
             else {
-                uint8_t *bytes = (uint8_t*)self->ords;
+                uint8_t *bytes = (uint8_t*)ivars->ords;
                 bytes += doc_id * sizeof(uint16_t);
                 return NumUtil_decode_bigend_u16(bytes);
             }
         case 32:
-            if (self->native_ords) {
-                uint32_t *ints = (uint32_t*)self->ords;
+            if (ivars->native_ords) {
+                uint32_t *ints = (uint32_t*)ivars->ords;
                 return ints[doc_id];
             }
             else {
-                uint8_t *bytes = (uint8_t*)self->ords;
+                uint8_t *bytes = (uint8_t*)ivars->ords;
                 bytes += doc_id * sizeof(uint32_t);
                 return NumUtil_decode_bigend_u32(bytes);
             }
         default: {
-                THROW(ERR, "Invalid ord width: %i32", self->ord_width);
+                THROW(ERR, "Invalid ord width: %i32", ivars->ord_width);
                 UNREACHABLE_RETURN(int32_t);
             }
     }
@@ -102,9 +106,10 @@ SortCache_ordinal(SortCache *self, int32_t doc_id) {
 
 int32_t
 SortCache_find(SortCache *self, Obj *term) {
-    FieldType *const type   = self->type;
+    SortCacheIVARS *const ivars = SortCache_IVARS(self);
+    FieldType *const type   = ivars->type;
     int32_t          lo     = 0;
-    int32_t          hi     = self->cardinality - 1;
+    int32_t          hi     = ivars->cardinality - 1;
     int32_t          result = -100;
     Obj             *blank  = SortCache_Make_Blank(self);
 
@@ -113,7 +118,7 @@ SortCache_find(SortCache *self, Obj *term) {
         && !Obj_Is_A(blank, Obj_Get_VTable(term))
        ) {
         THROW(ERR, "SortCache error for field %o: term is a %o, and not "
-              "comparable to a %o", self->field, Obj_Get_Class_Name(term),
+              "comparable to a %o", ivars->field, Obj_Get_Class_Name(term),
               Obj_Get_Class_Name(blank));
     }
 
@@ -151,22 +156,22 @@ SortCache_find(SortCache *self, Obj *term) {
 
 void*
 SortCache_get_ords(SortCache *self) {
-    return self->ords;
+    return SortCache_IVARS(self)->ords;
 }
 
 int32_t
 SortCache_get_cardinality(SortCache *self) {
-    return self->cardinality;
+    return SortCache_IVARS(self)->cardinality;
 }
 
 int32_t
 SortCache_get_null_ord(SortCache *self) {
-    return self->null_ord;
+    return SortCache_IVARS(self)->null_ord;
 }
 
 int32_t
 SortCache_get_ord_width(SortCache *self) {
-    return self->ord_width;
+    return SortCache_IVARS(self)->ord_width;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/SortCache/NumericSortCache.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/SortCache/NumericSortCache.c b/core/Lucy/Index/SortCache/NumericSortCache.c
index 0898062..d4af636 100644
--- a/core/Lucy/Index/SortCache/NumericSortCache.c
+++ b/core/Lucy/Index/SortCache/NumericSortCache.c
@@ -45,19 +45,20 @@ NumSortCache_init(NumericSortCache *self, const CharBuf *field,
     void    *ords    = InStream_Buf(ord_in, (size_t)ord_len);
     SortCache_init((SortCache*)self, field, type, ords, cardinality, doc_max,
                    null_ord, ord_width);
+    NumericSortCacheIVARS *const ivars = NumSortCache_IVARS(self);
 
     // Assign.
-    self->ord_in = (InStream*)INCREF(ord_in);
-    self->dat_in = (InStream*)INCREF(dat_in);
+    ivars->ord_in = (InStream*)INCREF(ord_in);
+    ivars->dat_in = (InStream*)INCREF(dat_in);
 
     // Validate ord file length.
     double BITS_PER_BYTE = 8.0;
-    double docs_per_byte = BITS_PER_BYTE / self->ord_width;
+    double docs_per_byte = BITS_PER_BYTE / ivars->ord_width;
     double max_ords      = ord_len * docs_per_byte;
-    if (max_ords < self->doc_max + 1) {
+    if (max_ords < ivars->doc_max + 1) {
         DECREF(self);
         THROW(ERR, "Conflict between ord count max %f64 and doc_max %i32 for "
-              "field %o", max_ords, self->doc_max, field);
+              "field %o", max_ords, ivars->doc_max, field);
     }
 
     ABSTRACT_CLASS_CHECK(self, NUMERICSORTCACHE);
@@ -66,13 +67,14 @@ NumSortCache_init(NumericSortCache *self, const CharBuf *field,
 
 void
 NumSortCache_destroy(NumericSortCache *self) {
-    if (self->ord_in) {
-        InStream_Close(self->ord_in);
-        InStream_Dec_RefCount(self->ord_in);
+    NumericSortCacheIVARS *const ivars = NumSortCache_IVARS(self);
+    if (ivars->ord_in) {
+        InStream_Close(ivars->ord_in);
+        InStream_Dec_RefCount(ivars->ord_in);
     }
-    if (self->dat_in) {
-        InStream_Close(self->dat_in);
-        InStream_Dec_RefCount(self->dat_in);
+    if (ivars->dat_in) {
+        InStream_Close(ivars->dat_in);
+        InStream_Dec_RefCount(ivars->dat_in);
     }
     SUPER_DESTROY(self, NUMERICSORTCACHE);
 }
@@ -101,16 +103,17 @@ F64SortCache_init(Float64SortCache *self, const CharBuf *field,
 
 Obj*
 F64SortCache_value(Float64SortCache *self, int32_t ord, Obj *blank) {
-    if (ord == self->null_ord) {
+    Float64SortCacheIVARS *const ivars = F64SortCache_IVARS(self);
+    if (ord == ivars->null_ord) {
         return NULL;
     }
     else if (ord < 0) {
-        THROW(ERR, "Ordinal less than 0 for %o: %i32", self->field, ord);
+        THROW(ERR, "Ordinal less than 0 for %o: %i32", ivars->field, ord);
     }
     else {
         Float64 *num_blank = (Float64*)CERTIFY(blank, FLOAT64);
-        InStream_Seek(self->dat_in, ord * sizeof(double));
-        Float64_Set_Value(num_blank, InStream_Read_F64(self->dat_in));
+        InStream_Seek(ivars->dat_in, ord * sizeof(double));
+        Float64_Set_Value(num_blank, InStream_Read_F64(ivars->dat_in));
     }
     return blank;
 }
@@ -145,16 +148,17 @@ F32SortCache_init(Float32SortCache *self, const CharBuf *field,
 
 Obj*
 F32SortCache_value(Float32SortCache *self, int32_t ord, Obj *blank) {
-    if (ord == self->null_ord) {
+    Float32SortCacheIVARS *const ivars = F32SortCache_IVARS(self);
+    if (ord == ivars->null_ord) {
         return NULL;
     }
     else if (ord < 0) {
-        THROW(ERR, "Ordinal less than 0 for %o: %i32", self->field, ord);
+        THROW(ERR, "Ordinal less than 0 for %o: %i32", ivars->field, ord);
     }
     else {
         Float32 *num_blank = (Float32*)CERTIFY(blank, FLOAT32);
-        InStream_Seek(self->dat_in, ord * sizeof(float));
-        Float32_Set_Value(num_blank, InStream_Read_F32(self->dat_in));
+        InStream_Seek(ivars->dat_in, ord * sizeof(float));
+        Float32_Set_Value(num_blank, InStream_Read_F32(ivars->dat_in));
     }
     return blank;
 }
@@ -189,16 +193,17 @@ I32SortCache_init(Int32SortCache *self, const CharBuf *field,
 
 Obj*
 I32SortCache_value(Int32SortCache *self, int32_t ord, Obj *blank) {
-    if (ord == self->null_ord) {
+    Int32SortCacheIVARS *const ivars = I32SortCache_IVARS(self);
+    if (ord == ivars->null_ord) {
         return NULL;
     }
     else if (ord < 0) {
-        THROW(ERR, "Ordinal less than 0 for %o: %i32", self->field, ord);
+        THROW(ERR, "Ordinal less than 0 for %o: %i32", ivars->field, ord);
     }
     else {
         Integer32 *int_blank = (Integer32*)CERTIFY(blank, INTEGER32);
-        InStream_Seek(self->dat_in, ord * sizeof(int32_t));
-        Int32_Set_Value(int_blank, InStream_Read_I32(self->dat_in));
+        InStream_Seek(ivars->dat_in, ord * sizeof(int32_t));
+        Int32_Set_Value(int_blank, InStream_Read_I32(ivars->dat_in));
     }
     return blank;
 }
@@ -233,16 +238,17 @@ I64SortCache_init(Int64SortCache *self, const CharBuf *field,
 
 Obj*
 I64SortCache_value(Int64SortCache *self, int32_t ord, Obj *blank) {
-    if (ord == self->null_ord) {
+    Int64SortCacheIVARS *const ivars = I64SortCache_IVARS(self);
+    if (ord == ivars->null_ord) {
         return NULL;
     }
     else if (ord < 0) {
-        THROW(ERR, "Ordinal less than 0 for %o: %i32", self->field, ord);
+        THROW(ERR, "Ordinal less than 0 for %o: %i32", ivars->field, ord);
     }
     else {
         Integer64 *int_blank = (Integer64*)CERTIFY(blank, INTEGER64);
-        InStream_Seek(self->dat_in, ord * sizeof(int64_t));
-        Int64_Set_Value(int_blank, InStream_Read_I64(self->dat_in));
+        InStream_Seek(ivars->dat_in, ord * sizeof(int64_t));
+        Int64_Set_Value(int_blank, InStream_Read_I64(ivars->dat_in));
     }
     return blank;
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/SortCache/TextSortCache.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/SortCache/TextSortCache.c b/core/Lucy/Index/SortCache/TextSortCache.c
index 1905215..9c05c63 100644
--- a/core/Lucy/Index/SortCache/TextSortCache.c
+++ b/core/Lucy/Index/SortCache/TextSortCache.c
@@ -49,37 +49,39 @@ TextSortCache_init(TextSortCache *self, const CharBuf *field,
     void *ords = InStream_Buf(ord_in, (size_t)ord_len);
     SortCache_init((SortCache*)self, field, type, ords, cardinality, doc_max,
                    null_ord, ord_width);
+    TextSortCacheIVARS *const ivars = TextSortCache_IVARS(self);
 
     // Validate ords file length.
-    double  bytes_per_doc = self->ord_width / 8.0;
+    double  bytes_per_doc = ivars->ord_width / 8.0;
     double  max_ords      = ord_len / bytes_per_doc;
-    if (max_ords < self->doc_max + 1) {
-        WARN("ORD WIDTH: %i32 %i32", ord_width, self->ord_width);
+    if (max_ords < ivars->doc_max + 1) {
+        WARN("ORD WIDTH: %i32 %i32", ord_width, ivars->ord_width);
         THROW(ERR, "Conflict between ord count max %f64 and doc_max %i32 for "
               "field %o", max_ords, doc_max, field);
     }
 
     // Assign.
-    self->ord_in = (InStream*)INCREF(ord_in);
-    self->ix_in  = (InStream*)INCREF(ix_in);
-    self->dat_in = (InStream*)INCREF(dat_in);
+    ivars->ord_in = (InStream*)INCREF(ord_in);
+    ivars->ix_in  = (InStream*)INCREF(ix_in);
+    ivars->dat_in = (InStream*)INCREF(dat_in);
 
     return self;
 }
 
 void
 TextSortCache_destroy(TextSortCache *self) {
-    if (self->ord_in) {
-        InStream_Close(self->ord_in);
-        InStream_Dec_RefCount(self->ord_in);
+    TextSortCacheIVARS *const ivars = TextSortCache_IVARS(self);
+    if (ivars->ord_in) {
+        InStream_Close(ivars->ord_in);
+        InStream_Dec_RefCount(ivars->ord_in);
     }
-    if (self->ix_in) {
-        InStream_Close(self->ix_in);
-        InStream_Dec_RefCount(self->ix_in);
+    if (ivars->ix_in) {
+        InStream_Close(ivars->ix_in);
+        InStream_Dec_RefCount(ivars->ix_in);
     }
-    if (self->dat_in) {
-        InStream_Close(self->dat_in);
-        InStream_Dec_RefCount(self->dat_in);
+    if (ivars->dat_in) {
+        InStream_Close(ivars->dat_in);
+        InStream_Dec_RefCount(ivars->dat_in);
     }
     SUPER_DESTROY(self, TEXTSORTCACHE);
 }
@@ -88,11 +90,12 @@ TextSortCache_destroy(TextSortCache *self) {
 
 Obj*
 TextSortCache_value(TextSortCache *self, int32_t ord, Obj *blank) {
-    if (ord == self->null_ord) {
+    TextSortCacheIVARS *const ivars = TextSortCache_IVARS(self);
+    if (ord == ivars->null_ord) {
         return NULL;
     }
-    InStream_Seek(self->ix_in, ord * sizeof(int64_t));
-    int64_t offset = InStream_Read_I64(self->ix_in);
+    InStream_Seek(ivars->ix_in, ord * sizeof(int64_t));
+    int64_t offset = InStream_Read_I64(ivars->ix_in);
     if (offset == NULL_SENTINEL) {
         return NULL;
     }
@@ -100,8 +103,8 @@ TextSortCache_value(TextSortCache *self, int32_t ord, Obj *blank) {
         uint32_t next_ord = ord + 1;
         int64_t next_offset;
         while (1) {
-            InStream_Seek(self->ix_in, next_ord * sizeof(int64_t));
-            next_offset = InStream_Read_I64(self->ix_in);
+            InStream_Seek(ivars->ix_in, next_ord * sizeof(int64_t));
+            next_offset = InStream_Read_I64(ivars->ix_in);
             if (next_offset != NULL_SENTINEL) { break; }
             next_ord++;
         }
@@ -110,13 +113,13 @@ TextSortCache_value(TextSortCache *self, int32_t ord, Obj *blank) {
         CERTIFY(blank, CHARBUF);
         int64_t len = next_offset - offset;
         char *ptr = CB_Grow((CharBuf*)blank, (size_t)len);
-        InStream_Seek(self->dat_in, offset);
-        InStream_Read_Bytes(self->dat_in, ptr, (size_t)len);
+        InStream_Seek(ivars->dat_in, offset);
+        InStream_Read_Bytes(ivars->dat_in, ptr, (size_t)len);
         ptr[len] = '\0';
         if (!StrHelp_utf8_valid(ptr, (size_t)len)) {
             CB_Set_Size((CharBuf*)blank, 0);
             THROW(ERR, "Invalid UTF-8 at %i64 in %o", offset,
-                  InStream_Get_Filename(self->dat_in));
+                  InStream_Get_Filename(ivars->dat_in));
         }
         CB_Set_Size((CharBuf*)blank, (size_t)len);
     }

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/SortFieldWriter.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/SortFieldWriter.c b/core/Lucy/Index/SortFieldWriter.c
index 6d3bc16..59a90ec 100644
--- a/core/Lucy/Index/SortFieldWriter.c
+++ b/core/Lucy/Index/SortFieldWriter.c
@@ -77,56 +77,58 @@ SortFieldWriter_init(SortFieldWriter *self, Schema *schema,
                      OutStream *temp_dat_out) {
     // Init.
     SortEx_init((SortExternal*)self, sizeof(SFWriterElem));
-    self->null_ord        = -1;
-    self->count           = 0;
-    self->ord_start       = 0;
-    self->ord_end         = 0;
-    self->ix_start        = 0;
-    self->ix_end          = 0;
-    self->dat_start       = 0;
-    self->dat_end         = 0;
-    self->run_cardinality = -1;
-    self->run_max         = -1;
-    self->sort_cache      = NULL;
-    self->doc_map         = NULL;
-    self->sorted_ids      = NULL;
-    self->run_ord         = 0;
-    self->run_tick        = 0;
-    self->ord_width       = 0;
+    SortFieldWriterIVARS *const ivars = SortFieldWriter_IVARS(self);
+    ivars->null_ord        = -1;
+    ivars->count           = 0;
+    ivars->ord_start       = 0;
+    ivars->ord_end         = 0;
+    ivars->ix_start        = 0;
+    ivars->ix_end          = 0;
+    ivars->dat_start       = 0;
+    ivars->dat_end         = 0;
+    ivars->run_cardinality = -1;
+    ivars->run_max         = -1;
+    ivars->sort_cache      = NULL;
+    ivars->doc_map         = NULL;
+    ivars->sorted_ids      = NULL;
+    ivars->run_ord         = 0;
+    ivars->run_tick        = 0;
+    ivars->ord_width       = 0;
 
     // Assign.
-    self->field        = CB_Clone(field);
-    self->schema       = (Schema*)INCREF(schema);
-    self->snapshot     = (Snapshot*)INCREF(snapshot);
-    self->segment      = (Segment*)INCREF(segment);
-    self->polyreader   = (PolyReader*)INCREF(polyreader);
-    self->mem_pool     = (MemoryPool*)INCREF(memory_pool);
-    self->temp_ord_out = (OutStream*)INCREF(temp_ord_out);
-    self->temp_ix_out  = (OutStream*)INCREF(temp_ix_out);
-    self->temp_dat_out = (OutStream*)INCREF(temp_dat_out);
-    self->mem_thresh   = mem_thresh;
+    ivars->field        = CB_Clone(field);
+    ivars->schema       = (Schema*)INCREF(schema);
+    ivars->snapshot     = (Snapshot*)INCREF(snapshot);
+    ivars->segment      = (Segment*)INCREF(segment);
+    ivars->polyreader   = (PolyReader*)INCREF(polyreader);
+    ivars->mem_pool     = (MemoryPool*)INCREF(memory_pool);
+    ivars->temp_ord_out = (OutStream*)INCREF(temp_ord_out);
+    ivars->temp_ix_out  = (OutStream*)INCREF(temp_ix_out);
+    ivars->temp_dat_out = (OutStream*)INCREF(temp_dat_out);
+    ivars->mem_thresh   = mem_thresh;
 
     // Derive.
-    self->field_num = Seg_Field_Num(segment, field);
+    ivars->field_num = Seg_Field_Num(segment, field);
     FieldType *type = (FieldType*)CERTIFY(
-                          Schema_Fetch_Type(self->schema, field), FIELDTYPE);
-    self->type    = (FieldType*)INCREF(type);
-    self->prim_id = FType_Primitive_ID(type);
-    if (self->prim_id == FType_TEXT || self->prim_id == FType_BLOB) {
-        self->var_width = true;
+                          Schema_Fetch_Type(ivars->schema, field), FIELDTYPE);
+    ivars->type    = (FieldType*)INCREF(type);
+    ivars->prim_id = FType_Primitive_ID(type);
+    if (ivars->prim_id == FType_TEXT || ivars->prim_id == FType_BLOB) {
+        ivars->var_width = true;
     }
     else {
-        self->var_width = false;
+        ivars->var_width = false;
     }
-    self->uniq_vals = (Hash*)ZKHash_new(memory_pool, self->prim_id);
+    ivars->uniq_vals = (Hash*)ZKHash_new(memory_pool, ivars->prim_id);
 
     return self;
 }
 
 void
 SortFieldWriter_clear_cache(SortFieldWriter *self) {
-    if (self->uniq_vals) {
-        Hash_Clear(self->uniq_vals);
+    SortFieldWriterIVARS *const ivars = SortFieldWriter_IVARS(self);
+    if (ivars->uniq_vals) {
+        Hash_Clear(ivars->uniq_vals);
     }
     SortFieldWriter_Clear_Cache_t super_clear_cache
         = SUPER_METHOD_PTR(SORTFIELDWRITER, Lucy_SortFieldWriter_Clear_Cache);
@@ -135,35 +137,36 @@ SortFieldWriter_clear_cache(SortFieldWriter *self) {
 
 void
 SortFieldWriter_destroy(SortFieldWriter *self) {
-    DECREF(self->uniq_vals);
-    self->uniq_vals = NULL;
-    DECREF(self->field);
-    DECREF(self->schema);
-    DECREF(self->snapshot);
-    DECREF(self->segment);
-    DECREF(self->polyreader);
-    DECREF(self->type);
-    DECREF(self->mem_pool);
-    DECREF(self->temp_ord_out);
-    DECREF(self->temp_ix_out);
-    DECREF(self->temp_dat_out);
-    DECREF(self->ord_in);
-    DECREF(self->ix_in);
-    DECREF(self->dat_in);
-    DECREF(self->sort_cache);
-    DECREF(self->doc_map);
-    FREEMEM(self->sorted_ids);
+    SortFieldWriterIVARS *const ivars = SortFieldWriter_IVARS(self);
+    DECREF(ivars->uniq_vals);
+    ivars->uniq_vals = NULL;
+    DECREF(ivars->field);
+    DECREF(ivars->schema);
+    DECREF(ivars->snapshot);
+    DECREF(ivars->segment);
+    DECREF(ivars->polyreader);
+    DECREF(ivars->type);
+    DECREF(ivars->mem_pool);
+    DECREF(ivars->temp_ord_out);
+    DECREF(ivars->temp_ix_out);
+    DECREF(ivars->temp_dat_out);
+    DECREF(ivars->ord_in);
+    DECREF(ivars->ix_in);
+    DECREF(ivars->dat_in);
+    DECREF(ivars->sort_cache);
+    DECREF(ivars->doc_map);
+    FREEMEM(ivars->sorted_ids);
     SUPER_DESTROY(self, SORTFIELDWRITER);
 }
 
 int32_t
 SortFieldWriter_get_null_ord(SortFieldWriter *self) {
-    return self->null_ord;
+    return SortFieldWriter_IVARS(self)->null_ord;
 }
 
 int32_t
 SortFieldWriter_get_ord_width(SortFieldWriter *self) {
-    return self->ord_width;
+    return SortFieldWriter_IVARS(self)->ord_width;
 }
 
 static Obj*
@@ -179,28 +182,32 @@ S_find_unique_value(Hash *uniq_vals, Obj *val) {
 
 void
 SortFieldWriter_add(SortFieldWriter *self, int32_t doc_id, Obj *value) {
+    SortFieldWriterIVARS *const ivars = SortFieldWriter_IVARS(self);
+
     // Uniq-ify the value, and record it for this document.
     SFWriterElem elem;
-    elem.value = S_find_unique_value(self->uniq_vals, value);
+    elem.value = S_find_unique_value(ivars->uniq_vals, value);
     elem.doc_id = doc_id;
     SortFieldWriter_Feed(self, &elem);
-    self->count++;
+    ivars->count++;
 }
 
 void
 SortFieldWriter_add_segment(SortFieldWriter *self, SegReader *reader,
                             I32Array *doc_map, SortCache *sort_cache) {
     if (!sort_cache) { return; }
+    SortFieldWriterIVARS *const ivars = SortFieldWriter_IVARS(self);
     SortFieldWriter *run
-        = SortFieldWriter_new(self->schema, self->snapshot, self->segment,
-                              self->polyreader, self->field, self->mem_pool,
-                              self->mem_thresh, NULL, NULL, NULL);
-    run->sort_cache = (SortCache*)INCREF(sort_cache);
-    run->doc_map    = (I32Array*)INCREF(doc_map);
-    run->run_max    = SegReader_Doc_Max(reader);
-    run->run_cardinality = SortCache_Get_Cardinality(sort_cache);
-    run->null_ord   = SortCache_Get_Null_Ord(sort_cache);
-    run->run_tick   = 1;
+        = SortFieldWriter_new(ivars->schema, ivars->snapshot, ivars->segment,
+                              ivars->polyreader, ivars->field, ivars->mem_pool,
+                              ivars->mem_thresh, NULL, NULL, NULL);
+    SortFieldWriterIVARS *const run_ivars = SortFieldWriter_IVARS(run);
+    run_ivars->sort_cache = (SortCache*)INCREF(sort_cache);
+    run_ivars->doc_map    = (I32Array*)INCREF(doc_map);
+    run_ivars->run_max    = SegReader_Doc_Max(reader);
+    run_ivars->run_cardinality = SortCache_Get_Cardinality(sort_cache);
+    run_ivars->null_ord   = SortCache_Get_Null_Ord(sort_cache);
+    run_ivars->run_tick   = 1;
     SortFieldWriter_Add_Run(self, (SortExternal*)run);
 }
 
@@ -322,10 +329,11 @@ S_write_val(Obj *val, int8_t prim_id, OutStream *ix_out, OutStream *dat_out,
 
 int
 SortFieldWriter_compare(SortFieldWriter *self, void *va, void *vb) {
+    SortFieldWriterIVARS *const ivars = SortFieldWriter_IVARS(self);
     SFWriterElem *a = (SFWriterElem*)va;
     SFWriterElem *b = (SFWriterElem*)vb;
     int32_t comparison
-        = FType_null_back_compare_values(self->type, a->value, b->value);
+        = FType_null_back_compare_values(ivars->type, a->value, b->value);
     if (comparison == 0) { comparison = b->doc_id - a->doc_id; }
     return comparison;
 }
@@ -342,64 +350,68 @@ S_compare_doc_ids_by_ord_rev(void *context, const void *va, const void *vb) {
 
 static void
 S_lazy_init_sorted_ids(SortFieldWriter *self) {
-    if (!self->sorted_ids) {
-        self->sorted_ids
-            = (int32_t*)MALLOCATE((self->run_max + 1) * sizeof(int32_t));
-        for (int32_t i = 0, max = self->run_max; i <= max; i++) {
-            self->sorted_ids[i] = i;
+    SortFieldWriterIVARS *const ivars = SortFieldWriter_IVARS(self);
+    if (!ivars->sorted_ids) {
+        ivars->sorted_ids
+            = (int32_t*)MALLOCATE((ivars->run_max + 1) * sizeof(int32_t));
+        for (int32_t i = 0, max = ivars->run_max; i <= max; i++) {
+            ivars->sorted_ids[i] = i;
         }
-        Sort_quicksort(self->sorted_ids + 1, self->run_max, sizeof(int32_t),
-                       S_compare_doc_ids_by_ord_rev, self->sort_cache);
+        Sort_quicksort(ivars->sorted_ids + 1, ivars->run_max, sizeof(int32_t),
+                       S_compare_doc_ids_by_ord_rev, ivars->sort_cache);
     }
 }
 
 void
 SortFieldWriter_flush(SortFieldWriter *self) {
+    SortFieldWriterIVARS *const ivars = SortFieldWriter_IVARS(self);
+
     // Don't add a run unless we have data to put in it.
     if (SortFieldWriter_Cache_Count(self) == 0) { return; }
 
-    OutStream *const temp_ord_out = self->temp_ord_out;
-    OutStream *const temp_ix_out  = self->temp_ix_out;
-    OutStream *const temp_dat_out = self->temp_dat_out;
+    OutStream *const temp_ord_out = ivars->temp_ord_out;
+    OutStream *const temp_ix_out  = ivars->temp_ix_out;
+    OutStream *const temp_dat_out = ivars->temp_dat_out;
 
     SortFieldWriter_Sort_Cache(self);
     SortFieldWriter *run
-        = SortFieldWriter_new(self->schema, self->snapshot, self->segment,
-                              self->polyreader, self->field, self->mem_pool,
-                              self->mem_thresh, NULL, NULL, NULL);
+        = SortFieldWriter_new(ivars->schema, ivars->snapshot, ivars->segment,
+                              ivars->polyreader, ivars->field, ivars->mem_pool,
+                              ivars->mem_thresh, NULL, NULL, NULL);
+    SortFieldWriterIVARS *const run_ivars = SortFieldWriter_IVARS(run);
 
     // Record stream starts and align.
-    run->ord_start = OutStream_Align(temp_ord_out, sizeof(int64_t));
-    if (self->var_width) {
-        run->ix_start  = OutStream_Align(temp_ix_out, sizeof(int64_t));
+    run_ivars->ord_start = OutStream_Align(temp_ord_out, sizeof(int64_t));
+    if (ivars->var_width) {
+        run_ivars->ix_start  = OutStream_Align(temp_ix_out, sizeof(int64_t));
     }
-    run->dat_start = OutStream_Align(temp_dat_out, sizeof(int64_t));
+    run_ivars->dat_start = OutStream_Align(temp_dat_out, sizeof(int64_t));
 
     // Have the run borrow the array of elems.
-    run->cache      = self->cache;
-    run->cache_max  = self->cache_max;
-    run->cache_tick = self->cache_tick;
-    run->cache_cap  = self->cache_cap;
+    run_ivars->cache      = ivars->cache;
+    run_ivars->cache_max  = ivars->cache_max;
+    run_ivars->cache_tick = ivars->cache_tick;
+    run_ivars->cache_cap  = ivars->cache_cap;
 
     // Write files, record stats.
-    run->run_max = (int32_t)Seg_Get_Count(self->segment);
-    run->run_cardinality = S_write_files(run, temp_ord_out, temp_ix_out,
-                                         temp_dat_out);
+    run_ivars->run_max = (int32_t)Seg_Get_Count(ivars->segment);
+    run_ivars->run_cardinality = S_write_files(run, temp_ord_out, temp_ix_out,
+                                               temp_dat_out);
 
     // Reclaim the buffer from the run and empty it.
-    run->cache       = NULL;
-    run->cache_max   = 0;
-    run->cache_tick  = 0;
-    run->cache_cap   = 0;
-    self->cache_tick = self->cache_max;
+    run_ivars->cache       = NULL;
+    run_ivars->cache_max   = 0;
+    run_ivars->cache_tick  = 0;
+    run_ivars->cache_cap   = 0;
+    ivars->cache_tick = ivars->cache_max;
     SortFieldWriter_Clear_Cache(self);
 
     // Record stream ends.
-    run->ord_end = OutStream_Tell(temp_ord_out);
-    if (self->var_width) {
-        run->ix_end  = OutStream_Tell(temp_ix_out);
+    run_ivars->ord_end = OutStream_Tell(temp_ord_out);
+    if (ivars->var_width) {
+        run_ivars->ix_end  = OutStream_Tell(temp_ix_out);
     }
-    run->dat_end = OutStream_Tell(temp_dat_out);
+    run_ivars->dat_end = OutStream_Tell(temp_dat_out);
 
     // Add the run to the array.
     SortFieldWriter_Add_Run(self, (SortExternal*)run);
@@ -407,7 +419,8 @@ SortFieldWriter_flush(SortFieldWriter *self) {
 
 uint32_t
 SortFieldWriter_refill(SortFieldWriter *self) {
-    if (!self->sort_cache) { return 0; }
+    SortFieldWriterIVARS *const ivars = SortFieldWriter_IVARS(self);
+    if (!ivars->sort_cache) { return 0; }
 
     // Sanity check, then reset the cache and prepare to start loading items.
     uint32_t cache_count = SortFieldWriter_Cache_Count(self);
@@ -416,28 +429,28 @@ SortFieldWriter_refill(SortFieldWriter *self) {
               cache_count);
     }
     SortFieldWriter_Clear_Cache(self);
-    MemPool_Release_All(self->mem_pool);
+    MemPool_Release_All(ivars->mem_pool);
     S_lazy_init_sorted_ids(self);
 
-    const int32_t    null_ord   = self->null_ord;
-    Hash *const      uniq_vals  = self->uniq_vals;
-    I32Array *const  doc_map    = self->doc_map;
-    SortCache *const sort_cache = self->sort_cache;
+    const int32_t    null_ord   = ivars->null_ord;
+    Hash *const      uniq_vals  = ivars->uniq_vals;
+    I32Array *const  doc_map    = ivars->doc_map;
+    SortCache *const sort_cache = ivars->sort_cache;
     Obj *const       blank      = SortCache_Make_Blank(sort_cache);
 
-    while (self->run_ord < self->run_cardinality
-           && MemPool_Get_Consumed(self->mem_pool) < self->mem_thresh
+    while (ivars->run_ord < ivars->run_cardinality
+           && MemPool_Get_Consumed(ivars->mem_pool) < ivars->mem_thresh
           ) {
-        Obj *val = SortCache_Value(sort_cache, self->run_ord, blank);
+        Obj *val = SortCache_Value(sort_cache, ivars->run_ord, blank);
         if (val) {
             Hash_Store(uniq_vals, val, (Obj*)CFISH_TRUE);
             break;
         }
-        self->run_ord++;
+        ivars->run_ord++;
     }
     uint32_t count = 0;
-    while (self->run_tick <= self->run_max) {
-        int32_t raw_doc_id = self->sorted_ids[self->run_tick];
+    while (ivars->run_tick <= ivars->run_max) {
+        int32_t raw_doc_id = ivars->sorted_ids[ivars->run_tick];
         int32_t ord = SortCache_Ordinal(sort_cache, raw_doc_id);
         if (ord != null_ord) {
             int32_t remapped = doc_map
@@ -449,17 +462,17 @@ SortFieldWriter_refill(SortFieldWriter *self) {
                 count++;
             }
         }
-        else if (ord > self->run_ord) {
+        else if (ord > ivars->run_ord) {
             break;
         }
-        self->run_tick++;
+        ivars->run_tick++;
     }
-    self->run_ord++;
+    ivars->run_ord++;
     SortFieldWriter_Sort_Cache(self);
 
-    if (self->run_ord >= self->run_cardinality) {
-        DECREF(self->sort_cache);
-        self->sort_cache = NULL;
+    if (ivars->run_ord >= ivars->run_cardinality) {
+        DECREF(ivars->sort_cache);
+        ivars->sort_cache = NULL;
     }
 
     DECREF(blank);
@@ -468,11 +481,12 @@ SortFieldWriter_refill(SortFieldWriter *self) {
 
 void
 SortFieldWriter_flip(SortFieldWriter *self) {
+    SortFieldWriterIVARS *const ivars = SortFieldWriter_IVARS(self);
     uint32_t num_items = SortFieldWriter_Cache_Count(self);
-    uint32_t num_runs = VA_Get_Size(self->runs);
+    uint32_t num_runs = VA_Get_Size(ivars->runs);
 
-    if (self->flipped) { THROW(ERR, "Can't call Flip() twice"); }
-    self->flipped = true;
+    if (ivars->flipped) { THROW(ERR, "Can't call Flip() twice"); }
+    ivars->flipped = true;
 
     // Sanity check.
     if (num_runs && num_items) {
@@ -484,40 +498,41 @@ SortFieldWriter_flip(SortFieldWriter *self) {
         SortFieldWriter_Sort_Cache(self);
     }
     else if (num_runs) {
-        Folder  *folder = PolyReader_Get_Folder(self->polyreader);
-        CharBuf *seg_name = Seg_Get_Name(self->segment);
+        Folder  *folder = PolyReader_Get_Folder(ivars->polyreader);
+        CharBuf *seg_name = Seg_Get_Name(ivars->segment);
         CharBuf *filepath = CB_newf("%o/sort_ord_temp", seg_name);
-        self->ord_in = Folder_Open_In(folder, filepath);
-        if (!self->ord_in) { RETHROW(INCREF(Err_get_error())); }
-        if (self->var_width) {
+        ivars->ord_in = Folder_Open_In(folder, filepath);
+        if (!ivars->ord_in) { RETHROW(INCREF(Err_get_error())); }
+        if (ivars->var_width) {
             CB_setf(filepath, "%o/sort_ix_temp", seg_name);
-            self->ix_in = Folder_Open_In(folder, filepath);
-            if (!self->ix_in) { RETHROW(INCREF(Err_get_error())); }
+            ivars->ix_in = Folder_Open_In(folder, filepath);
+            if (!ivars->ix_in) { RETHROW(INCREF(Err_get_error())); }
         }
         CB_setf(filepath, "%o/sort_dat_temp", seg_name);
-        self->dat_in = Folder_Open_In(folder, filepath);
-        if (!self->dat_in) { RETHROW(INCREF(Err_get_error())); }
+        ivars->dat_in = Folder_Open_In(folder, filepath);
+        if (!ivars->dat_in) { RETHROW(INCREF(Err_get_error())); }
         DECREF(filepath);
 
         // Assign streams and a slice of mem_thresh.
-        size_t sub_thresh = self->mem_thresh / num_runs;
+        size_t sub_thresh = ivars->mem_thresh / num_runs;
         if (sub_thresh < 65536) { sub_thresh = 65536; }
         for (uint32_t i = 0; i < num_runs; i++) {
-            SortFieldWriter *run = (SortFieldWriter*)VA_Fetch(self->runs, i);
-            S_flip_run(run, sub_thresh, self->ord_in, self->ix_in,
-                       self->dat_in);
+            SortFieldWriter *run = (SortFieldWriter*)VA_Fetch(ivars->runs, i);
+            S_flip_run(run, sub_thresh, ivars->ord_in, ivars->ix_in,
+                       ivars->dat_in);
         }
     }
 
-    self->flipped = true;
+    ivars->flipped = true;
 }
 
 static int32_t
 S_write_files(SortFieldWriter *self, OutStream *ord_out, OutStream *ix_out,
               OutStream *dat_out) {
-    int8_t    prim_id   = self->prim_id;
-    int32_t   doc_max   = (int32_t)Seg_Get_Count(self->segment);
-    bool      has_nulls = self->count == doc_max ? false : true;
+    SortFieldWriterIVARS *const ivars = SortFieldWriter_IVARS(self);
+    int8_t    prim_id   = ivars->prim_id;
+    int32_t   doc_max   = (int32_t)Seg_Get_Count(ivars->segment);
+    bool      has_nulls = ivars->count == doc_max ? false : true;
     size_t    size      = (doc_max + 1) * sizeof(int32_t);
     int32_t  *ords      = (int32_t*)MALLOCATE(size);
     int32_t   ord       = 0;
@@ -541,7 +556,7 @@ S_write_files(SortFieldWriter *self, OutStream *ord_out, OutStream *ix_out,
     while (NULL != (elem = (SFWriterElem*)SortFieldWriter_Fetch(self))) {
         if (elem->value != last_val_address) {
             int32_t comparison
-                = FType_Compare_Values(self->type, elem->value, val);
+                = FType_Compare_Values(ivars->type, elem->value, val);
             if (comparison != 0) {
                 ord++;
                 S_write_val(elem->value, prim_id, ix_out, dat_out, dat_start);
@@ -557,19 +572,19 @@ S_write_files(SortFieldWriter *self, OutStream *ord_out, OutStream *ix_out,
     if (has_nulls) {
         S_write_val(NULL, prim_id, ix_out, dat_out, dat_start);
         ord++;
-        self->null_ord = ord;
+        ivars->null_ord = ord;
     }
-    int32_t null_ord = self->null_ord;
+    int32_t null_ord = ivars->null_ord;
 
     // Write one extra file pointer so that we can always derive length.
-    if (self->var_width) {
+    if (ivars->var_width) {
         OutStream_Write_I64(ix_out, OutStream_Tell(dat_out) - dat_start);
     }
 
     // Calculate cardinality and ord width.
     int32_t cardinality = ord + 1;
-    self->ord_width     = S_calc_width(cardinality);
-    int32_t ord_width   = self->ord_width;
+    ivars->ord_width     = S_calc_width(cardinality);
+    int32_t ord_width   = ivars->ord_width;
 
     // Write ords.
     const double BITS_PER_BYTE = 8.0;
@@ -590,19 +605,21 @@ S_write_files(SortFieldWriter *self, OutStream *ord_out, OutStream *ix_out,
 
 int32_t
 SortFieldWriter_finish(SortFieldWriter *self) {
+    SortFieldWriterIVARS *const ivars = SortFieldWriter_IVARS(self);
+
     // Bail if there's no data.
     if (!SortFieldWriter_Peek(self)) { return 0; }
 
-    int32_t  field_num = self->field_num;
-    Folder  *folder    = PolyReader_Get_Folder(self->polyreader);
-    CharBuf *seg_name  = Seg_Get_Name(self->segment);
+    int32_t  field_num = ivars->field_num;
+    Folder  *folder    = PolyReader_Get_Folder(ivars->polyreader);
+    CharBuf *seg_name  = Seg_Get_Name(ivars->segment);
     CharBuf *path      = CB_newf("%o/sort-%i32.ord", seg_name, field_num);
 
     // Open streams.
     OutStream *ord_out = Folder_Open_Out(folder, path);
     if (!ord_out) { RETHROW(INCREF(Err_get_error())); }
     OutStream *ix_out = NULL;
-    if (self->var_width) {
+    if (ivars->var_width) {
         CB_setf(path, "%o/sort-%i32.ix", seg_name, field_num);
         ix_out = Folder_Open_Out(folder, path);
         if (!ix_out) { RETHROW(INCREF(Err_get_error())); }
@@ -628,78 +645,80 @@ SortFieldWriter_finish(SortFieldWriter *self) {
 static void
 S_flip_run(SortFieldWriter *run, size_t sub_thresh, InStream *ord_in,
            InStream *ix_in, InStream *dat_in) {
-    if (run->flipped) { THROW(ERR, "Can't Flip twice"); }
-    run->flipped = true;
+    SortFieldWriterIVARS *const run_ivars = SortFieldWriter_IVARS(run);
+
+    if (run_ivars->flipped) { THROW(ERR, "Can't Flip twice"); }
+    run_ivars->flipped = true;
 
     // Get our own MemoryPool, ZombieKeyedHash, and slice of mem_thresh.
-    DECREF(run->uniq_vals);
-    DECREF(run->mem_pool);
-    run->mem_pool   = MemPool_new(0);
-    run->uniq_vals  = (Hash*)ZKHash_new(run->mem_pool, run->prim_id);
-    run->mem_thresh = sub_thresh;
+    DECREF(run_ivars->uniq_vals);
+    DECREF(run_ivars->mem_pool);
+    run_ivars->mem_pool   = MemPool_new(0);
+    run_ivars->uniq_vals  = (Hash*)ZKHash_new(run_ivars->mem_pool, run_ivars->prim_id);
+    run_ivars->mem_thresh = sub_thresh;
 
     // Done if we already have a SortCache to read from.
-    if (run->sort_cache) { return; }
+    if (run_ivars->sort_cache) { return; }
 
     // Open the temp files for reading.
-    CharBuf *seg_name = Seg_Get_Name(run->segment);
+    CharBuf *seg_name = Seg_Get_Name(run_ivars->segment);
     CharBuf *alias    = CB_newf("%o/sort_ord_temp-%i64-to-%i64", seg_name,
-                                run->ord_start, run->ord_end);
-    InStream *ord_in_dupe = InStream_Reopen(ord_in, alias, run->ord_start,
-                                            run->ord_end - run->ord_start);
+                                run_ivars->ord_start, run_ivars->ord_end);
+    InStream *ord_in_dupe = InStream_Reopen(ord_in, alias, run_ivars->ord_start,
+                                            run_ivars->ord_end - run_ivars->ord_start);
     InStream *ix_in_dupe = NULL;
-    if (run->var_width) {
+    if (run_ivars->var_width) {
         CB_setf(alias, "%o/sort_ix_temp-%i64-to-%i64", seg_name,
-                run->ix_start, run->ix_end);
-        ix_in_dupe = InStream_Reopen(ix_in, alias, run->ix_start,
-                                     run->ix_end - run->ix_start);
+                run_ivars->ix_start, run_ivars->ix_end);
+        ix_in_dupe = InStream_Reopen(ix_in, alias, run_ivars->ix_start,
+                                     run_ivars->ix_end - run_ivars->ix_start);
     }
     CB_setf(alias, "%o/sort_dat_temp-%i64-to-%i64", seg_name,
-            run->dat_start, run->dat_end);
-    InStream *dat_in_dupe = InStream_Reopen(dat_in, alias, run->dat_start,
-                                            run->dat_end - run->dat_start);
+            run_ivars->dat_start, run_ivars->dat_end);
+    InStream *dat_in_dupe = InStream_Reopen(dat_in, alias, run_ivars->dat_start,
+                                            run_ivars->dat_end - run_ivars->dat_start);
     DECREF(alias);
 
     // Get a SortCache.
-    CharBuf *field = Seg_Field_Name(run->segment, run->field_num);
-    switch (run->prim_id & FType_PRIMITIVE_ID_MASK) {
+    CharBuf *field = Seg_Field_Name(run_ivars->segment, run_ivars->field_num);
+    switch (run_ivars->prim_id & FType_PRIMITIVE_ID_MASK) {
         case FType_TEXT:
-            run->sort_cache = (SortCache*)TextSortCache_new(
-                                  field, run->type, run->run_cardinality,
-                                  run->run_max, run->null_ord,
-                                  run->ord_width, ord_in_dupe,
+            run_ivars->sort_cache = (SortCache*)TextSortCache_new(
+                                  field, run_ivars->type, run_ivars->run_cardinality,
+                                  run_ivars->run_max, run_ivars->null_ord,
+                                  run_ivars->ord_width, ord_in_dupe,
                                   ix_in_dupe, dat_in_dupe);
             break;
         case FType_INT32:
-            run->sort_cache = (SortCache*)I32SortCache_new(
-                                  field, run->type, run->run_cardinality,
-                                  run->run_max, run->null_ord,
-                                  run->ord_width, ord_in_dupe,
+            run_ivars->sort_cache = (SortCache*)I32SortCache_new(
+                                  field, run_ivars->type, run_ivars->run_cardinality,
+                                  run_ivars->run_max, run_ivars->null_ord,
+                                  run_ivars->ord_width, ord_in_dupe,
                                   dat_in_dupe);
             break;
         case FType_INT64:
-            run->sort_cache = (SortCache*)I64SortCache_new(
-                                  field, run->type, run->run_cardinality,
-                                  run->run_max, run->null_ord,
-                                  run->ord_width, ord_in_dupe,
+            run_ivars->sort_cache = (SortCache*)I64SortCache_new(
+                                  field, run_ivars->type, run_ivars->run_cardinality,
+                                  run_ivars->run_max, run_ivars->null_ord,
+                                  run_ivars->ord_width, ord_in_dupe,
                                   dat_in_dupe);
             break;
         case FType_FLOAT32:
-            run->sort_cache = (SortCache*)F32SortCache_new(
-                                  field, run->type, run->run_cardinality,
-                                  run->run_max, run->null_ord,
-                                  run->ord_width, ord_in_dupe,
+            run_ivars->sort_cache = (SortCache*)F32SortCache_new(
+                                  field, run_ivars->type, run_ivars->run_cardinality,
+                                  run_ivars->run_max, run_ivars->null_ord,
+                                  run_ivars->ord_width, ord_in_dupe,
                                   dat_in_dupe);
             break;
         case FType_FLOAT64:
-            run->sort_cache = (SortCache*)F64SortCache_new(
-                                  field, run->type, run->run_cardinality,
-                                  run->run_max, run->null_ord,
-                                  run->ord_width, ord_in_dupe,
+            run_ivars->sort_cache = (SortCache*)F64SortCache_new(
+                                  field, run_ivars->type, run_ivars->run_cardinality,
+                                  run_ivars->run_max, run_ivars->null_ord,
+                                  run_ivars->ord_width, ord_in_dupe,
                                   dat_in_dupe);
             break;
         default:
-            THROW(ERR, "No SortCache class for %o", run->type);
+            THROW(ERR, "No SortCache class for %o", run_ivars->type);
     }
 
     DECREF(ord_in_dupe);

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/SortReader.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/SortReader.c b/core/Lucy/Index/SortReader.c
index 159d837..25f2df4 100644
--- a/core/Lucy/Index/SortReader.c
+++ b/core/Lucy/Index/SortReader.c
@@ -58,57 +58,56 @@ DefSortReader_new(Schema *schema, Folder *folder, Snapshot *snapshot,
 DefaultSortReader*
 DefSortReader_init(DefaultSortReader *self, Schema *schema, Folder *folder,
                    Snapshot *snapshot, VArray *segments, int32_t seg_tick) {
-    Segment *segment;
-    Hash    *metadata;
     DataReader_init((DataReader*)self, schema, folder, snapshot, segments,
                     seg_tick);
-    segment = DefSortReader_Get_Segment(self);
-    metadata = (Hash*)Seg_Fetch_Metadata_Str(segment, "sort", 4);
+    DefaultSortReaderIVARS *const ivars = DefSortReader_IVARS(self);
+    Segment *segment  = DefSortReader_Get_Segment(self);
+    Hash    *metadata = (Hash*)Seg_Fetch_Metadata_Str(segment, "sort", 4);
 
     // Check format.
-    self->format = 0;
+    ivars->format = 0;
     if (metadata) {
         Obj *format = Hash_Fetch_Str(metadata, "format", 6);
         if (!format) { THROW(ERR, "Missing 'format' var"); }
         else {
-            self->format = (int32_t)Obj_To_I64(format);
-            if (self->format < 2 || self->format > 3) {
+            ivars->format = (int32_t)Obj_To_I64(format);
+            if (ivars->format < 2 || ivars->format > 3) {
                 THROW(ERR, "Unsupported sort cache format: %i32",
-                      self->format);
+                      ivars->format);
             }
         }
     }
 
     // Init.
-    self->caches = Hash_new(0);
+    ivars->caches = Hash_new(0);
 
     // Either extract or fake up the "counts", "null_ords", and "ord_widths"
     // hashes.
     if (metadata) {
-        self->counts
+        ivars->counts
             = (Hash*)INCREF(CERTIFY(Hash_Fetch_Str(metadata, "counts", 6),
                                     HASH));
-        self->null_ords = (Hash*)Hash_Fetch_Str(metadata, "null_ords", 9);
-        if (self->null_ords) {
-            CERTIFY(self->null_ords, HASH);
-            INCREF(self->null_ords);
+        ivars->null_ords = (Hash*)Hash_Fetch_Str(metadata, "null_ords", 9);
+        if (ivars->null_ords) {
+            CERTIFY(ivars->null_ords, HASH);
+            INCREF(ivars->null_ords);
         }
         else {
-            self->null_ords = Hash_new(0);
+            ivars->null_ords = Hash_new(0);
         }
-        self->ord_widths = (Hash*)Hash_Fetch_Str(metadata, "ord_widths", 10);
-        if (self->ord_widths) {
-            CERTIFY(self->ord_widths, HASH);
-            INCREF(self->ord_widths);
+        ivars->ord_widths = (Hash*)Hash_Fetch_Str(metadata, "ord_widths", 10);
+        if (ivars->ord_widths) {
+            CERTIFY(ivars->ord_widths, HASH);
+            INCREF(ivars->ord_widths);
         }
         else {
-            self->ord_widths = Hash_new(0);
+            ivars->ord_widths = Hash_new(0);
         }
     }
     else {
-        self->counts     = Hash_new(0);
-        self->null_ords  = Hash_new(0);
-        self->ord_widths = Hash_new(0);
+        ivars->counts     = Hash_new(0);
+        ivars->null_ords  = Hash_new(0);
+        ivars->ord_widths = Hash_new(0);
     }
 
     return self;
@@ -116,30 +115,32 @@ DefSortReader_init(DefaultSortReader *self, Schema *schema, Folder *folder,
 
 void
 DefSortReader_close(DefaultSortReader *self) {
-    if (self->caches) {
-        Hash_Dec_RefCount(self->caches);
-        self->caches = NULL;
+    DefaultSortReaderIVARS *const ivars = DefSortReader_IVARS(self);
+    if (ivars->caches) {
+        Hash_Dec_RefCount(ivars->caches);
+        ivars->caches = NULL;
     }
-    if (self->counts) {
-        Hash_Dec_RefCount(self->counts);
-        self->counts = NULL;
+    if (ivars->counts) {
+        Hash_Dec_RefCount(ivars->counts);
+        ivars->counts = NULL;
     }
-    if (self->null_ords) {
-        Hash_Dec_RefCount(self->null_ords);
-        self->null_ords = NULL;
+    if (ivars->null_ords) {
+        Hash_Dec_RefCount(ivars->null_ords);
+        ivars->null_ords = NULL;
     }
-    if (self->ord_widths) {
-        Hash_Dec_RefCount(self->ord_widths);
-        self->ord_widths = NULL;
+    if (ivars->ord_widths) {
+        Hash_Dec_RefCount(ivars->ord_widths);
+        ivars->ord_widths = NULL;
     }
 }
 
 void
 DefSortReader_destroy(DefaultSortReader *self) {
-    DECREF(self->caches);
-    DECREF(self->counts);
-    DECREF(self->null_ords);
-    DECREF(self->ord_widths);
+    DefaultSortReaderIVARS *const ivars = DefSortReader_IVARS(self);
+    DECREF(ivars->caches);
+    DECREF(ivars->counts);
+    DECREF(ivars->null_ords);
+    DECREF(ivars->ord_widths);
     SUPER_DESTROY(self, DEFAULTSORTREADER);
 }
 
@@ -155,8 +156,10 @@ S_calc_ord_width(int32_t cardinality) {
 
 static SortCache*
 S_lazy_init_sort_cache(DefaultSortReader *self, const CharBuf *field) {
+    DefaultSortReaderIVARS *const ivars = DefSortReader_IVARS(self);
+
     // See if we have any values.
-    Obj *count_obj = Hash_Fetch(self->counts, (Obj*)field);
+    Obj *count_obj = Hash_Fetch(ivars->counts, (Obj*)field);
     int32_t count = count_obj ? (int32_t)Obj_To_I64(count_obj) : 0;
     if (!count) { return NULL; }
 
@@ -203,9 +206,9 @@ S_lazy_init_sort_cache(DefaultSortReader *self, const CharBuf *field) {
     }
     DECREF(path);
 
-    Obj     *null_ord_obj = Hash_Fetch(self->null_ords, (Obj*)field);
+    Obj     *null_ord_obj = Hash_Fetch(ivars->null_ords, (Obj*)field);
     int32_t  null_ord = null_ord_obj ? (int32_t)Obj_To_I64(null_ord_obj) : -1;
-    Obj     *ord_width_obj = Hash_Fetch(self->ord_widths, (Obj*)field);
+    Obj     *ord_width_obj = Hash_Fetch(ivars->ord_widths, (Obj*)field);
     int32_t  ord_width = ord_width_obj
                          ? (int32_t)Obj_To_I64(ord_width_obj)
                          : S_calc_ord_width(count);
@@ -241,9 +244,9 @@ S_lazy_init_sort_cache(DefaultSortReader *self, const CharBuf *field) {
         default:
             THROW(ERR, "No SortCache class for %o", type);
     }
-    Hash_Store(self->caches, (Obj*)field, (Obj*)cache);
+    Hash_Store(ivars->caches, (Obj*)field, (Obj*)cache);
 
-    if (self->format == 2) { // bug compatibility
+    if (ivars->format == 2) { // bug compatibility
         SortCache_Set_Native_Ords(cache, true);
     }
 
@@ -259,7 +262,8 @@ DefSortReader_fetch_sort_cache(DefaultSortReader *self, const CharBuf *field) {
     SortCache *cache = NULL;
 
     if (field) {
-        cache = (SortCache*)Hash_Fetch(self->caches, (Obj*)field);
+        DefaultSortReaderIVARS *const ivars = DefSortReader_IVARS(self);
+        cache = (SortCache*)Hash_Fetch(ivars->caches, (Obj*)field);
         if (!cache) {
             cache = S_lazy_init_sort_cache(self, field);
         }

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/SortWriter.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/SortWriter.c b/core/Lucy/Index/SortWriter.c
index fedde9a..28a88b7 100644
--- a/core/Lucy/Index/SortWriter.c
+++ b/core/Lucy/Index/SortWriter.c
@@ -52,32 +52,34 @@ SortWriter_init(SortWriter *self, Schema *schema, Snapshot *snapshot,
                 Segment *segment, PolyReader *polyreader) {
     uint32_t field_max = Schema_Num_Fields(schema) + 1;
     DataWriter_init((DataWriter*)self, schema, snapshot, segment, polyreader);
+    SortWriterIVARS *const ivars = SortWriter_IVARS(self);
 
     // Init.
-    self->field_writers   = VA_new(field_max);
-    self->counts          = Hash_new(0);
-    self->null_ords       = Hash_new(0);
-    self->ord_widths      = Hash_new(0);
-    self->temp_ord_out    = NULL;
-    self->temp_ix_out     = NULL;
-    self->temp_dat_out    = NULL;
-    self->mem_pool        = MemPool_new(0);
-    self->mem_thresh      = default_mem_thresh;
-    self->flush_at_finish = false;
+    ivars->field_writers   = VA_new(field_max);
+    ivars->counts          = Hash_new(0);
+    ivars->null_ords       = Hash_new(0);
+    ivars->ord_widths      = Hash_new(0);
+    ivars->temp_ord_out    = NULL;
+    ivars->temp_ix_out     = NULL;
+    ivars->temp_dat_out    = NULL;
+    ivars->mem_pool        = MemPool_new(0);
+    ivars->mem_thresh      = default_mem_thresh;
+    ivars->flush_at_finish = false;
 
     return self;
 }
 
 void
 SortWriter_destroy(SortWriter *self) {
-    DECREF(self->field_writers);
-    DECREF(self->counts);
-    DECREF(self->null_ords);
-    DECREF(self->ord_widths);
-    DECREF(self->temp_ord_out);
-    DECREF(self->temp_ix_out);
-    DECREF(self->temp_dat_out);
-    DECREF(self->mem_pool);
+    SortWriterIVARS *const ivars = SortWriter_IVARS(self);
+    DECREF(ivars->field_writers);
+    DECREF(ivars->counts);
+    DECREF(ivars->null_ords);
+    DECREF(ivars->ord_widths);
+    DECREF(ivars->temp_ord_out);
+    DECREF(ivars->temp_ix_out);
+    DECREF(ivars->temp_dat_out);
+    DECREF(ivars->mem_pool);
     SUPER_DESTROY(self, SORTWRITER);
 }
 
@@ -88,42 +90,44 @@ SortWriter_set_default_mem_thresh(size_t mem_thresh) {
 
 static SortFieldWriter*
 S_lazy_init_field_writer(SortWriter *self, int32_t field_num) {
+    SortWriterIVARS *const ivars = SortWriter_IVARS(self);
+
     SortFieldWriter *field_writer
-        = (SortFieldWriter*)VA_Fetch(self->field_writers, field_num);
+        = (SortFieldWriter*)VA_Fetch(ivars->field_writers, field_num);
     if (!field_writer) {
 
         // Open temp files.
-        if (!self->temp_ord_out) {
-            Folder  *folder   = self->folder;
-            CharBuf *seg_name = Seg_Get_Name(self->segment);
+        if (!ivars->temp_ord_out) {
+            Folder  *folder   = ivars->folder;
+            CharBuf *seg_name = Seg_Get_Name(ivars->segment);
             CharBuf *path     = CB_newf("%o/sort_ord_temp", seg_name);
-            self->temp_ord_out = Folder_Open_Out(folder, path);
-            if (!self->temp_ord_out) {
+            ivars->temp_ord_out = Folder_Open_Out(folder, path);
+            if (!ivars->temp_ord_out) {
                 DECREF(path);
                 RETHROW(INCREF(Err_get_error()));
             }
             CB_setf(path, "%o/sort_ix_temp", seg_name);
-            self->temp_ix_out = Folder_Open_Out(folder, path);
-            if (!self->temp_ix_out) {
+            ivars->temp_ix_out = Folder_Open_Out(folder, path);
+            if (!ivars->temp_ix_out) {
                 DECREF(path);
                 RETHROW(INCREF(Err_get_error()));
             }
             CB_setf(path, "%o/sort_dat_temp", seg_name);
-            self->temp_dat_out = Folder_Open_Out(folder, path);
-            if (!self->temp_dat_out) {
+            ivars->temp_dat_out = Folder_Open_Out(folder, path);
+            if (!ivars->temp_dat_out) {
                 DECREF(path);
                 RETHROW(INCREF(Err_get_error()));
             }
             DECREF(path);
         }
 
-        CharBuf *field = Seg_Field_Name(self->segment, field_num);
+        CharBuf *field = Seg_Field_Name(ivars->segment, field_num);
         field_writer
-            = SortFieldWriter_new(self->schema, self->snapshot, self->segment,
-                                  self->polyreader, field, self->mem_pool,
-                                  self->mem_thresh, self->temp_ord_out,
-                                  self->temp_ix_out, self->temp_dat_out);
-        VA_Store(self->field_writers, field_num, (Obj*)field_writer);
+            = SortFieldWriter_new(ivars->schema, ivars->snapshot, ivars->segment,
+                                  ivars->polyreader, field, ivars->mem_pool,
+                                  ivars->mem_thresh, ivars->temp_ord_out,
+                                  ivars->temp_ix_out, ivars->temp_dat_out);
+        VA_Store(ivars->field_writers, field_num, (Obj*)field_writer);
     }
     return field_writer;
 }
@@ -131,6 +135,7 @@ S_lazy_init_field_writer(SortWriter *self, int32_t field_num) {
 void
 SortWriter_add_inverted_doc(SortWriter *self, Inverter *inverter,
                             int32_t doc_id) {
+    SortWriterIVARS *const ivars = SortWriter_IVARS(self);
     int32_t field_num;
 
     Inverter_Iterate(inverter);
@@ -146,21 +151,22 @@ SortWriter_add_inverted_doc(SortWriter *self, Inverter *inverter,
 
     // If our SortFieldWriters have collectively passed the memory threshold,
     // flush all of them, then release all unique values with a single action.
-    if (MemPool_Get_Consumed(self->mem_pool) > self->mem_thresh) {
-        for (uint32_t i = 0; i < VA_Get_Size(self->field_writers); i++) {
+    if (MemPool_Get_Consumed(ivars->mem_pool) > ivars->mem_thresh) {
+        for (uint32_t i = 0; i < VA_Get_Size(ivars->field_writers); i++) {
             SortFieldWriter *const field_writer
-                = (SortFieldWriter*)VA_Fetch(self->field_writers, i);
+                = (SortFieldWriter*)VA_Fetch(ivars->field_writers, i);
             if (field_writer) { SortFieldWriter_Flush(field_writer); }
         }
-        MemPool_Release_All(self->mem_pool);
-        self->flush_at_finish = true;
+        MemPool_Release_All(ivars->mem_pool);
+        ivars->flush_at_finish = true;
     }
 }
 
 void
 SortWriter_add_segment(SortWriter *self, SegReader *reader,
                        I32Array *doc_map) {
-    VArray *fields = Schema_All_Fields(self->schema);
+    SortWriterIVARS *const ivars = SortWriter_IVARS(self);
+    VArray *fields = Schema_All_Fields(ivars->schema);
 
     // Proceed field-at-a-time, rather than doc-at-a-time.
     for (uint32_t i = 0, max = VA_Get_Size(fields); i < max; i++) {
@@ -171,11 +177,11 @@ SortWriter_add_segment(SortWriter *self, SegReader *reader,
                            ? SortReader_Fetch_Sort_Cache(sort_reader, field)
                            : NULL;
         if (cache) {
-            int32_t field_num = Seg_Field_Num(self->segment, field);
+            int32_t field_num = Seg_Field_Num(ivars->segment, field);
             SortFieldWriter *field_writer
                 = S_lazy_init_field_writer(self, field_num);
             SortFieldWriter_Add_Segment(field_writer, reader, doc_map, cache);
-            self->flush_at_finish = true;
+            ivars->flush_at_finish = true;
         }
     }
 
@@ -184,14 +190,15 @@ SortWriter_add_segment(SortWriter *self, SegReader *reader,
 
 void
 SortWriter_finish(SortWriter *self) {
-    VArray *const field_writers = self->field_writers;
+    SortWriterIVARS *const ivars = SortWriter_IVARS(self);
+    VArray *const field_writers = ivars->field_writers;
 
     // If we have no data, bail out.
-    if (!self->temp_ord_out) { return; }
+    if (!ivars->temp_ord_out) { return; }
 
     // If we've either flushed or added segments, flush everything so that any
     // one field can use the entire margin up to mem_thresh.
-    if (self->flush_at_finish) {
+    if (ivars->flush_at_finish) {
         for (uint32_t i = 1, max = VA_Get_Size(field_writers); i < max; i++) {
             SortFieldWriter *field_writer
                 = (SortFieldWriter*)VA_Fetch(field_writers, i);
@@ -202,26 +209,26 @@ SortWriter_finish(SortWriter *self) {
     }
 
     // Close down temp streams.
-    OutStream_Close(self->temp_ord_out);
-    OutStream_Close(self->temp_ix_out);
-    OutStream_Close(self->temp_dat_out);
+    OutStream_Close(ivars->temp_ord_out);
+    OutStream_Close(ivars->temp_ix_out);
+    OutStream_Close(ivars->temp_dat_out);
 
     for (uint32_t i = 1, max = VA_Get_Size(field_writers); i < max; i++) {
         SortFieldWriter *field_writer
             = (SortFieldWriter*)VA_Delete(field_writers, i);
         if (field_writer) {
-            CharBuf *field = Seg_Field_Name(self->segment, i);
+            CharBuf *field = Seg_Field_Name(ivars->segment, i);
             SortFieldWriter_Flip(field_writer);
             int32_t count = SortFieldWriter_Finish(field_writer);
-            Hash_Store(self->counts, (Obj*)field,
+            Hash_Store(ivars->counts, (Obj*)field,
                        (Obj*)CB_newf("%i32", count));
             int32_t null_ord = SortFieldWriter_Get_Null_Ord(field_writer);
             if (null_ord != -1) {
-                Hash_Store(self->null_ords, (Obj*)field,
+                Hash_Store(ivars->null_ords, (Obj*)field,
                            (Obj*)CB_newf("%i32", null_ord));
             }
             int32_t ord_width = SortFieldWriter_Get_Ord_Width(field_writer);
-            Hash_Store(self->ord_widths, (Obj*)field,
+            Hash_Store(ivars->ord_widths, (Obj*)field,
                        (Obj*)CB_newf("%i32", ord_width));
         }
 
@@ -230,12 +237,12 @@ SortWriter_finish(SortWriter *self) {
     VA_Clear(field_writers);
 
     // Store metadata.
-    Seg_Store_Metadata_Str(self->segment, "sort", 4,
+    Seg_Store_Metadata_Str(ivars->segment, "sort", 4,
                            (Obj*)SortWriter_Metadata(self));
 
     // Clean up.
-    Folder  *folder   = self->folder;
-    CharBuf *seg_name = Seg_Get_Name(self->segment);
+    Folder  *folder   = ivars->folder;
+    CharBuf *seg_name = Seg_Get_Name(ivars->segment);
     CharBuf *path     = CB_newf("%o/sort_ord_temp", seg_name);
     Folder_Delete(folder, path);
     CB_setf(path, "%o/sort_ix_temp", seg_name);
@@ -247,10 +254,11 @@ SortWriter_finish(SortWriter *self) {
 
 Hash*
 SortWriter_metadata(SortWriter *self) {
+    SortWriterIVARS *const ivars = SortWriter_IVARS(self);
     Hash *const metadata  = DataWriter_metadata((DataWriter*)self);
-    Hash_Store_Str(metadata, "counts", 6, INCREF(self->counts));
-    Hash_Store_Str(metadata, "null_ords", 9, INCREF(self->null_ords));
-    Hash_Store_Str(metadata, "ord_widths", 10, INCREF(self->ord_widths));
+    Hash_Store_Str(metadata, "counts", 6, INCREF(ivars->counts));
+    Hash_Store_Str(metadata, "null_ords", 9, INCREF(ivars->null_ords));
+    Hash_Store_Str(metadata, "ord_widths", 10, INCREF(ivars->ord_widths));
     return metadata;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/TermInfo.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/TermInfo.c b/core/Lucy/Index/TermInfo.c
index ef40da2..b4fc2a9 100644
--- a/core/Lucy/Index/TermInfo.c
+++ b/core/Lucy/Index/TermInfo.c
@@ -28,91 +28,98 @@ TInfo_new(int32_t doc_freq) {
 
 TermInfo*
 TInfo_init(TermInfo *self, int32_t doc_freq) {
-    self->doc_freq      = doc_freq;
-    self->post_filepos  = 0;
-    self->skip_filepos  = 0;
-    self->lex_filepos   = 0;
+    TermInfoIVARS *const ivars = TInfo_IVARS(self);
+    ivars->doc_freq      = doc_freq;
+    ivars->post_filepos  = 0;
+    ivars->skip_filepos  = 0;
+    ivars->lex_filepos   = 0;
     return self;
 }
 
 TermInfo*
 TInfo_clone(TermInfo *self) {
-    TermInfo *twin = TInfo_new(self->doc_freq);
-    twin->post_filepos = self->post_filepos;
-    twin->skip_filepos = self->skip_filepos;
-    twin->lex_filepos  = self->lex_filepos;
+    TermInfoIVARS *const ivars = TInfo_IVARS(self);
+    TermInfo *twin = TInfo_new(ivars->doc_freq);
+    TermInfoIVARS *const twin_ivars = TInfo_IVARS(twin);
+    twin_ivars->post_filepos = ivars->post_filepos;
+    twin_ivars->skip_filepos = ivars->skip_filepos;
+    twin_ivars->lex_filepos  = ivars->lex_filepos;
     return twin;
 }
 
 int32_t
 TInfo_get_doc_freq(TermInfo *self) {
-    return self->doc_freq;
+    return TInfo_IVARS(self)->doc_freq;
 }
 
 int64_t
 TInfo_get_lex_filepos(TermInfo *self) {
-    return self->lex_filepos;
+    return TInfo_IVARS(self)->lex_filepos;
 }
 
 int64_t
 TInfo_get_post_filepos(TermInfo *self) {
-    return self->post_filepos;
+    return TInfo_IVARS(self)->post_filepos;
 }
 
 int64_t
 TInfo_get_skip_filepos(TermInfo *self) {
-    return self->skip_filepos;
+    return TInfo_IVARS(self)->skip_filepos;
 }
 
 void
 TInfo_set_doc_freq(TermInfo *self, int32_t doc_freq) {
-    self->doc_freq = doc_freq;
+    TInfo_IVARS(self)->doc_freq = doc_freq;
 }
 
 void
 TInfo_set_lex_filepos(TermInfo *self, int64_t filepos) {
-    self->lex_filepos = filepos;
+    TInfo_IVARS(self)->lex_filepos = filepos;
 }
 
 void
 TInfo_set_post_filepos(TermInfo *self, int64_t filepos) {
-    self->post_filepos = filepos;
+    TInfo_IVARS(self)->post_filepos = filepos;
 }
 
 void
 TInfo_set_skip_filepos(TermInfo *self, int64_t filepos) {
-    self->skip_filepos = filepos;
+    TInfo_IVARS(self)->skip_filepos = filepos;
 }
 
 // TODO: this should probably be some sort of Dump variant rather than
 // To_String.
 CharBuf*
 TInfo_to_string(TermInfo *self) {
+    TermInfoIVARS *const ivars = TInfo_IVARS(self);
     return CB_newf(
                "doc freq:      %i32\n"
                "post filepos:  %i64\n"
                "skip filepos:  %i64\n"
                "index filepos: %i64",
-               self->doc_freq, self->post_filepos,
-               self->skip_filepos, self->lex_filepos
+               ivars->doc_freq, ivars->post_filepos,
+               ivars->skip_filepos, ivars->lex_filepos
            );
 }
 
 void
 TInfo_mimic(TermInfo *self, Obj *other) {
-    TermInfo *twin = (TermInfo*)CERTIFY(other, TERMINFO);
-    self->doc_freq     = twin->doc_freq;
-    self->post_filepos = twin->post_filepos;
-    self->skip_filepos = twin->skip_filepos;
-    self->lex_filepos  = twin->lex_filepos;
+    CERTIFY(other, TERMINFO);
+    TermInfoIVARS *const ivars = TInfo_IVARS(self);
+    TermInfoIVARS *const ovars = TInfo_IVARS((TermInfo*)other);
+    ivars->doc_freq     = ovars->doc_freq;
+    ivars->post_filepos = ovars->post_filepos;
+    ivars->skip_filepos = ovars->skip_filepos;
+    ivars->lex_filepos  = ovars->lex_filepos;
 }
 
 void
 TInfo_reset(TermInfo *self) {
-    self->doc_freq      = 0;
-    self->post_filepos  = 0;
-    self->skip_filepos  = 0;
-    self->lex_filepos   = 0;
+    TermInfoIVARS *const ivars = TInfo_IVARS(self);
+    ivars->doc_freq      = 0;
+    ivars->post_filepos  = 0;
+    ivars->skip_filepos  = 0;
+    ivars->lex_filepos   = 0;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/TermStepper.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/TermStepper.c b/core/Lucy/Index/TermStepper.c
index b78030e..466d7da 100644
--- a/core/Lucy/Index/TermStepper.c
+++ b/core/Lucy/Index/TermStepper.c
@@ -26,31 +26,35 @@
 TermStepper*
 TermStepper_init(TermStepper *self) {
     Stepper_init((Stepper*)self);
-    self->value = NULL;
+    TermStepperIVARS *const ivars = TermStepper_IVARS(self);
+    ivars->value = NULL;
     return self;
 }
 
 void
 TermStepper_destroy(TermStepper *self) {
-    DECREF(self->value);
+    TermStepperIVARS *const ivars = TermStepper_IVARS(self);
+    DECREF(ivars->value);
     SUPER_DESTROY(self, TERMSTEPPER);
 }
 
 void
 TermStepper_reset(TermStepper *self) {
-    DECREF(self->value);
-    self->value = NULL;
+    TermStepperIVARS *const ivars = TermStepper_IVARS(self);
+    DECREF(ivars->value);
+    ivars->value = NULL;
 }
 
 Obj*
 TermStepper_get_value(TermStepper *self) {
-    return self->value;
+    return TermStepper_IVARS(self)->value;
 }
 
 void
 TermStepper_set_value(TermStepper *self, Obj *value) {
-    DECREF(self->value);
-    self->value = value ? INCREF(value) : NULL;
+    TermStepperIVARS *const ivars = TermStepper_IVARS(self);
+    DECREF(ivars->value);
+    ivars->value = value ? INCREF(value) : NULL;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/TermVector.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/TermVector.c b/core/Lucy/Index/TermVector.c
index 4c3216b..4b0ee04 100644
--- a/core/Lucy/Index/TermVector.c
+++ b/core/Lucy/Index/TermVector.c
@@ -33,18 +33,20 @@ TV_new(const CharBuf *field, const CharBuf *text, I32Array *positions,
 TermVector*
 TV_init(TermVector *self, const CharBuf *field, const CharBuf *text,
         I32Array *positions, I32Array *start_offsets, I32Array *end_offsets) {
+    TermVectorIVARS *const ivars = TV_IVARS(self);
+
     // Assign.
-    self->field          = CB_Clone(field);
-    self->text           = CB_Clone(text);
-    self->num_pos        = I32Arr_Get_Size(positions);
-    self->positions      = (I32Array*)INCREF(positions);
-    self->start_offsets  = (I32Array*)INCREF(start_offsets);
-    self->end_offsets    = (I32Array*)INCREF(end_offsets);
-
-    if (I32Arr_Get_Size(start_offsets) != self->num_pos
-        || I32Arr_Get_Size(end_offsets) != self->num_pos
+    ivars->field          = CB_Clone(field);
+    ivars->text           = CB_Clone(text);
+    ivars->num_pos        = I32Arr_Get_Size(positions);
+    ivars->positions      = (I32Array*)INCREF(positions);
+    ivars->start_offsets  = (I32Array*)INCREF(start_offsets);
+    ivars->end_offsets    = (I32Array*)INCREF(end_offsets);
+
+    if (I32Arr_Get_Size(start_offsets) != ivars->num_pos
+        || I32Arr_Get_Size(end_offsets) != ivars->num_pos
        ) {
-        THROW(ERR, "Unbalanced arrays: %u32 %u32 %u32", self->num_pos,
+        THROW(ERR, "Unbalanced arrays: %u32 %u32 %u32", ivars->num_pos,
               I32Arr_Get_Size(start_offsets), I32Arr_Get_Size(end_offsets));
     }
 
@@ -53,40 +55,42 @@ TV_init(TermVector *self, const CharBuf *field, const CharBuf *text,
 
 void
 TV_destroy(TermVector *self) {
-    DECREF(self->field);
-    DECREF(self->text);
-    DECREF(self->positions);
-    DECREF(self->start_offsets);
-    DECREF(self->end_offsets);
+    TermVectorIVARS *const ivars = TV_IVARS(self);
+    DECREF(ivars->field);
+    DECREF(ivars->text);
+    DECREF(ivars->positions);
+    DECREF(ivars->start_offsets);
+    DECREF(ivars->end_offsets);
     SUPER_DESTROY(self, TERMVECTOR);
 }
 
 I32Array*
 TV_get_positions(TermVector *self) {
-    return self->positions;
+    return TV_IVARS(self)->positions;
 }
 
 I32Array*
 TV_get_start_offsets(TermVector *self) {
-    return self->start_offsets;
+    return TV_IVARS(self)->start_offsets;
 }
 
 I32Array*
 TV_get_end_offsets(TermVector *self) {
-    return self->end_offsets;
+    return TV_IVARS(self)->end_offsets;
 }
 
 void
 TV_serialize(TermVector *self, OutStream *target) {
-    int32_t *posits = self->positions->ints;
-    int32_t *starts = self->start_offsets->ints;
-    int32_t *ends   = self->start_offsets->ints;
+    TermVectorIVARS *const ivars = TV_IVARS(self);
+    int32_t *posits = I32Arr_IVARS(ivars->positions)->ints;
+    int32_t *starts = I32Arr_IVARS(ivars->start_offsets)->ints;
+    int32_t *ends   = I32Arr_IVARS(ivars->start_offsets)->ints;
 
-    Freezer_serialize_charbuf(self->field, target);
-    Freezer_serialize_charbuf(self->text, target);
-    OutStream_Write_C32(target, self->num_pos);
+    Freezer_serialize_charbuf(ivars->field, target);
+    Freezer_serialize_charbuf(ivars->text, target);
+    OutStream_Write_C32(target, ivars->num_pos);
 
-    for (uint32_t i = 0; i < self->num_pos; i++) {
+    for (uint32_t i = 0; i < ivars->num_pos; i++) {
         OutStream_Write_C32(target, posits[i]);
         OutStream_Write_C32(target, starts[i]);
         OutStream_Write_C32(target, ends[i]);
@@ -125,21 +129,20 @@ TV_deserialize(TermVector *self, InStream *instream) {
 
 bool
 TV_equals(TermVector *self, Obj *other) {
-    TermVector *const twin = (TermVector*)other;
-    int32_t *const posits       = self->positions->ints;
-    int32_t *const starts       = self->start_offsets->ints;
-    int32_t *const ends         = self->start_offsets->ints;
-    int32_t *const other_posits = twin->positions->ints;
-    int32_t *const other_starts = twin->start_offsets->ints;
-    int32_t *const other_ends   = twin->start_offsets->ints;
-
-    if (twin == self) { return true; }
-
-    if (!CB_Equals(self->field, (Obj*)twin->field)) { return false; }
-    if (!CB_Equals(self->text, (Obj*)twin->text))   { return false; }
-    if (self->num_pos != twin->num_pos)             { return false; }
-
-    for (uint32_t i = 0; i < self->num_pos; i++) {
+    if ((TermVector*)other == self) { return true; }
+    TermVectorIVARS *const ivars = TV_IVARS(self);
+    TermVectorIVARS *const ovars = TV_IVARS((TermVector*)other);
+    if (!CB_Equals(ivars->field, (Obj*)ovars->field)) { return false; }
+    if (!CB_Equals(ivars->text, (Obj*)ovars->text))   { return false; }
+    if (ivars->num_pos != ovars->num_pos)             { return false; }
+
+    int32_t *const posits       = I32Arr_IVARS(ivars->positions)->ints;
+    int32_t *const starts       = I32Arr_IVARS(ivars->start_offsets)->ints;
+    int32_t *const ends         = I32Arr_IVARS(ivars->start_offsets)->ints;
+    int32_t *const other_posits = I32Arr_IVARS(ovars->positions)->ints;
+    int32_t *const other_starts = I32Arr_IVARS(ovars->start_offsets)->ints;
+    int32_t *const other_ends   = I32Arr_IVARS(ovars->start_offsets)->ints;
+    for (uint32_t i = 0; i < ivars->num_pos; i++) {
         if (posits[i] != other_posits[i]) { return false; }
         if (starts[i] != other_starts[i]) { return false; }
         if (ends[i]   != other_ends[i])   { return false; }

http://git-wip-us.apache.org/repos/asf/lucy/blob/965fdb2a/core/Lucy/Index/ZombieKeyedHash.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Index/ZombieKeyedHash.c b/core/Lucy/Index/ZombieKeyedHash.c
index a69a5a7..512e2e5 100644
--- a/core/Lucy/Index/ZombieKeyedHash.c
+++ b/core/Lucy/Index/ZombieKeyedHash.c
@@ -26,33 +26,36 @@ ZKHash_new(MemoryPool *memory_pool, uint8_t primitive_id) {
     ZombieKeyedHash *self
         = (ZombieKeyedHash*)VTable_Make_Obj(ZOMBIEKEYEDHASH);
     Hash_init((Hash*)self, 0);
-    self->mem_pool = (MemoryPool*)INCREF(memory_pool);
-    self->prim_id  = primitive_id;
+    ZombieKeyedHashIVARS *const ivars = ZKHash_IVARS(self);
+    ivars->mem_pool = (MemoryPool*)INCREF(memory_pool);
+    ivars->prim_id  = primitive_id;
     return self;
 }
 
 void
 ZKHash_destroy(ZombieKeyedHash *self) {
-    DECREF(self->mem_pool);
+    ZombieKeyedHashIVARS *const ivars = ZKHash_IVARS(self);
+    DECREF(ivars->mem_pool);
     SUPER_DESTROY(self, ZOMBIEKEYEDHASH);
 }
 
 Obj*
 ZKHash_make_key(ZombieKeyedHash *self, Obj *key, int32_t hash_sum) {
+    ZombieKeyedHashIVARS *const ivars = ZKHash_IVARS(self);
     UNUSED_VAR(hash_sum);
     Obj *retval = NULL;
-    switch (self->prim_id & FType_PRIMITIVE_ID_MASK) {
+    switch (ivars->prim_id & FType_PRIMITIVE_ID_MASK) {
         case FType_TEXT: {
                 CharBuf *source = (CharBuf*)key;
                 size_t size = ZCB_size() + CB_Get_Size(source) + 1;
-                void *allocation = MemPool_grab(self->mem_pool, size);
+                void *allocation = MemPool_grab(ivars->mem_pool, size);
                 retval = (Obj*)ZCB_newf(allocation, size, "%o", source);
             }
             break;
         case FType_INT32: {
                 size_t size = VTable_Get_Obj_Alloc_Size(INTEGER32);
                 Integer32 *copy
-                    = (Integer32*)MemPool_grab(self->mem_pool, size);
+                    = (Integer32*)MemPool_grab(ivars->mem_pool, size);
                 VTable_Init_Obj(INTEGER32, copy);
                 Int32_init(copy, 0);
                 Int32_Mimic(copy, key);
@@ -62,7 +65,7 @@ ZKHash_make_key(ZombieKeyedHash *self, Obj *key, int32_t hash_sum) {
         case FType_INT64: {
                 size_t size = VTable_Get_Obj_Alloc_Size(INTEGER64);
                 Integer64 *copy
-                    = (Integer64*)MemPool_Grab(self->mem_pool, size);
+                    = (Integer64*)MemPool_Grab(ivars->mem_pool, size);
                 VTable_Init_Obj(INTEGER64, copy);
                 Int64_init(copy, 0);
                 Int64_Mimic(copy, key);
@@ -71,7 +74,7 @@ ZKHash_make_key(ZombieKeyedHash *self, Obj *key, int32_t hash_sum) {
             break;
         case FType_FLOAT32: {
                 size_t size = VTable_Get_Obj_Alloc_Size(FLOAT32);
-                Float32 *copy = (Float32*)MemPool_Grab(self->mem_pool, size);
+                Float32 *copy = (Float32*)MemPool_Grab(ivars->mem_pool, size);
                 VTable_Init_Obj(FLOAT32, copy);
                 Float32_init(copy, 0);
                 Float32_Mimic(copy, key);
@@ -80,7 +83,7 @@ ZKHash_make_key(ZombieKeyedHash *self, Obj *key, int32_t hash_sum) {
             break;
         case FType_FLOAT64: {
                 size_t size = VTable_Get_Obj_Alloc_Size(FLOAT64);
-                Float64 *copy = (Float64*)MemPool_Grab(self->mem_pool, size);
+                Float64 *copy = (Float64*)MemPool_Grab(ivars->mem_pool, size);
                 VTable_Init_Obj(FLOAT64, copy);
                 Float64_init(copy, 0);
                 Float64_Mimic(copy, key);
@@ -88,7 +91,7 @@ ZKHash_make_key(ZombieKeyedHash *self, Obj *key, int32_t hash_sum) {
             }
             break;
         default:
-            THROW(ERR, "Unrecognized primitive id: %i8", self->prim_id);
+            THROW(ERR, "Unrecognized primitive id: %i8", ivars->prim_id);
     }
 
     /* FIXME This is a hack.  It will leak memory if host objects get cached,


[lucy-commits] [19/34] git commit: refs/heads/master - Fix prefix capitalization bug.

Posted by ma...@apache.org.
Fix prefix capitalization bug.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/ff0ec8d5
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/ff0ec8d5
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/ff0ec8d5

Branch: refs/heads/master
Commit: ff0ec8d5ce189d204e015772c30994bd73457d5d
Parents: 25f4f65
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Mon Jul 1 08:41:38 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 16:08:43 2013 -0700

----------------------------------------------------------------------
 clownfish/compiler/src/CFCBindClass.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/ff0ec8d5/clownfish/compiler/src/CFCBindClass.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCBindClass.c b/clownfish/compiler/src/CFCBindClass.c
index a1b3ac6..33b4d71 100644
--- a/clownfish/compiler/src/CFCBindClass.c
+++ b/clownfish/compiler/src/CFCBindClass.c
@@ -156,7 +156,7 @@ S_ivars_hack(CFCBindClass *self) {
     const char *full_struct = CFCClass_full_struct_sym(self->client);
     const char *full_ivars  = CFCClass_full_ivars_name(self->client);
     const char *short_ivars = CFCClass_short_ivars_name(self->client);
-    const char *prefix      = CFCClass_get_PREFIX(self->client);
+    const char *prefix      = CFCClass_get_prefix(self->client);
     const char *class_cnick = CFCClass_get_cnick(self->client);
     char pattern[] =
         "typedef struct %s %s;\n"


[lucy-commits] [16/34] Migrate Lucy's store classes to IVARS.

Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/lucy/blob/d04580a1/core/Lucy/Store/LockFactory.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/LockFactory.c b/core/Lucy/Store/LockFactory.c
index 2f1f362..4bcae61 100644
--- a/core/Lucy/Store/LockFactory.c
+++ b/core/Lucy/Store/LockFactory.c
@@ -34,29 +34,33 @@ LockFact_new(Folder *folder, const CharBuf *host) {
 
 LockFactory*
 LockFact_init(LockFactory *self, Folder *folder, const CharBuf *host) {
-    self->folder    = (Folder*)INCREF(folder);
-    self->host      = CB_Clone(host);
+    LockFactoryIVARS *const ivars = LockFact_IVARS(self);
+    ivars->folder    = (Folder*)INCREF(folder);
+    ivars->host      = CB_Clone(host);
     return self;
 }
 
 void
 LockFact_destroy(LockFactory *self) {
-    DECREF(self->folder);
-    DECREF(self->host);
+    LockFactoryIVARS *const ivars = LockFact_IVARS(self);
+    DECREF(ivars->folder);
+    DECREF(ivars->host);
     SUPER_DESTROY(self, LOCKFACTORY);
 }
 
 Lock*
 LockFact_make_lock(LockFactory *self, const CharBuf *name, int32_t timeout,
                    int32_t interval) {
-    return (Lock*)LFLock_new(self->folder, name, self->host, timeout,
+    LockFactoryIVARS *const ivars = LockFact_IVARS(self);
+    return (Lock*)LFLock_new(ivars->folder, name, ivars->host, timeout,
                              interval);
 }
 
 Lock*
 LockFact_make_shared_lock(LockFactory *self, const CharBuf *name,
                           int32_t timeout, int32_t interval) {
-    return (Lock*)ShLock_new(self->folder, name, self->host, timeout,
+    LockFactoryIVARS *const ivars = LockFact_IVARS(self);
+    return (Lock*)ShLock_new(ivars->folder, name, ivars->host, timeout,
                              interval);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/d04580a1/core/Lucy/Store/OutStream.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/OutStream.c b/core/Lucy/Store/OutStream.c
index 1a38066..b9122c2 100644
--- a/core/Lucy/Store/OutStream.c
+++ b/core/Lucy/Store/OutStream.c
@@ -27,15 +27,16 @@
 
 // Inlined version of OutStream_Write_Bytes.
 static INLINE void
-SI_write_bytes(OutStream *self, const void *bytes, size_t len);
+SI_write_bytes(OutStream *self, OutStreamIVARS *ivars,
+               const void *bytes, size_t len);
 
 // Inlined version of OutStream_Write_C32.
 static INLINE void
-SI_write_c32(OutStream *self, uint32_t value);
+SI_write_c32(OutStream *self, OutStreamIVARS *ivars, uint32_t value);
 
 // Flush content in the buffer to the FileHandle.
 static void
-S_flush(OutStream *self);
+S_flush(OutStream *self, OutStreamIVARS *ivars);
 
 OutStream*
 OutStream_open(Obj *file) {
@@ -45,22 +46,24 @@ OutStream_open(Obj *file) {
 
 OutStream*
 OutStream_do_open(OutStream *self, Obj *file) {
+    OutStreamIVARS *const ivars = OutStream_IVARS(self);
+
     // Init.
-    self->buf         = (char*)MALLOCATE(IO_STREAM_BUF_SIZE);
-    self->buf_start   = 0;
-    self->buf_pos     = 0;
+    ivars->buf         = (char*)MALLOCATE(IO_STREAM_BUF_SIZE);
+    ivars->buf_start   = 0;
+    ivars->buf_pos     = 0;
 
     // Obtain a FileHandle.
     if (Obj_Is_A(file, FILEHANDLE)) {
-        self->file_handle = (FileHandle*)INCREF(file);
+        ivars->file_handle = (FileHandle*)INCREF(file);
     }
     else if (Obj_Is_A(file, RAMFILE)) {
-        self->file_handle
+        ivars->file_handle
             = (FileHandle*)RAMFH_open(NULL, FH_WRITE_ONLY, (RAMFile*)file);
     }
     else if (Obj_Is_A(file, CHARBUF)) {
-        self->file_handle = (FileHandle*)FSFH_open((CharBuf*)file,
-                                                   FH_WRITE_ONLY | FH_CREATE | FH_EXCLUSIVE);
+        ivars->file_handle = (FileHandle*)FSFH_open((CharBuf*)file,
+                                                    FH_WRITE_ONLY | FH_CREATE | FH_EXCLUSIVE);
     }
     else {
         Err_set_error(Err_new(CB_newf("Invalid type for param 'file': '%o'",
@@ -68,39 +71,41 @@ OutStream_do_open(OutStream *self, Obj *file) {
         DECREF(self);
         return NULL;
     }
-    if (!self->file_handle) {
+    if (!ivars->file_handle) {
         ERR_ADD_FRAME(Err_get_error());
         DECREF(self);
         return NULL;
     }
 
     // Derive filepath from FileHandle.
-    self->path = CB_Clone(FH_Get_Path(self->file_handle));
+    ivars->path = CB_Clone(FH_Get_Path(ivars->file_handle));
 
     return self;
 }
 
 void
 OutStream_destroy(OutStream *self) {
-    if (self->file_handle != NULL) {
+    OutStreamIVARS *const ivars = OutStream_IVARS(self);
+    if (ivars->file_handle != NULL) {
         // Inlined flush, ignoring errors.
-        if (self->buf_pos) {
-            FH_Write(self->file_handle, self->buf, self->buf_pos);
+        if (ivars->buf_pos) {
+            FH_Write(ivars->file_handle, ivars->buf, ivars->buf_pos);
         }
-        DECREF(self->file_handle);
+        DECREF(ivars->file_handle);
     }
-    DECREF(self->path);
-    FREEMEM(self->buf);
+    DECREF(ivars->path);
+    FREEMEM(ivars->buf);
     SUPER_DESTROY(self, OUTSTREAM);
 }
 
 CharBuf*
 OutStream_get_path(OutStream *self) {
-    return self->path;
+    return OutStream_IVARS(self)->path;
 }
 
 void
 OutStream_absorb(OutStream *self, InStream *instream) {
+    OutStreamIVARS *const ivars = OutStream_IVARS(self);
     char buf[IO_STREAM_BUF_SIZE];
     int64_t bytes_left = InStream_Length(instream);
 
@@ -115,21 +120,23 @@ OutStream_absorb(OutStream *self, InStream *instream) {
                                        ? (size_t)bytes_left
                                        : IO_STREAM_BUF_SIZE;
         InStream_Read_Bytes(instream, buf, bytes_this_iter);
-        SI_write_bytes(self, buf, bytes_this_iter);
+        SI_write_bytes(self, ivars, buf, bytes_this_iter);
         bytes_left -= bytes_this_iter;
     }
 }
 
 void
 OutStream_grow(OutStream *self, int64_t length) {
-    if (!FH_Grow(self->file_handle, length)) {
+    OutStreamIVARS *const ivars = OutStream_IVARS(self);
+    if (!FH_Grow(ivars->file_handle, length)) {
         RETHROW(INCREF(Err_get_error()));
     }
 }
 
 int64_t
 OutStream_tell(OutStream *self) {
-    return self->buf_start + self->buf_pos;
+    OutStreamIVARS *const ivars = OutStream_IVARS(self);
+    return ivars->buf_start + ivars->buf_pos;
 }
 
 int64_t
@@ -142,19 +149,21 @@ OutStream_align(OutStream *self, int64_t modulus) {
 
 void
 OutStream_flush(OutStream *self) {
-    S_flush(self);
+    OutStreamIVARS *const ivars = OutStream_IVARS(self);
+    S_flush(self, ivars);
 }
 
 static void
-S_flush(OutStream *self) {
-    if (self->file_handle == NULL) {
-        THROW(ERR, "Can't write to a closed OutStream for %o", self->path);
+S_flush(OutStream *self, OutStreamIVARS *ivars) {
+    UNUSED_VAR(self);
+    if (ivars->file_handle == NULL) {
+        THROW(ERR, "Can't write to a closed OutStream for %o", ivars->path);
     }
-    if (!FH_Write(self->file_handle, self->buf, self->buf_pos)) {
+    if (!FH_Write(ivars->file_handle, ivars->buf, ivars->buf_pos)) {
         RETHROW(INCREF(Err_get_error()));
     }
-    self->buf_start += self->buf_pos;
-    self->buf_pos = 0;
+    ivars->buf_start += ivars->buf_pos;
+    ivars->buf_pos = 0;
 }
 
 int64_t
@@ -164,117 +173,122 @@ OutStream_length(OutStream *self) {
 
 void
 OutStream_write_bytes(OutStream *self, const void *bytes, size_t len) {
-    SI_write_bytes(self, bytes, len);
+    SI_write_bytes(self, OutStream_IVARS(self), bytes, len);
 }
 
 static INLINE void
-SI_write_bytes(OutStream *self, const void *bytes, size_t len) {
+SI_write_bytes(OutStream *self, OutStreamIVARS *ivars,
+               const void *bytes, size_t len) {
     // If this data is larger than the buffer size, flush and write.
     if (len >= IO_STREAM_BUF_SIZE) {
-        S_flush(self);
-        if (!FH_Write(self->file_handle, bytes, len)) {
+        S_flush(self, ivars);
+        if (!FH_Write(ivars->file_handle, bytes, len)) {
             RETHROW(INCREF(Err_get_error()));
         }
-        self->buf_start += len;
+        ivars->buf_start += len;
     }
     // If there's not enough room in the buffer, flush then add.
-    else if (self->buf_pos + len >= IO_STREAM_BUF_SIZE) {
-        S_flush(self);
-        memcpy((self->buf + self->buf_pos), bytes, len);
-        self->buf_pos += len;
+    else if (ivars->buf_pos + len >= IO_STREAM_BUF_SIZE) {
+        S_flush(self, ivars);
+        memcpy((ivars->buf + ivars->buf_pos), bytes, len);
+        ivars->buf_pos += len;
     }
     // If there's room, just add these bytes to the buffer.
     else {
-        memcpy((self->buf + self->buf_pos), bytes, len);
-        self->buf_pos += len;
+        memcpy((ivars->buf + ivars->buf_pos), bytes, len);
+        ivars->buf_pos += len;
     }
 }
 
 static INLINE void
-SI_write_u8(OutStream *self, uint8_t value) {
-    if (self->buf_pos >= IO_STREAM_BUF_SIZE) {
-        S_flush(self);
+SI_write_u8(OutStream *self, OutStreamIVARS *ivars, uint8_t value) {
+    if (ivars->buf_pos >= IO_STREAM_BUF_SIZE) {
+        S_flush(self, ivars);
     }
-    self->buf[self->buf_pos++] = (char)value;
+    ivars->buf[ivars->buf_pos++] = (char)value;
 }
 
 void
 OutStream_write_i8(OutStream *self, int8_t value) {
-    SI_write_u8(self, (uint8_t)value);
+    OutStreamIVARS *const ivars = OutStream_IVARS(self);
+    SI_write_u8(self, ivars, (uint8_t)value);
 }
 
 void
 OutStream_write_u8(OutStream *self, uint8_t value) {
-    SI_write_u8(self, value);
+    OutStreamIVARS *const ivars = OutStream_IVARS(self);
+    SI_write_u8(self, ivars, value);
 }
 
 static INLINE void
-SI_write_u32(OutStream *self, uint32_t value) {
+SI_write_u32(OutStream *self, OutStreamIVARS *ivars, uint32_t value) {
 #ifdef BIG_END
-    SI_write_bytes(self, &value, 4);
+    SI_write_bytes(self, ivars, &value, 4);
 #else
     char  buf[4];
     char *buf_copy = buf;
     NumUtil_encode_bigend_u32(value, &buf_copy);
-    SI_write_bytes(self, buf, 4);
+    SI_write_bytes(self, ivars, buf, 4);
 #endif
 }
 
 void
 OutStream_write_i32(OutStream *self, int32_t value) {
-    SI_write_u32(self, (uint32_t)value);
+    SI_write_u32(self, OutStream_IVARS(self), (uint32_t)value);
 }
 
 void
 OutStream_write_u32(OutStream *self, uint32_t value) {
-    SI_write_u32(self, value);
+    SI_write_u32(self, OutStream_IVARS(self), value);
 }
 
 static INLINE void
-SI_write_u64(OutStream *self, uint64_t value) {
+SI_write_u64(OutStream *self, OutStreamIVARS *ivars, uint64_t value) {
 #ifdef BIG_END
-    SI_write_bytes(self, &value, 8);
+    SI_write_bytes(self, ivars, &value, 8);
 #else
     char  buf[sizeof(uint64_t)];
     char *buf_copy = buf;
     NumUtil_encode_bigend_u64(value, &buf_copy);
-    SI_write_bytes(self, buf, sizeof(uint64_t));
+    SI_write_bytes(self, ivars, buf, sizeof(uint64_t));
 #endif
 }
 
 void
 OutStream_write_i64(OutStream *self, int64_t value) {
-    SI_write_u64(self, (uint64_t)value);
+    SI_write_u64(self, OutStream_IVARS(self), (uint64_t)value);
 }
 
 void
 OutStream_write_u64(OutStream *self, uint64_t value) {
-    SI_write_u64(self, value);
+    SI_write_u64(self, OutStream_IVARS(self), value);
 }
 
 void
 OutStream_write_f32(OutStream *self, float value) {
+    OutStreamIVARS *const ivars = OutStream_IVARS(self);
     char  buf[sizeof(float)];
     char *buf_copy = buf;
     NumUtil_encode_bigend_f32(value, &buf_copy);
-    SI_write_bytes(self, buf_copy, sizeof(float));
+    SI_write_bytes(self, ivars, buf_copy, sizeof(float));
 }
 
 void
 OutStream_write_f64(OutStream *self, double value) {
+    OutStreamIVARS *const ivars = OutStream_IVARS(self);
     char  buf[sizeof(double)];
     char *buf_copy = buf;
     NumUtil_encode_bigend_f64(value, &buf_copy);
-    SI_write_bytes(self, buf_copy, sizeof(double));
+    SI_write_bytes(self, ivars, buf_copy, sizeof(double));
 }
 
 void
 OutStream_write_c32(OutStream *self, uint32_t value) {
-    SI_write_c32(self, value);
+    SI_write_c32(self, OutStream_IVARS(self), value);
 }
 
 static INLINE void
-SI_write_c32(OutStream *self, uint32_t value) {
+SI_write_c32(OutStream *self, OutStreamIVARS *ivars, uint32_t value) {
     uint8_t buf[C32_MAX_BYTES];
     uint8_t *ptr = buf + sizeof(buf) - 1;
 
@@ -288,11 +302,12 @@ SI_write_c32(OutStream *self, uint32_t value) {
         value >>= 7;
     }
 
-    SI_write_bytes(self, ptr, (buf + sizeof(buf)) - ptr);
+    SI_write_bytes(self, ivars, ptr, (buf + sizeof(buf)) - ptr);
 }
 
 void
 OutStream_write_c64(OutStream *self, uint64_t value) {
+    OutStreamIVARS *const ivars = OutStream_IVARS(self);
     uint8_t buf[C64_MAX_BYTES];
     uint8_t *ptr = buf + sizeof(buf) - 1;
 
@@ -306,24 +321,26 @@ OutStream_write_c64(OutStream *self, uint64_t value) {
         value >>= 7;
     }
 
-    SI_write_bytes(self, ptr, (buf + sizeof(buf)) - ptr);
+    SI_write_bytes(self, ivars, ptr, (buf + sizeof(buf)) - ptr);
 }
 
 void
 OutStream_write_string(OutStream *self, const char *string, size_t len) {
-    SI_write_c32(self, (uint32_t)len);
-    SI_write_bytes(self, string, len);
+    OutStreamIVARS *const ivars = OutStream_IVARS(self);
+    SI_write_c32(self, ivars, (uint32_t)len);
+    SI_write_bytes(self, ivars, string, len);
 }
 
 void
 OutStream_close(OutStream *self) {
-    if (self->file_handle) {
-        S_flush(self);
-        if (!FH_Close(self->file_handle)) {
+    OutStreamIVARS *const ivars = OutStream_IVARS(self);
+    if (ivars->file_handle) {
+        S_flush(self, ivars);
+        if (!FH_Close(ivars->file_handle)) {
             RETHROW(INCREF(Err_get_error()));
         }
-        DECREF(self->file_handle);
-        self->file_handle = NULL;
+        DECREF(ivars->file_handle);
+        ivars->file_handle = NULL;
     }
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/d04580a1/core/Lucy/Store/RAMDirHandle.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/RAMDirHandle.c b/core/Lucy/Store/RAMDirHandle.c
index 1553895..71f616b 100644
--- a/core/Lucy/Store/RAMDirHandle.c
+++ b/core/Lucy/Store/RAMDirHandle.c
@@ -31,37 +31,40 @@ RAMDH_new(RAMFolder *folder) {
 RAMDirHandle*
 RAMDH_init(RAMDirHandle *self, RAMFolder *folder) {
     DH_init((DirHandle*)self, RAMFolder_Get_Path(folder));
-    self->folder = (RAMFolder*)INCREF(folder);
-    self->elems  = Hash_Keys(self->folder->entries);
-    self->tick   = -1;
+    RAMDirHandleIVARS *const ivars = RAMDH_IVARS(self);
+    ivars->folder = (RAMFolder*)INCREF(folder);
+    ivars->elems  = Hash_Keys(RAMFolder_IVARS(ivars->folder)->entries);
+    ivars->tick   = -1;
     return self;
 }
 
 bool
 RAMDH_close(RAMDirHandle *self) {
-    if (self->elems) {
-        VA_Dec_RefCount(self->elems);
-        self->elems = NULL;
+    RAMDirHandleIVARS *const ivars = RAMDH_IVARS(self);
+    if (ivars->elems) {
+        VA_Dec_RefCount(ivars->elems);
+        ivars->elems = NULL;
     }
-    if (self->folder) {
-        RAMFolder_Dec_RefCount(self->folder);
-        self->folder = NULL;
+    if (ivars->folder) {
+        RAMFolder_Dec_RefCount(ivars->folder);
+        ivars->folder = NULL;
     }
     return true;
 }
 
 bool
 RAMDH_next(RAMDirHandle *self) {
-    if (self->elems) {
-        self->tick++;
-        if (self->tick < (int32_t)VA_Get_Size(self->elems)) {
+    RAMDirHandleIVARS *const ivars = RAMDH_IVARS(self);
+    if (ivars->elems) {
+        ivars->tick++;
+        if (ivars->tick < (int32_t)VA_Get_Size(ivars->elems)) {
             CharBuf *path = (CharBuf*)CERTIFY(
-                                VA_Fetch(self->elems, self->tick), CHARBUF);
-            CB_Mimic(self->entry, (Obj*)path);
+                                VA_Fetch(ivars->elems, ivars->tick), CHARBUF);
+            CB_Mimic(ivars->entry, (Obj*)path);
             return true;
         }
         else {
-            self->tick--;
+            ivars->tick--;
             return false;
         }
     }
@@ -70,10 +73,11 @@ RAMDH_next(RAMDirHandle *self) {
 
 bool
 RAMDH_entry_is_dir(RAMDirHandle *self) {
-    if (self->elems) {
-        CharBuf *name = (CharBuf*)VA_Fetch(self->elems, self->tick);
+    RAMDirHandleIVARS *const ivars = RAMDH_IVARS(self);
+    if (ivars->elems) {
+        CharBuf *name = (CharBuf*)VA_Fetch(ivars->elems, ivars->tick);
         if (name) {
-            return RAMFolder_Local_Is_Directory(self->folder, name);
+            return RAMFolder_Local_Is_Directory(ivars->folder, name);
         }
     }
     return false;

http://git-wip-us.apache.org/repos/asf/lucy/blob/d04580a1/core/Lucy/Store/RAMFile.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/RAMFile.c b/core/Lucy/Store/RAMFile.c
index 3e41a7f..6766c00 100644
--- a/core/Lucy/Store/RAMFile.c
+++ b/core/Lucy/Store/RAMFile.c
@@ -27,30 +27,32 @@ RAMFile_new(ByteBuf *contents, bool read_only) {
 
 RAMFile*
 RAMFile_init(RAMFile *self, ByteBuf *contents, bool read_only) {
-    self->contents = contents ? (ByteBuf*)INCREF(contents) : BB_new(0);
-    self->read_only = read_only;
+    RAMFileIVARS *const ivars = RAMFile_IVARS(self);
+    ivars->contents = contents ? (ByteBuf*)INCREF(contents) : BB_new(0);
+    ivars->read_only = read_only;
     return self;
 }
 
 void
 RAMFile_destroy(RAMFile *self) {
-    DECREF(self->contents);
+    RAMFileIVARS *const ivars = RAMFile_IVARS(self);
+    DECREF(ivars->contents);
     SUPER_DESTROY(self, RAMFILE);
 }
 
 ByteBuf*
 RAMFile_get_contents(RAMFile *self) {
-    return self->contents;
+    return RAMFile_IVARS(self)->contents;
 }
 
 bool
 RAMFile_read_only(RAMFile *self) {
-    return self->read_only;
+    return RAMFile_IVARS(self)->read_only;
 }
 
 void
 RAMFile_set_read_only(RAMFile *self, bool read_only) {
-    self->read_only = read_only;
+    RAMFile_IVARS(self)->read_only = read_only;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/d04580a1/core/Lucy/Store/RAMFileHandle.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/RAMFileHandle.c b/core/Lucy/Store/RAMFileHandle.c
index 828cabe..16f8bc2 100644
--- a/core/Lucy/Store/RAMFileHandle.c
+++ b/core/Lucy/Store/RAMFileHandle.c
@@ -15,8 +15,6 @@
  */
 
 #define C_LUCY_RAMFILEHANDLE
-#define C_LUCY_RAMFILE
-#define C_LUCY_FILEWINDOW
 #include "Lucy/Util/ToolSet.h"
 
 #include "Lucy/Store/RAMFileHandle.h"
@@ -40,6 +38,7 @@ RAMFH_do_open(RAMFileHandle *self, const CharBuf *path, uint32_t flags,
           ? true : false;
 
     FH_do_open((FileHandle*)self, path, flags);
+    RAMFileHandleIVARS *const ivars = RAMFH_IVARS(self);
 
     // Obtain a RAMFile.
     if (file) {
@@ -48,10 +47,10 @@ RAMFH_do_open(RAMFileHandle *self, const CharBuf *path, uint32_t flags,
             DECREF(self);
             return NULL;
         }
-        self->ram_file = (RAMFile*)INCREF(file);
+        ivars->ram_file = (RAMFile*)INCREF(file);
     }
     else if (can_create) {
-        self->ram_file = RAMFile_new(NULL, false);
+        ivars->ram_file = RAMFile_new(NULL, false);
     }
     else {
         Err_set_error(Err_new(CB_newf("Must supply either RAMFile or FH_CREATE | FH_WRITE_ONLY")));
@@ -61,25 +60,29 @@ RAMFH_do_open(RAMFileHandle *self, const CharBuf *path, uint32_t flags,
 
     // Prevent writes to to the RAMFile if FH_READ_ONLY was specified.
     if (flags & FH_READ_ONLY) {
-        RAMFile_Set_Read_Only(self->ram_file, true);
+        RAMFile_Set_Read_Only(ivars->ram_file, true);
     }
 
-    self->len = BB_Get_Size(self->ram_file->contents);
+    ivars->contents = (ByteBuf*)INCREF(RAMFile_Get_Contents(ivars->ram_file));
+    ivars->len      = BB_Get_Size(ivars->contents);
 
     return self;
 }
 
 void
 RAMFH_destroy(RAMFileHandle *self) {
-    DECREF(self->ram_file);
+    RAMFileHandleIVARS *const ivars = RAMFH_IVARS(self);
+    DECREF(ivars->ram_file);
+    DECREF(ivars->contents);
     SUPER_DESTROY(self, RAMFILEHANDLE);
 }
 
 bool
 RAMFH_window(RAMFileHandle *self, FileWindow *window, int64_t offset,
              int64_t len) {
+    RAMFileHandleIVARS *const ivars = RAMFH_IVARS(self);
     int64_t end = offset + len;
-    if (!(self->flags & FH_READ_ONLY)) {
+    if (!(ivars->flags & FH_READ_ONLY)) {
         Err_set_error(Err_new(CB_newf("Can't read from write-only handle")));
         return false;
     }
@@ -88,13 +91,13 @@ RAMFH_window(RAMFileHandle *self, FileWindow *window, int64_t offset,
                                       offset)));
         return false;
     }
-    else if (end > self->len) {
+    else if (end > ivars->len) {
         Err_set_error(Err_new(CB_newf("Tried to read past EOF: offset %i64 + request %i64 > len %i64",
-                                      offset, len, self->len)));
+                                      offset, len, ivars->len)));
         return false;
     }
     else {
-        char *const buf = BB_Get_Buf(self->ram_file->contents) + offset;
+        char *const buf = BB_Get_Buf(ivars->contents) + offset;
         FileWindow_Set_Window(window, buf, offset, len);
         return true;
     }
@@ -109,8 +112,9 @@ RAMFH_release_window(RAMFileHandle *self, FileWindow *window) {
 
 bool
 RAMFH_read(RAMFileHandle *self, char *dest, int64_t offset, size_t len) {
+    RAMFileHandleIVARS *const ivars = RAMFH_IVARS(self);
     int64_t end = offset + len;
-    if (!(self->flags & FH_READ_ONLY)) {
+    if (!(ivars->flags & FH_READ_ONLY)) {
         Err_set_error(Err_new(CB_newf("Can't read from write-only handle")));
         return false;
     }
@@ -119,13 +123,13 @@ RAMFH_read(RAMFileHandle *self, char *dest, int64_t offset, size_t len) {
                                       offset)));
         return false;
     }
-    else if (end > self->len) {
+    else if (end > ivars->len) {
         Err_set_error(Err_new(CB_newf("Attempt to read %u64 bytes starting at %i64 goes past EOF %u64",
-                                      (uint64_t)len, offset, self->len)));
+                                      (uint64_t)len, offset, ivars->len)));
         return false;
     }
     else {
-        char *const source = BB_Get_Buf(self->ram_file->contents) + offset;
+        char *const source = BB_Get_Buf(ivars->contents) + offset;
         memcpy(dest, source, len);
         return true;
     }
@@ -133,41 +137,43 @@ RAMFH_read(RAMFileHandle *self, char *dest, int64_t offset, size_t len) {
 
 bool
 RAMFH_write(RAMFileHandle *self, const void *data, size_t len) {
-    if (self->ram_file->read_only) {
+    RAMFileHandleIVARS *const ivars = RAMFH_IVARS(self);
+    if (ivars->flags & FH_READ_ONLY) {
         Err_set_error(Err_new(CB_newf("Attempt to write to read-only RAMFile")));
         return false;
     }
-    BB_Cat_Bytes(self->ram_file->contents, data, len);
-    self->len += len;
+    BB_Cat_Bytes(ivars->contents, data, len);
+    ivars->len += len;
     return true;
 }
 
 bool
 RAMFH_grow(RAMFileHandle *self, int64_t len) {
+    RAMFileHandleIVARS *const ivars = RAMFH_IVARS(self);
     if (len > INT32_MAX) {
         Err_set_error(Err_new(CB_newf("Can't support RAM files of size %i64 (> %i32)",
                                       len, (int32_t)INT32_MAX)));
         return false;
     }
-    else if (self->ram_file->read_only) {
+    else if (ivars->flags & FH_READ_ONLY) {
         Err_set_error(Err_new(CB_newf("Can't grow read-only RAMFile '%o'",
-                                      self->path)));
+                                      ivars->path)));
         return false;
     }
     else {
-        BB_Grow(self->ram_file->contents, (size_t)len);
+        BB_Grow(ivars->contents, (size_t)len);
         return true;
     }
 }
 
 RAMFile*
 RAMFH_get_file(RAMFileHandle *self) {
-    return self->ram_file;
+    return RAMFH_IVARS(self)->ram_file;
 }
 
 int64_t
 RAMFH_length(RAMFileHandle *self) {
-    return self->len;
+    return RAMFH_IVARS(self)->len;
 }
 
 bool

http://git-wip-us.apache.org/repos/asf/lucy/blob/d04580a1/core/Lucy/Store/RAMFileHandle.cfh
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/RAMFileHandle.cfh b/core/Lucy/Store/RAMFileHandle.cfh
index 956f1b0..6e55f45 100644
--- a/core/Lucy/Store/RAMFileHandle.cfh
+++ b/core/Lucy/Store/RAMFileHandle.cfh
@@ -25,6 +25,7 @@ class Lucy::Store::RAMFileHandle cnick RAMFH
     inherits Lucy::Store::FileHandle {
 
     RAMFile *ram_file;
+    ByteBuf *contents;
     int64_t  len;
 
     inert incremented nullable RAMFileHandle*

http://git-wip-us.apache.org/repos/asf/lucy/blob/d04580a1/core/Lucy/Store/RAMFolder.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/RAMFolder.c b/core/Lucy/Store/RAMFolder.c
index c0d21f0..055ef04 100644
--- a/core/Lucy/Store/RAMFolder.c
+++ b/core/Lucy/Store/RAMFolder.c
@@ -55,14 +55,15 @@ RAMFolder_check(RAMFolder *self) {
 
 bool
 RAMFolder_local_mkdir(RAMFolder *self, const CharBuf *name) {
-    if (Hash_Fetch(self->entries, (Obj*)name)) {
+    RAMFolderIVARS *const ivars = RAMFolder_IVARS(self);
+    if (Hash_Fetch(ivars->entries, (Obj*)name)) {
         Err_set_error(Err_new(CB_newf("Can't MkDir, '%o' already exists",
                                       name)));
         return false;
     }
     else {
         CharBuf *fullpath = S_fullpath(self, name);
-        Hash_Store(self->entries, (Obj*)name,
+        Hash_Store(ivars->entries, (Obj*)name,
                    (Obj*)RAMFolder_new(fullpath));
         DECREF(fullpath);
         return true;
@@ -72,9 +73,10 @@ RAMFolder_local_mkdir(RAMFolder *self, const CharBuf *name) {
 FileHandle*
 RAMFolder_local_open_filehandle(RAMFolder *self, const CharBuf *name,
                                 uint32_t flags) {
+    RAMFolderIVARS *const ivars = RAMFolder_IVARS(self);
     RAMFileHandle *fh;
     CharBuf *fullpath = S_fullpath(self, name);
-    RAMFile *file = (RAMFile*)Hash_Fetch(self->entries, (Obj*)name);
+    RAMFile *file = (RAMFile*)Hash_Fetch(ivars->entries, (Obj*)name);
     bool can_create
         = (flags & (FH_WRITE_ONLY | FH_CREATE)) == (FH_WRITE_ONLY | FH_CREATE)
           ? true : false;
@@ -99,7 +101,7 @@ RAMFolder_local_open_filehandle(RAMFolder *self, const CharBuf *name,
     if (fh) {
         if (!file) {
             file = RAMFH_Get_File(fh);
-            Hash_Store(self->entries, (Obj*)name, INCREF(file));
+            Hash_Store(ivars->entries, (Obj*)name, INCREF(file));
         }
     }
     else {
@@ -121,12 +123,14 @@ RAMFolder_local_open_dir(RAMFolder *self) {
 
 bool
 RAMFolder_local_exists(RAMFolder *self, const CharBuf *name) {
-    return !!Hash_Fetch(self->entries, (Obj*)name);
+    RAMFolderIVARS *const ivars = RAMFolder_IVARS(self);
+    return !!Hash_Fetch(ivars->entries, (Obj*)name);
 }
 
 bool
 RAMFolder_local_is_directory(RAMFolder *self, const CharBuf *name) {
-    Obj *entry = Hash_Fetch(self->entries, (Obj*)name);
+    RAMFolderIVARS *const ivars = RAMFolder_IVARS(self);
+    Obj *entry = Hash_Fetch(ivars->entries, (Obj*)name);
     if (entry && Obj_Is_A(entry, FOLDER)) { return true; }
     return false;
 }
@@ -182,7 +186,8 @@ S_rename_or_hard_link(RAMFolder *self, const CharBuf* from, const CharBuf *to,
     }
 
     // Find the original element.
-    elem = Hash_Fetch(inner_from_folder->entries, (Obj*)from_name);
+    elem = Hash_Fetch(RAMFolder_IVARS(inner_from_folder)->entries,
+                      (Obj*)from_name);
     if (!elem) {
         if (Folder_Is_A(from_folder, COMPOUNDFILEREADER)
             && Folder_Local_Exists(from_folder, (CharBuf*)from_name)
@@ -198,7 +203,8 @@ S_rename_or_hard_link(RAMFolder *self, const CharBuf* from, const CharBuf *to,
 
     // Execute the rename/hard-link.
     if (op == OP_RENAME) {
-        Obj *existing = Hash_Fetch(inner_to_folder->entries, (Obj*)to_name);
+        Obj *existing = Hash_Fetch(RAMFolder_IVARS(inner_to_folder)->entries,
+                                   (Obj*)to_name);
         if (existing) {
             bool conflict = false;
 
@@ -230,8 +236,10 @@ S_rename_or_hard_link(RAMFolder *self, const CharBuf* from, const CharBuf *to,
 
         // Perform the store first, then the delete. Inform Folder objects
         // about the relocation.
-        Hash_Store(inner_to_folder->entries, (Obj*)to_name, INCREF(elem));
-        DECREF(Hash_Delete(inner_from_folder->entries, (Obj*)from_name));
+        Hash_Store(RAMFolder_IVARS(inner_to_folder)->entries,
+                   (Obj*)to_name, INCREF(elem));
+        DECREF(Hash_Delete(RAMFolder_IVARS(inner_from_folder)->entries,
+                           (Obj*)from_name));
         if (Obj_Is_A(elem, FOLDER)) {
             CharBuf *newpath = S_fullpath(inner_to_folder, (CharBuf*)to_name);
             Folder_Set_Path((Folder*)elem, newpath);
@@ -246,14 +254,15 @@ S_rename_or_hard_link(RAMFolder *self, const CharBuf* from, const CharBuf *to,
         }
         else {
             Obj *existing
-                = Hash_Fetch(inner_to_folder->entries, (Obj*)to_name);
+                = Hash_Fetch(RAMFolder_IVARS(inner_to_folder)->entries,
+                             (Obj*)to_name);
             if (existing) {
                 Err_set_error(Err_new(CB_newf("'%o' already exists", to)));
                 return false;
             }
             else {
-                Hash_Store(inner_to_folder->entries, (Obj*)to_name,
-                           INCREF(elem));
+                Hash_Store(RAMFolder_IVARS(inner_to_folder)->entries,
+                           (Obj*)to_name, INCREF(elem));
             }
         }
     }
@@ -292,7 +301,8 @@ RAMFolder_hard_link(RAMFolder *self, const CharBuf *from, const CharBuf *to) {
 
 bool
 RAMFolder_local_delete(RAMFolder *self, const CharBuf *name) {
-    Obj *entry = Hash_Fetch(self->entries, (Obj*)name);
+    RAMFolderIVARS *const ivars = RAMFolder_IVARS(self);
+    Obj *entry = Hash_Fetch(ivars->entries, (Obj*)name);
     if (entry) {
         if (Obj_Is_A(entry, RAMFILE)) {
             ;
@@ -307,7 +317,7 @@ RAMFolder_local_delete(RAMFolder *self, const CharBuf *name) {
             else {
                 inner_folder = (RAMFolder*)CERTIFY(entry, RAMFOLDER);
             }
-            if (Hash_Get_Size(inner_folder->entries)) {
+            if (Hash_Get_Size(RAMFolder_IVARS(inner_folder)->entries)) {
                 // Can't delete non-empty dir.
                 return false;
             }
@@ -315,7 +325,7 @@ RAMFolder_local_delete(RAMFolder *self, const CharBuf *name) {
         else {
             return false;
         }
-        DECREF(Hash_Delete(self->entries, (Obj*)name));
+        DECREF(Hash_Delete(ivars->entries, (Obj*)name));
         return true;
     }
     else {
@@ -325,7 +335,8 @@ RAMFolder_local_delete(RAMFolder *self, const CharBuf *name) {
 
 Folder*
 RAMFolder_local_find_folder(RAMFolder *self, const CharBuf *path) {
-    Folder *local_folder = (Folder*)Hash_Fetch(self->entries, (Obj*)path);
+    RAMFolderIVARS *const ivars = RAMFolder_IVARS(self);
+    Folder *local_folder = (Folder*)Hash_Fetch(ivars->entries, (Obj*)path);
     if (local_folder && Folder_Is_A(local_folder, FOLDER)) {
         return local_folder;
     }
@@ -339,8 +350,9 @@ RAMFolder_close(RAMFolder *self) {
 
 static CharBuf*
 S_fullpath(RAMFolder *self, const CharBuf *path) {
-    if (CB_Get_Size(self->path)) {
-        return CB_newf("%o/%o", self->path, path);
+    RAMFolderIVARS *const ivars = RAMFolder_IVARS(self);
+    if (CB_Get_Size(ivars->path)) {
+        return CB_newf("%o/%o", ivars->path, path);
     }
     else {
         return CB_Clone(path);

http://git-wip-us.apache.org/repos/asf/lucy/blob/d04580a1/core/Lucy/Store/SharedLock.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/SharedLock.c b/core/Lucy/Store/SharedLock.c
index 5e5b2e0..702f9df 100644
--- a/core/Lucy/Store/SharedLock.c
+++ b/core/Lucy/Store/SharedLock.c
@@ -37,10 +37,11 @@ SharedLock*
 ShLock_init(SharedLock *self, Folder *folder, const CharBuf *name,
             const CharBuf *host, int32_t timeout, int32_t interval) {
     LFLock_init((LockFileLock*)self, folder, name, host, timeout, interval);
+    SharedLockIVARS *const ivars = ShLock_IVARS(self);
 
     // Override.
-    DECREF(self->lock_path);
-    self->lock_path = CB_newf("");
+    DECREF(ivars->lock_path);
+    ivars->lock_path = CB_newf("");
 
     return self;
 }
@@ -53,26 +54,27 @@ ShLock_shared(SharedLock *self) {
 
 bool
 ShLock_request(SharedLock *self) {
+    SharedLockIVARS *const ivars = ShLock_IVARS(self);
     uint32_t i = 0;
     ShLock_Request_t super_request
         = SUPER_METHOD_PTR(SHAREDLOCK, Lucy_ShLock_Request);
 
     // Empty lock_path indicates whether this particular instance is locked.
-    if (self->lock_path
-        && !CB_Equals_Str(self->lock_path, "", 0)
-        && Folder_Exists(self->folder, self->lock_path)
+    if (ivars->lock_path
+        && !CB_Equals_Str(ivars->lock_path, "", 0)
+        && Folder_Exists(ivars->folder, ivars->lock_path)
        ) {
         // Don't allow double obtain.
         Err_set_error((Err*)LockErr_new(CB_newf("Lock already obtained via '%o'",
-                                                self->lock_path)));
+                                                ivars->lock_path)));
         return false;
     }
 
-    DECREF(self->lock_path);
-    self->lock_path = CB_new(CB_Get_Size(self->name) + 10);
+    DECREF(ivars->lock_path);
+    ivars->lock_path = CB_new(CB_Get_Size(ivars->name) + 10);
     do {
-        CB_setf(self->lock_path, "locks/%o-%u32.lock", self->name, ++i);
-    } while (Folder_Exists(self->folder, self->lock_path));
+        CB_setf(ivars->lock_path, "locks/%o-%u32.lock", ivars->name, ++i);
+    } while (Folder_Exists(ivars->folder, ivars->lock_path));
 
     bool success = super_request(self);
     if (!success) { ERR_ADD_FRAME(Err_get_error()); }
@@ -81,27 +83,29 @@ ShLock_request(SharedLock *self) {
 
 void
 ShLock_release(SharedLock *self) {
-    if (self->lock_path && !CB_Equals_Str(self->lock_path, "", 0)) {
+    SharedLockIVARS *const ivars = ShLock_IVARS(self);
+    if (ivars->lock_path && !CB_Equals_Str(ivars->lock_path, "", 0)) {
         ShLock_Release_t super_release
             = SUPER_METHOD_PTR(SHAREDLOCK, Lucy_ShLock_Release);
         super_release(self);
 
         // Empty out lock_path.
-        DECREF(self->lock_path);
-        self->lock_path = CB_newf("");
+        DECREF(ivars->lock_path);
+        ivars->lock_path = CB_newf("");
     }
 }
 
 
 void
 ShLock_clear_stale(SharedLock *self) {
+    SharedLockIVARS *const ivars = ShLock_IVARS(self);
     DirHandle *dh;
     CharBuf   *entry;
     CharBuf   *candidate = NULL;
     CharBuf   *lock_dir_name = (CharBuf*)ZCB_WRAP_STR("locks", 5);
 
-    if (Folder_Find_Folder(self->folder, lock_dir_name)) {
-        dh = Folder_Open_Dir(self->folder, lock_dir_name);
+    if (Folder_Find_Folder(ivars->folder, lock_dir_name)) {
+        dh = Folder_Open_Dir(ivars->folder, lock_dir_name);
         if (!dh) { RETHROW(INCREF(Err_get_error())); }
         entry = DH_Get_Entry(dh);
     }
@@ -111,7 +115,7 @@ ShLock_clear_stale(SharedLock *self) {
 
     // Take a stab at any file that begins with our lock name.
     while (DH_Next(dh)) {
-        if (CB_Starts_With(entry, self->name)
+        if (CB_Starts_With(entry, ivars->name)
             && CB_Ends_With_Str(entry, ".lock", 5)
            ) {
             candidate = candidate ? candidate : CB_new(0);
@@ -126,12 +130,13 @@ ShLock_clear_stale(SharedLock *self) {
 
 bool
 ShLock_is_locked(SharedLock *self) {
+    SharedLockIVARS *const ivars = ShLock_IVARS(self);
     DirHandle *dh;
     CharBuf   *entry;
 
     CharBuf *lock_dir_name = (CharBuf*)ZCB_WRAP_STR("locks", 5);
-    if (Folder_Find_Folder(self->folder, lock_dir_name)) {
-        dh = Folder_Open_Dir(self->folder, lock_dir_name);
+    if (Folder_Find_Folder(ivars->folder, lock_dir_name)) {
+        dh = Folder_Open_Dir(ivars->folder, lock_dir_name);
         if (!dh) { RETHROW(INCREF(Err_get_error())); }
         entry = DH_Get_Entry(dh);
     }
@@ -141,7 +146,7 @@ ShLock_is_locked(SharedLock *self) {
 
     while (DH_Next(dh)) {
         // Translation:  $locked = 1 if $entry =~ /^\Q$name-\d+\.lock$/
-        if (CB_Starts_With(entry, self->name)
+        if (CB_Starts_With(entry, ivars->name)
             && CB_Ends_With_Str(entry, ".lock", 5)
            ) {
             ZombieCharBuf *scratch = ZCB_WRAP(entry);
@@ -151,7 +156,7 @@ ShLock_is_locked(SharedLock *self) {
             }
             if (ZCB_Code_Point_From(scratch, 1) == '-') {
                 ZCB_Chop(scratch, 1);
-                if (ZCB_Equals(scratch, (Obj*)self->name)) {
+                if (ZCB_Equals(scratch, (Obj*)ivars->name)) {
                     DECREF(dh);
                     return true;
                 }


[lucy-commits] [15/34] git commit: refs/heads/master - Access FileWindow member vars via getters.

Posted by ma...@apache.org.
Access FileWindow member vars via getters.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/4f7440f8
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/4f7440f8
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/4f7440f8

Branch: refs/heads/master
Commit: 4f7440f81617a182a53d1e7bc363023f4d6c9375
Parents: d04580a
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Sat Jun 29 15:07:37 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 16:08:42 2013 -0700

----------------------------------------------------------------------
 core/Lucy/Store/FSFileHandle.c |  5 +++--
 core/Lucy/Store/FileWindow.c   | 14 ++++++++++++++
 core/Lucy/Store/FileWindow.cfh |  9 +++++++++
 core/Lucy/Store/InStream.c     | 25 +++++++++++++++----------
 4 files changed, 41 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/4f7440f8/core/Lucy/Store/FSFileHandle.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/FSFileHandle.c b/core/Lucy/Store/FSFileHandle.c
index 4074a75..ac523fa 100644
--- a/core/Lucy/Store/FSFileHandle.c
+++ b/core/Lucy/Store/FSFileHandle.c
@@ -15,7 +15,6 @@
  */
 
 #define C_LUCY_FSFILEHANDLE
-#define C_LUCY_FILEWINDOW
 #include "Lucy/Util/ToolSet.h"
 
 #include <errno.h>
@@ -313,7 +312,9 @@ SI_window(FSFileHandle *self, FSFileHandleIVARS *ivars, FileWindow *window,
 
 bool
 FSFH_release_window(FSFileHandle *self, FileWindow *window) {
-    if (!SI_unmap(self, window->buf, window->len)) { return false; }
+    char *buf = FileWindow_Get_Buf(window);
+    int64_t len = FileWindow_Get_Len(window);
+    if (!SI_unmap(self, buf, len)) { return false; }
     FileWindow_Set_Window(window, NULL, 0, 0);
     return true;
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/4f7440f8/core/Lucy/Store/FileWindow.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/FileWindow.c b/core/Lucy/Store/FileWindow.c
index 067c6a8..a410931 100644
--- a/core/Lucy/Store/FileWindow.c
+++ b/core/Lucy/Store/FileWindow.c
@@ -51,4 +51,18 @@ FileWindow_set_window(FileWindow *self, char *buf, int64_t offset,
     ivars->len    = len;
 }
 
+char*
+FileWindow_get_buf(FileWindow *self) {
+    return FileWindow_IVARS(self)->buf;
+}
+
+int64_t
+FileWindow_get_offset(FileWindow *self) {
+    return FileWindow_IVARS(self)->offset;
+}
+
+int64_t
+FileWindow_get_len(FileWindow *self) {
+    return FileWindow_IVARS(self)->len;
+}
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/4f7440f8/core/Lucy/Store/FileWindow.cfh
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/FileWindow.cfh b/core/Lucy/Store/FileWindow.cfh
index dc1d17c..9b8a359 100644
--- a/core/Lucy/Store/FileWindow.cfh
+++ b/core/Lucy/Store/FileWindow.cfh
@@ -35,6 +35,15 @@ class Lucy::Store::FileWindow inherits Clownfish::Obj {
 
     void
     Set_Window(FileWindow *self, char *buf, int64_t offset, int64_t len);
+
+    char*
+    Get_Buf(FileWindow *self);
+
+    int64_t
+    Get_Offset(FileWindow *self);
+
+    int64_t
+    Get_Len(FileWindow *self);
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/4f7440f8/core/Lucy/Store/InStream.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/InStream.c b/core/Lucy/Store/InStream.c
index 7727a11..caf286e 100644
--- a/core/Lucy/Store/InStream.c
+++ b/core/Lucy/Store/InStream.c
@@ -15,7 +15,6 @@
  */
 
 #define C_LUCY_INSTREAM
-#define C_LUCY_FILEWINDOW
 #include "Lucy/Util/ToolSet.h"
 
 #include "Lucy/Store/InStream.h"
@@ -203,9 +202,12 @@ S_fill(InStream *self, int64_t amount) {
 
     // Make the request.
     if (FH_Window(ivars->file_handle, window, real_file_pos, amount)) {
-        char *const window_limit = window->buf + window->len;
-        ivars->buf = window->buf
-                     - window->offset     // theoretical start of real file
+        char    *fw_buf    = FileWindow_Get_Buf(window);
+        int64_t  fw_offset = FileWindow_Get_Offset(window);
+        int64_t  fw_len    = FileWindow_Get_Len(window);
+        char *const window_limit = fw_buf + fw_len;
+        ivars->buf = fw_buf
+                     - fw_offset          // theoretical start of real file
                      + ivars->offset      // top of virtual file
                      + virtual_file_pos;  // position within virtual file
         ivars->limit = window_limit - ivars->buf > remaining
@@ -228,8 +230,11 @@ void
 InStream_seek(InStream *self, int64_t target) {
     InStreamIVARS *const ivars = InStream_IVARS(self);
     FileWindow *const window = ivars->window;
-    int64_t virtual_window_top = window->offset - ivars->offset;
-    int64_t virtual_window_end = virtual_window_top + window->len;
+    char    *fw_buf    = FileWindow_Get_Buf(window);
+    int64_t  fw_offset = FileWindow_Get_Offset(window);
+    int64_t  fw_len    = FileWindow_Get_Len(window);
+    int64_t  virtual_window_top = fw_offset - ivars->offset;
+    int64_t  virtual_window_end = virtual_window_top + fw_len;
 
     if (target < 0) {
         THROW(ERR, "Can't Seek '%o' to negative target %i64", ivars->filename,
@@ -239,7 +244,7 @@ InStream_seek(InStream *self, int64_t target) {
     else if (target >= virtual_window_top
              && target <= virtual_window_end
             ) {
-        ivars->buf = window->buf - window->offset + ivars->offset + target;
+        ivars->buf = fw_buf - fw_offset + ivars->offset + target;
     }
     else if (target > ivars->len) {
         THROW(ERR, "Can't Seek '%o' past EOF (%i64 > %i64)", ivars->filename,
@@ -259,9 +264,9 @@ InStream_seek(InStream *self, int64_t target) {
 static INLINE int64_t
 SI_tell(InStream *self) {
     InStreamIVARS *const ivars = InStream_IVARS(self);
-    FileWindow *const window = ivars->window;
-    int64_t pos_in_buf = PTR_TO_I64(ivars->buf) - PTR_TO_I64(window->buf);
-    return pos_in_buf + window->offset - ivars->offset;
+    char *fw_buf = FileWindow_Get_Buf(ivars->window);
+    int64_t pos_in_buf = PTR_TO_I64(ivars->buf) - PTR_TO_I64(fw_buf);
+    return pos_in_buf + FileWindow_Get_Offset(ivars->window) - ivars->offset;
 }
 
 int64_t


[lucy-commits] [03/34] git commit: refs/heads/master - Migrate Lucy's analysis classes to IVARS.

Posted by ma...@apache.org.
Migrate Lucy's analysis classes to IVARS.

Change all Lucy's analysis classes to access instance vars via an
IVARS struct rather than via `self`.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/68352179
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/68352179
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/68352179

Branch: refs/heads/master
Commit: 683521798756a052cd279e55d1d3eac811cb4823
Parents: ec90e66
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Thu Jun 27 13:59:37 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 15:50:06 2013 -0700

----------------------------------------------------------------------
 core/Lucy/Analysis/Analyzer.c           |   5 +-
 core/Lucy/Analysis/CaseFolder.c         |  16 ++--
 core/Lucy/Analysis/EasyAnalyzer.c       |  44 ++++++----
 core/Lucy/Analysis/Inversion.c          | 124 ++++++++++++++-------------
 core/Lucy/Analysis/Normalizer.c         |  39 +++++----
 core/Lucy/Analysis/PolyAnalyzer.c       |  30 ++++---
 core/Lucy/Analysis/RegexTokenizer.c     |  15 ++--
 core/Lucy/Analysis/SnowballStemmer.c    |  43 ++++++----
 core/Lucy/Analysis/SnowballStopFilter.c |  24 ++++--
 core/Lucy/Analysis/StandardTokenizer.c  |   8 +-
 core/Lucy/Analysis/Token.c              |  54 ++++++------
 11 files changed, 227 insertions(+), 175 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/68352179/core/Lucy/Analysis/Analyzer.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Analysis/Analyzer.c b/core/Lucy/Analysis/Analyzer.c
index 2ba60e5..ab23fdc 100644
--- a/core/Lucy/Analysis/Analyzer.c
+++ b/core/Lucy/Analysis/Analyzer.c
@@ -47,7 +47,10 @@ Analyzer_split(Analyzer *self, CharBuf *text) {
     Token      *token;
 
     while ((token = Inversion_Next(inversion)) != NULL) {
-        VA_Push(out, (Obj*)CB_new_from_trusted_utf8(token->text, token->len));
+        TokenIVARS *const token_ivars = Token_IVARS(token);
+        CharBuf *string
+            = CB_new_from_trusted_utf8(token_ivars->text, token_ivars->len);
+        VA_Push(out, (Obj*)string);
     }
 
     DECREF(inversion);

http://git-wip-us.apache.org/repos/asf/lucy/blob/68352179/core/Lucy/Analysis/CaseFolder.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Analysis/CaseFolder.c b/core/Lucy/Analysis/CaseFolder.c
index 313d0cd..9330caf 100644
--- a/core/Lucy/Analysis/CaseFolder.c
+++ b/core/Lucy/Analysis/CaseFolder.c
@@ -30,31 +30,33 @@ CaseFolder_new() {
 CaseFolder*
 CaseFolder_init(CaseFolder *self) {
     Analyzer_init((Analyzer*)self);
-    self->normalizer = Normalizer_new(NULL, true, false);
+    CaseFolderIVARS *const ivars = CaseFolder_IVARS(self);
+    ivars->normalizer = Normalizer_new(NULL, true, false);
     return self;
 }
 
 void
 CaseFolder_destroy(CaseFolder *self) {
-    DECREF(self->normalizer);
+    CaseFolderIVARS *const ivars = CaseFolder_IVARS(self);
+    DECREF(ivars->normalizer);
     SUPER_DESTROY(self, CASEFOLDER);
 }
 
 Inversion*
 CaseFolder_transform(CaseFolder *self, Inversion *inversion) {
-    return Normalizer_Transform(self->normalizer, inversion);
+    CaseFolderIVARS *const ivars = CaseFolder_IVARS(self);
+    return Normalizer_Transform(ivars->normalizer, inversion);
 }
 
 Inversion*
 CaseFolder_transform_text(CaseFolder *self, CharBuf *text) {
-    return Normalizer_Transform_Text(self->normalizer, text);
+    CaseFolderIVARS *const ivars = CaseFolder_IVARS(self);
+    return Normalizer_Transform_Text(ivars->normalizer, text);
 }
 
 bool
 CaseFolder_equals(CaseFolder *self, Obj *other) {
-    CaseFolder *const twin = (CaseFolder*)other;
-    if (twin == self)                 { return true; }
-    UNUSED_VAR(self);
+    if ((CaseFolder*)other == self)   { return true; }
     if (!Obj_Is_A(other, CASEFOLDER)) { return false; }
     return true;
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/68352179/core/Lucy/Analysis/EasyAnalyzer.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Analysis/EasyAnalyzer.c b/core/Lucy/Analysis/EasyAnalyzer.c
index 8d1534c..5441fd8 100644
--- a/core/Lucy/Analysis/EasyAnalyzer.c
+++ b/core/Lucy/Analysis/EasyAnalyzer.c
@@ -32,48 +32,53 @@ EasyAnalyzer_new(const CharBuf *language) {
 EasyAnalyzer*
 EasyAnalyzer_init(EasyAnalyzer *self, const CharBuf *language) {
     Analyzer_init((Analyzer*)self);
-    self->language   = CB_Clone(language);
-    self->tokenizer  = StandardTokenizer_new();
-    self->normalizer = Normalizer_new(NULL, true, false);
-    self->stemmer    = SnowStemmer_new(language);
+    EasyAnalyzerIVARS *const ivars = EasyAnalyzer_IVARS(self);
+    ivars->language   = CB_Clone(language);
+    ivars->tokenizer  = StandardTokenizer_new();
+    ivars->normalizer = Normalizer_new(NULL, true, false);
+    ivars->stemmer    = SnowStemmer_new(language);
     return self;
 }
 
 void
 EasyAnalyzer_destroy(EasyAnalyzer *self) {
-    DECREF(self->language);
-    DECREF(self->tokenizer);
-    DECREF(self->normalizer);
-    DECREF(self->stemmer);
+    EasyAnalyzerIVARS *const ivars = EasyAnalyzer_IVARS(self);
+    DECREF(ivars->language);
+    DECREF(ivars->tokenizer);
+    DECREF(ivars->normalizer);
+    DECREF(ivars->stemmer);
     SUPER_DESTROY(self, EASYANALYZER);
 }
 
 Inversion*
 EasyAnalyzer_transform(EasyAnalyzer *self, Inversion *inversion) {
-    Inversion *inv1 = StandardTokenizer_Transform(self->tokenizer, inversion);
-    Inversion *inv2 = Normalizer_Transform(self->normalizer, inv1);
+    EasyAnalyzerIVARS *const ivars = EasyAnalyzer_IVARS(self);
+    Inversion *inv1 = StandardTokenizer_Transform(ivars->tokenizer, inversion);
+    Inversion *inv2 = Normalizer_Transform(ivars->normalizer, inv1);
     DECREF(inv1);
-    inv1 = SnowStemmer_Transform(self->stemmer, inv2);
+    inv1 = SnowStemmer_Transform(ivars->stemmer, inv2);
     DECREF(inv2);
     return inv1;
 }
 
 Inversion*
 EasyAnalyzer_transform_text(EasyAnalyzer *self, CharBuf *text) {
-    Inversion *inv1 = StandardTokenizer_Transform_Text(self->tokenizer, text);
-    Inversion *inv2 = Normalizer_Transform(self->normalizer, inv1);
+    EasyAnalyzerIVARS *const ivars = EasyAnalyzer_IVARS(self);
+    Inversion *inv1 = StandardTokenizer_Transform_Text(ivars->tokenizer, text);
+    Inversion *inv2 = Normalizer_Transform(ivars->normalizer, inv1);
     DECREF(inv1);
-    inv1 = SnowStemmer_Transform(self->stemmer, inv2);
+    inv1 = SnowStemmer_Transform(ivars->stemmer, inv2);
     DECREF(inv2);
     return inv1;
 }
 
 Hash*
 EasyAnalyzer_dump(EasyAnalyzer *self) {
+    EasyAnalyzerIVARS *const ivars = EasyAnalyzer_IVARS(self);
     EasyAnalyzer_Dump_t super_dump
         = SUPER_METHOD_PTR(EASYANALYZER, Lucy_EasyAnalyzer_Dump);
     Hash *dump = super_dump(self);
-    Hash_Store_Str(dump, "language", 8, (Obj*)CB_Clone(self->language));
+    Hash_Store_Str(dump, "language", 8, (Obj*)CB_Clone(ivars->language));
     return dump;
 }
 
@@ -90,10 +95,11 @@ EasyAnalyzer_load(EasyAnalyzer *self, Obj *dump) {
 
 bool
 EasyAnalyzer_equals(EasyAnalyzer *self, Obj *other) {
-    EasyAnalyzer *const twin = (EasyAnalyzer*)other;
-    if (twin == self)                                     { return true; }
-    if (!Obj_Is_A(other, EASYANALYZER))                   { return false; }
-    if (!CB_Equals(twin->language, (Obj*)self->language)) { return false; }
+    if ((EasyAnalyzer*)other == self)                       { return true; }
+    if (!Obj_Is_A(other, EASYANALYZER))                     { return false; }
+    EasyAnalyzerIVARS *const ivars = EasyAnalyzer_IVARS(self);
+    EasyAnalyzerIVARS *const ovars = EasyAnalyzer_IVARS((EasyAnalyzer*)other);
+    if (!CB_Equals(ovars->language, (Obj*)ivars->language)) { return false; }
     return true;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/68352179/core/Lucy/Analysis/Inversion.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Analysis/Inversion.c b/core/Lucy/Analysis/Inversion.c
index abfede2..9a3fb34 100644
--- a/core/Lucy/Analysis/Inversion.c
+++ b/core/Lucy/Analysis/Inversion.c
@@ -24,20 +24,21 @@
 
 // After inversion, record how many like tokens occur in each group.
 static void
-S_count_clusters(Inversion *self);
+S_count_clusters(Inversion *self, InversionIVARS *ivars);
 
 Inversion*
 Inversion_new(Token *seed_token) {
     Inversion *self = (Inversion*)VTable_Make_Obj(INVERSION);
+    InversionIVARS *const ivars = Inversion_IVARS(self);
 
     // Init.
-    self->cap                 = 16;
-    self->size                = 0;
-    self->tokens              = (Token**)CALLOCATE(self->cap, sizeof(Token*));
-    self->cur                 = 0;
-    self->inverted            = false;
-    self->cluster_counts      = NULL;
-    self->cluster_counts_size = 0;
+    ivars->cap                 = 16;
+    ivars->size                = 0;
+    ivars->tokens              = (Token**)CALLOCATE(ivars->cap, sizeof(Token*));
+    ivars->cur                 = 0;
+    ivars->inverted            = false;
+    ivars->cluster_counts      = NULL;
+    ivars->cluster_counts_size = 0;
 
     // Process the seed token.
     if (seed_token != NULL) {
@@ -49,138 +50,145 @@ Inversion_new(Token *seed_token) {
 
 void
 Inversion_destroy(Inversion *self) {
-    if (self->tokens) {
-        Token **tokens       = self->tokens;
-        Token **const limit  = tokens + self->size;
+    InversionIVARS *const ivars = Inversion_IVARS(self);
+    if (ivars->tokens) {
+        Token **tokens       = ivars->tokens;
+        Token **const limit  = tokens + ivars->size;
         for (; tokens < limit; tokens++) {
             DECREF(*tokens);
         }
-        FREEMEM(self->tokens);
+        FREEMEM(ivars->tokens);
     }
-    FREEMEM(self->cluster_counts);
+    FREEMEM(ivars->cluster_counts);
     SUPER_DESTROY(self, INVERSION);
 }
 
 uint32_t
 Inversion_get_size(Inversion *self) {
-    return self->size;
+    return Inversion_IVARS(self)->size;
 }
 
 Token*
 Inversion_next(Inversion *self) {
+    InversionIVARS *const ivars = Inversion_IVARS(self);
     // Kill the iteration if we're out of tokens.
-    if (self->cur == self->size) {
+    if (ivars->cur == ivars->size) {
         return NULL;
     }
-    return self->tokens[self->cur++];
+    return ivars->tokens[ivars->cur++];
 }
 
 void
 Inversion_reset(Inversion *self) {
-    self->cur = 0;
+    Inversion_IVARS(self)->cur = 0;
 }
 
 static void
 S_grow(Inversion *self, size_t size) {
-    if (size > self->cap) {
+    InversionIVARS *const ivars = Inversion_IVARS(self);
+    if (size > ivars->cap) {
         uint64_t amount = size * sizeof(Token*);
         // Clip rather than wrap.
         if (amount > SIZE_MAX || amount < size) { amount = SIZE_MAX; }
-        self->tokens = (Token**)REALLOCATE(self->tokens, (size_t)amount);
-        self->cap    = size;
-        memset(self->tokens + self->size, 0,
-               (size - self->size) * sizeof(Token*));
+        ivars->tokens = (Token**)REALLOCATE(ivars->tokens, (size_t)amount);
+        ivars->cap    = size;
+        memset(ivars->tokens + ivars->size, 0,
+               (size - ivars->size) * sizeof(Token*));
     }
 }
 
 void
 Inversion_append(Inversion *self, Token *token) {
-    if (self->inverted) {
+    InversionIVARS *const ivars = Inversion_IVARS(self);
+    if (ivars->inverted) {
         THROW(ERR, "Can't append tokens after inversion");
     }
-    if (self->size >= self->cap) {
-        size_t new_capacity = Memory_oversize(self->size + 1, sizeof(Token*));
+    if (ivars->size >= ivars->cap) {
+        size_t new_capacity = Memory_oversize(ivars->size + 1, sizeof(Token*));
         S_grow(self, new_capacity);
     }
-    self->tokens[self->size] = token;
-    self->size++;
+    ivars->tokens[ivars->size] = token;
+    ivars->size++;
 }
 
 Token**
 Inversion_next_cluster(Inversion *self, uint32_t *count) {
-    Token **cluster = self->tokens + self->cur;
+    InversionIVARS *const ivars = Inversion_IVARS(self);
+    Token **cluster = ivars->tokens + ivars->cur;
 
-    if (self->cur == self->size) {
+    if (ivars->cur == ivars->size) {
         *count = 0;
         return NULL;
     }
 
     // Don't read past the end of the cluster counts array.
-    if (!self->inverted) {
+    if (!ivars->inverted) {
         THROW(ERR, "Inversion not yet inverted");
     }
-    if (self->cur > self->cluster_counts_size) {
+    if (ivars->cur > ivars->cluster_counts_size) {
         THROW(ERR, "Tokens were added after inversion");
     }
 
     // Place cluster count in passed-in var, advance bookmark.
-    *count = self->cluster_counts[self->cur];
-    self->cur += *count;
+    *count = ivars->cluster_counts[ivars->cur];
+    ivars->cur += *count;
 
     return cluster;
 }
 
 void
 Inversion_invert(Inversion *self) {
-    Token   **tokens = self->tokens;
-    Token   **limit  = tokens + self->size;
+    InversionIVARS *const ivars = Inversion_IVARS(self);
+    Token   **tokens = ivars->tokens;
+    Token   **limit  = tokens + ivars->size;
     int32_t   token_pos = 0;
 
     // Thwart future attempts to append.
-    if (self->inverted) {
+    if (ivars->inverted) {
         THROW(ERR, "Inversion has already been inverted");
     }
-    self->inverted = true;
+    ivars->inverted = true;
 
     // Assign token positions.
     for (; tokens < limit; tokens++) {
-        Token *const cur_token = *tokens;
-        cur_token->pos = token_pos;
-        token_pos = (int32_t)((uint32_t)token_pos + (uint32_t)cur_token->pos_inc);
-        if (token_pos < cur_token->pos) {
+        TokenIVARS *const cur_token_ivars = Token_IVARS(*tokens);
+        cur_token_ivars->pos = token_pos;
+        token_pos = (int32_t)((uint32_t)token_pos
+                              + (uint32_t)cur_token_ivars->pos_inc);
+        if (token_pos < cur_token_ivars->pos) {
             THROW(ERR, "Token positions out of order: %i32 %i32",
-                  cur_token->pos, token_pos);
+                  cur_token_ivars->pos, token_pos);
         }
     }
 
     // Sort the tokens lexically, and hand off to cluster counting routine.
-    Sort_quicksort(self->tokens, self->size, sizeof(Token*), Token_compare,
+    Sort_quicksort(ivars->tokens, ivars->size, sizeof(Token*), Token_compare,
                    NULL);
-    S_count_clusters(self);
+    S_count_clusters(self, ivars);
 }
 
 static void
-S_count_clusters(Inversion *self) {
-    Token **tokens = self->tokens;
+S_count_clusters(Inversion *self, InversionIVARS *ivars) {
+    UNUSED_VAR(self);
+    Token **tokens = ivars->tokens;
     uint32_t *counts
-        = (uint32_t*)CALLOCATE(self->size + 1, sizeof(uint32_t));
+        = (uint32_t*)CALLOCATE(ivars->size + 1, sizeof(uint32_t));
 
     // Save the cluster counts.
-    self->cluster_counts_size = self->size;
-    self->cluster_counts = counts;
+    ivars->cluster_counts_size = ivars->size;
+    ivars->cluster_counts = counts;
 
-    for (uint32_t i = 0; i < self->size;) {
-        Token *const base_token = tokens[i];
-        char  *const base_text  = base_token->text;
-        const size_t base_len   = base_token->len;
+    for (uint32_t i = 0; i < ivars->size;) {
+        TokenIVARS *const base_token_ivars = Token_IVARS(tokens[i]);
+        char  *const base_text  = base_token_ivars->text;
+        const size_t base_len   = base_token_ivars->len;
         uint32_t     j          = i + 1;
 
         // Iterate through tokens until text doesn't match.
-        while (j < self->size) {
-            Token *const candidate = tokens[j];
-
-            if ((candidate->len == base_len)
-                && (memcmp(candidate->text, base_text, base_len) == 0)
+        while (j < ivars->size) {
+            TokenIVARS *const candidate_ivars = Token_IVARS(tokens[j]);
+            if ((candidate_ivars->len == base_len)
+                && (memcmp(candidate_ivars->text, base_text, base_len) == 0)
                ) {
                 j++;
             }

http://git-wip-us.apache.org/repos/asf/lucy/blob/68352179/core/Lucy/Analysis/Normalizer.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Analysis/Normalizer.c b/core/Lucy/Analysis/Normalizer.c
index 3102882..a120db3 100644
--- a/core/Lucy/Analysis/Normalizer.c
+++ b/core/Lucy/Analysis/Normalizer.c
@@ -37,6 +37,7 @@ Normalizer*
 Normalizer_init(Normalizer *self, const CharBuf *form, bool case_fold,
                 bool strip_accents) {
     int options = UTF8PROC_STABLE;
+    NormalizerIVARS *const ivars = Normalizer_IVARS(self);
 
     if (form == NULL
         || CB_Equals_Str(form, "NFKC", 4) || CB_Equals_Str(form, "nfkc", 4)
@@ -59,7 +60,7 @@ Normalizer_init(Normalizer *self, const CharBuf *form, bool case_fold,
     if (case_fold)     { options |= UTF8PROC_CASEFOLD; }
     if (strip_accents) { options |= UTF8PROC_STRIPMARK; }
 
-    self->options = options;
+    ivars->options = options;
 
     return self;
 }
@@ -72,10 +73,14 @@ Normalizer_transform(Normalizer *self, Inversion *inversion) {
     int32_t *buffer = static_buffer;
     ssize_t bufsize = INITIAL_BUFSIZE;
     Token *token;
+    NormalizerIVARS *const ivars = Normalizer_IVARS(self);
 
     while (NULL != (token = Inversion_Next(inversion))) {
-        ssize_t len = utf8proc_decompose((uint8_t*)token->text, token->len,
-                                         buffer, bufsize, self->options);
+        TokenIVARS *const token_ivars = Token_IVARS(token);
+        ssize_t len
+            = utf8proc_decompose((uint8_t*)token_ivars->text,
+                                 token_ivars->len, buffer, bufsize,
+                                 ivars->options);
 
         if (len > bufsize) {
             // buffer too small, (re)allocate
@@ -85,22 +90,23 @@ Normalizer_transform(Normalizer *self, Inversion *inversion) {
             // allocate additional INITIAL_BUFSIZE items
             bufsize = len + INITIAL_BUFSIZE;
             buffer = (int32_t*)MALLOCATE((bufsize + 1) * sizeof(int32_t));
-            len = utf8proc_decompose((uint8_t*)token->text, token->len,
-                                     buffer, bufsize, self->options);
+            len = utf8proc_decompose((uint8_t*)token_ivars->text,
+                                     token_ivars->len, buffer, bufsize,
+                                     ivars->options);
         }
         if (len < 0) {
             continue;
         }
 
-        len = utf8proc_reencode(buffer, len, self->options);
+        len = utf8proc_reencode(buffer, len, ivars->options);
 
         if (len >= 0) {
-            if (len > (ssize_t)token->len) {
-                FREEMEM(token->text);
-                token->text = (char*)MALLOCATE(len + 1);
+            if (len > (ssize_t)token_ivars->len) {
+                FREEMEM(token_ivars->text);
+                token_ivars->text = (char*)MALLOCATE(len + 1);
             }
-            memcpy(token->text, buffer, len + 1);
-            token->len = len;
+            memcpy(token_ivars->text, buffer, len + 1);
+            token_ivars->len = len;
         }
     }
 
@@ -117,7 +123,7 @@ Normalizer_dump(Normalizer *self) {
     Normalizer_Dump_t super_dump
         = SUPER_METHOD_PTR(NORMALIZER, Lucy_Normalizer_Dump);
     Hash *dump = super_dump(self);
-    int options = self->options;
+    int options = Normalizer_IVARS(self)->options;
 
     CharBuf *form = options & UTF8PROC_COMPOSE ?
                     options & UTF8PROC_COMPAT ?
@@ -157,10 +163,11 @@ Normalizer_load(Normalizer *self, Obj *dump) {
 
 bool
 Normalizer_equals(Normalizer *self, Obj *other) {
-    Normalizer *const twin = (Normalizer*)other;
-    if (twin == self)                   { return true; }
-    if (!Obj_Is_A(other, NORMALIZER))   { return false; }
-    if (twin->options != self->options) { return false; }
+    if ((Normalizer*)other == self)       { return true; }
+    if (!Obj_Is_A(other, NORMALIZER))     { return false; }
+    NormalizerIVARS *const ivars = Normalizer_IVARS(self);
+    NormalizerIVARS *const ovars = Normalizer_IVARS((Normalizer*)other);
+    if (ovars->options != ivars->options) { return false; }
     return true;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/68352179/core/Lucy/Analysis/PolyAnalyzer.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Analysis/PolyAnalyzer.c b/core/Lucy/Analysis/PolyAnalyzer.c
index dd635c1..f755e4e 100644
--- a/core/Lucy/Analysis/PolyAnalyzer.c
+++ b/core/Lucy/Analysis/PolyAnalyzer.c
@@ -34,17 +34,19 @@ PolyAnalyzer*
 PolyAnalyzer_init(PolyAnalyzer *self, const CharBuf *language,
                   VArray *analyzers) {
     Analyzer_init((Analyzer*)self);
+    PolyAnalyzerIVARS *const ivars = PolyAnalyzer_IVARS(self);
+
     if (analyzers) {
         for (uint32_t i = 0, max = VA_Get_Size(analyzers); i < max; i++) {
             CERTIFY(VA_Fetch(analyzers, i), ANALYZER);
         }
-        self->analyzers = (VArray*)INCREF(analyzers);
+        ivars->analyzers = (VArray*)INCREF(analyzers);
     }
     else if (language) {
-        self->analyzers = VA_new(3);
-        VA_Push(self->analyzers, (Obj*)CaseFolder_new());
-        VA_Push(self->analyzers, (Obj*)RegexTokenizer_new(NULL));
-        VA_Push(self->analyzers, (Obj*)SnowStemmer_new(language));
+        ivars->analyzers = VA_new(3);
+        VA_Push(ivars->analyzers, (Obj*)CaseFolder_new());
+        VA_Push(ivars->analyzers, (Obj*)RegexTokenizer_new(NULL));
+        VA_Push(ivars->analyzers, (Obj*)SnowStemmer_new(language));
     }
     else {
         THROW(ERR, "Must specify either 'language' or 'analyzers'");
@@ -55,18 +57,19 @@ PolyAnalyzer_init(PolyAnalyzer *self, const CharBuf *language,
 
 void
 PolyAnalyzer_destroy(PolyAnalyzer *self) {
-    DECREF(self->analyzers);
+    PolyAnalyzerIVARS *const ivars = PolyAnalyzer_IVARS(self);
+    DECREF(ivars->analyzers);
     SUPER_DESTROY(self, POLYANALYZER);
 }
 
 VArray*
 PolyAnalyzer_get_analyzers(PolyAnalyzer *self) {
-    return self->analyzers;
+    return PolyAnalyzer_IVARS(self)->analyzers;
 }
 
 Inversion*
 PolyAnalyzer_transform(PolyAnalyzer *self, Inversion *inversion) {
-    VArray *const analyzers = self->analyzers;
+    VArray *const analyzers = PolyAnalyzer_IVARS(self)->analyzers;
     (void)INCREF(inversion);
 
     // Iterate through each of the analyzers in order.
@@ -82,7 +85,7 @@ PolyAnalyzer_transform(PolyAnalyzer *self, Inversion *inversion) {
 
 Inversion*
 PolyAnalyzer_transform_text(PolyAnalyzer *self, CharBuf *text) {
-    VArray *const   analyzers     = self->analyzers;
+    VArray *const   analyzers     = PolyAnalyzer_IVARS(self)->analyzers;
     const uint32_t  num_analyzers = VA_Get_Size(analyzers);
     Inversion      *retval;
 
@@ -109,10 +112,11 @@ PolyAnalyzer_transform_text(PolyAnalyzer *self, CharBuf *text) {
 
 bool
 PolyAnalyzer_equals(PolyAnalyzer *self, Obj *other) {
-    PolyAnalyzer *const twin = (PolyAnalyzer*)other;
-    if (twin == self)                                       { return true; }
-    if (!Obj_Is_A(other, POLYANALYZER))                     { return false; }
-    if (!VA_Equals(twin->analyzers, (Obj*)self->analyzers)) { return false; }
+    if ((PolyAnalyzer*)other == self)                         { return true; }
+    if (!Obj_Is_A(other, POLYANALYZER))                       { return false; }
+    PolyAnalyzerIVARS *const ivars = PolyAnalyzer_IVARS(self);
+    PolyAnalyzerIVARS *const ovars = PolyAnalyzer_IVARS((PolyAnalyzer*)other);
+    if (!VA_Equals(ovars->analyzers, (Obj*)ivars->analyzers)) { return false; }
     return true;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/68352179/core/Lucy/Analysis/RegexTokenizer.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Analysis/RegexTokenizer.c b/core/Lucy/Analysis/RegexTokenizer.c
index 628571f..b44095e 100644
--- a/core/Lucy/Analysis/RegexTokenizer.c
+++ b/core/Lucy/Analysis/RegexTokenizer.c
@@ -34,7 +34,8 @@ RegexTokenizer_transform(RegexTokenizer *self, Inversion *inversion) {
     Token *token;
 
     while (NULL != (token = Inversion_Next(inversion))) {
-        RegexTokenizer_Tokenize_Str(self, token->text, token->len,
+        TokenIVARS *const token_ivars = Token_IVARS(token);
+        RegexTokenizer_Tokenize_Str(self, token_ivars->text, token_ivars->len,
                                     new_inversion);
     }
 
@@ -51,10 +52,11 @@ RegexTokenizer_transform_text(RegexTokenizer *self, CharBuf *text) {
 
 Obj*
 RegexTokenizer_dump(RegexTokenizer *self) {
+    RegexTokenizerIVARS *const ivars = RegexTokenizer_IVARS(self);
     RegexTokenizer_Dump_t super_dump
         = SUPER_METHOD_PTR(REGEXTOKENIZER, Lucy_RegexTokenizer_Dump);
     Hash *dump = (Hash*)CERTIFY(super_dump(self), HASH);
-    Hash_Store_Str(dump, "pattern", 7, CB_Dump(self->pattern));
+    Hash_Store_Str(dump, "pattern", 7, CB_Dump(ivars->pattern));
     return (Obj*)dump;
 }
 
@@ -71,10 +73,11 @@ RegexTokenizer_load(RegexTokenizer *self, Obj *dump) {
 
 bool
 RegexTokenizer_equals(RegexTokenizer *self, Obj *other) {
-    RegexTokenizer *const twin = (RegexTokenizer*)other;
-    if (twin == self)                                   { return true; }
-    if (!Obj_Is_A(other, REGEXTOKENIZER))               { return false; }
-    if (!CB_Equals(twin->pattern, (Obj*)self->pattern)) { return false; }
+    if ((RegexTokenizer*)other == self)                   { return true; }
+    if (!Obj_Is_A(other, REGEXTOKENIZER))                 { return false; }
+    RegexTokenizerIVARS *ivars = RegexTokenizer_IVARS(self);
+    RegexTokenizerIVARS *ovars = RegexTokenizer_IVARS((RegexTokenizer*)other);
+    if (!CB_Equals(ivars->pattern, (Obj*)ovars->pattern)) { return false; }
     return true;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/68352179/core/Lucy/Analysis/SnowballStemmer.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Analysis/SnowballStemmer.c b/core/Lucy/Analysis/SnowballStemmer.c
index 67be914..2229389 100644
--- a/core/Lucy/Analysis/SnowballStemmer.c
+++ b/core/Lucy/Analysis/SnowballStemmer.c
@@ -35,14 +35,15 @@ SnowballStemmer*
 SnowStemmer_init(SnowballStemmer *self, const CharBuf *language) {
     char lang_buf[3];
     Analyzer_init((Analyzer*)self);
-    self->language = CB_Clone(language);
+    SnowballStemmerIVARS *const ivars = SnowStemmer_IVARS(self);
+    ivars->language = CB_Clone(language);
 
     // Get a Snowball stemmer.  Be case-insensitive.
     lang_buf[0] = tolower(CB_Code_Point_At(language, 0));
     lang_buf[1] = tolower(CB_Code_Point_At(language, 1));
     lang_buf[2] = '\0';
-    self->snowstemmer = sb_stemmer_new(lang_buf, "UTF_8");
-    if (!self->snowstemmer) {
+    ivars->snowstemmer = sb_stemmer_new(lang_buf, "UTF_8");
+    if (!ivars->snowstemmer) {
         THROW(ERR, "Can't find a Snowball stemmer for %o", language);
     }
 
@@ -51,29 +52,33 @@ SnowStemmer_init(SnowballStemmer *self, const CharBuf *language) {
 
 void
 SnowStemmer_destroy(SnowballStemmer *self) {
-    if (self->snowstemmer) {
-        sb_stemmer_delete((struct sb_stemmer*)self->snowstemmer);
+    SnowballStemmerIVARS *const ivars = SnowStemmer_IVARS(self);
+    if (ivars->snowstemmer) {
+        sb_stemmer_delete((struct sb_stemmer*)ivars->snowstemmer);
     }
-    DECREF(self->language);
+    DECREF(ivars->language);
     SUPER_DESTROY(self, SNOWBALLSTEMMER);
 }
 
 Inversion*
 SnowStemmer_transform(SnowballStemmer *self, Inversion *inversion) {
     Token *token;
+    SnowballStemmerIVARS *const ivars = SnowStemmer_IVARS(self);
     struct sb_stemmer *const snowstemmer
-        = (struct sb_stemmer*)self->snowstemmer;
+        = (struct sb_stemmer*)ivars->snowstemmer;
 
     while (NULL != (token = Inversion_Next(inversion))) {
+        TokenIVARS *const token_ivars = Token_IVARS(token);
         const sb_symbol *stemmed_text 
-            = sb_stemmer_stem(snowstemmer, (sb_symbol*)token->text, token->len);
+            = sb_stemmer_stem(snowstemmer, (sb_symbol*)token_ivars->text,
+                              token_ivars->len);
         size_t len = sb_stemmer_length(snowstemmer);
-        if (len > token->len) {
-            FREEMEM(token->text);
-            token->text = (char*)MALLOCATE(len + 1);
+        if (len > token_ivars->len) {
+            FREEMEM(token_ivars->text);
+            token_ivars->text = (char*)MALLOCATE(len + 1);
         }
-        memcpy(token->text, stemmed_text, len + 1);
-        token->len = len;
+        memcpy(token_ivars->text, stemmed_text, len + 1);
+        token_ivars->len = len;
     }
     Inversion_Reset(inversion);
     return (Inversion*)INCREF(inversion);
@@ -81,10 +86,11 @@ SnowStemmer_transform(SnowballStemmer *self, Inversion *inversion) {
 
 Hash*
 SnowStemmer_dump(SnowballStemmer *self) {
+    SnowballStemmerIVARS *const ivars = SnowStemmer_IVARS(self);
     SnowStemmer_Dump_t super_dump
         = SUPER_METHOD_PTR(SNOWBALLSTEMMER, Lucy_SnowStemmer_Dump);
     Hash *dump = super_dump(self);
-    Hash_Store_Str(dump, "language", 8, (Obj*)CB_Clone(self->language));
+    Hash_Store_Str(dump, "language", 8, (Obj*)CB_Clone(ivars->language));
     return dump;
 }
 
@@ -101,10 +107,11 @@ SnowStemmer_load(SnowballStemmer *self, Obj *dump) {
 
 bool
 SnowStemmer_equals(SnowballStemmer *self, Obj *other) {
-    SnowballStemmer *const twin = (SnowballStemmer*)other;
-    if (twin == self)                                     { return true; }
-    if (!Obj_Is_A(other, SNOWBALLSTEMMER))                { return false; }
-    if (!CB_Equals(twin->language, (Obj*)self->language)) { return false; }
+    if ((SnowballStemmer*)other == self)                    { return true; }
+    if (!Obj_Is_A(other, SNOWBALLSTEMMER))                  { return false; }
+    SnowballStemmerIVARS *ivars = SnowStemmer_IVARS(self);
+    SnowballStemmerIVARS *ovars = SnowStemmer_IVARS((SnowballStemmer*)other);
+    if (!CB_Equals(ovars->language, (Obj*)ivars->language)) { return false; }
     return true;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/68352179/core/Lucy/Analysis/SnowballStopFilter.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Analysis/SnowballStopFilter.c b/core/Lucy/Analysis/SnowballStopFilter.c
index 50c995c..e0d1f63 100644
--- a/core/Lucy/Analysis/SnowballStopFilter.c
+++ b/core/Lucy/Analysis/SnowballStopFilter.c
@@ -33,14 +33,15 @@ SnowballStopFilter*
 SnowStop_init(SnowballStopFilter *self, const CharBuf *language,
               Hash *stoplist) {
     Analyzer_init((Analyzer*)self);
+    SnowballStopFilterIVARS *const ivars = SnowStop_IVARS(self);
 
     if (stoplist) {
         if (language) { THROW(ERR, "Can't have both stoplist and language"); }
-        self->stoplist = (Hash*)INCREF(stoplist);
+        ivars->stoplist = (Hash*)INCREF(stoplist);
     }
     else if (language) {
-        self->stoplist = SnowStop_gen_stoplist(language);
-        if (!self->stoplist) {
+        ivars->stoplist = SnowStop_gen_stoplist(language);
+        if (!ivars->stoplist) {
             THROW(ERR, "Can't get a stoplist for '%o'", language);
         }
     }
@@ -53,7 +54,8 @@ SnowStop_init(SnowballStopFilter *self, const CharBuf *language,
 
 void
 SnowStop_destroy(SnowballStopFilter *self) {
-    DECREF(self->stoplist);
+    SnowballStopFilterIVARS *const ivars = SnowStop_IVARS(self);
+    DECREF(ivars->stoplist);
     SUPER_DESTROY(self, SNOWBALLSTOPFILTER);
 }
 
@@ -61,10 +63,12 @@ Inversion*
 SnowStop_transform(SnowballStopFilter *self, Inversion *inversion) {
     Token *token;
     Inversion *new_inversion = Inversion_new(NULL);
-    Hash *const stoplist  = self->stoplist;
+    SnowballStopFilterIVARS *const ivars = SnowStop_IVARS(self);
+    Hash *const stoplist  = ivars->stoplist;
 
     while (NULL != (token = Inversion_Next(inversion))) {
-        if (!Hash_Fetch_Str(stoplist, token->text, token->len)) {
+        TokenIVARS *const token_ivars = Token_IVARS(token);
+        if (!Hash_Fetch_Str(stoplist, token_ivars->text, token_ivars->len)) {
             Inversion_Append(new_inversion, (Token*)INCREF(token));
         }
     }
@@ -74,10 +78,12 @@ SnowStop_transform(SnowballStopFilter *self, Inversion *inversion) {
 
 bool
 SnowStop_equals(SnowballStopFilter *self, Obj *other) {
-    SnowballStopFilter *const twin = (SnowballStopFilter*)other;
-    if (twin == self)                         { return true; }
+    if ((SnowballStopFilter*)other == self)   { return true; }
     if (!Obj_Is_A(other, SNOWBALLSTOPFILTER)) { return false; }
-    if (!Hash_Equals(twin->stoplist, (Obj*)self->stoplist)) {
+    SnowballStopFilterIVARS *const ivars = SnowStop_IVARS(self);
+    SnowballStopFilterIVARS *const ovars
+        = SnowStop_IVARS((SnowballStopFilter*)other);
+    if (!Hash_Equals(ivars->stoplist, (Obj*)ovars->stoplist)) {
         return false;
     }
     return true;

http://git-wip-us.apache.org/repos/asf/lucy/blob/68352179/core/Lucy/Analysis/StandardTokenizer.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Analysis/StandardTokenizer.c b/core/Lucy/Analysis/StandardTokenizer.c
index 1ccd2d0..61a19a1 100644
--- a/core/Lucy/Analysis/StandardTokenizer.c
+++ b/core/Lucy/Analysis/StandardTokenizer.c
@@ -86,8 +86,9 @@ StandardTokenizer_transform(StandardTokenizer *self, Inversion *inversion) {
     Token *token;
 
     while (NULL != (token = Inversion_Next(inversion))) {
-        StandardTokenizer_Tokenize_Str(self, token->text, token->len,
-                                       new_inversion);
+        TokenIVARS *const token_ivars = Token_IVARS(token);
+        StandardTokenizer_Tokenize_Str(self, token_ivars->text,
+                                       token_ivars->len, new_inversion);
     }
 
     return new_inversion;
@@ -293,8 +294,7 @@ S_skip_extend_format(const char *text, size_t len, lucy_StringIter *iter) {
 
 bool
 StandardTokenizer_equals(StandardTokenizer *self, Obj *other) {
-    StandardTokenizer *const twin = (StandardTokenizer*)other;
-    if (twin == self)                        { return true; }
+    if ((StandardTokenizer*)other == self)   { return true; }
     if (!Obj_Is_A(other, STANDARDTOKENIZER)) { return false; }
     return true;
 }

http://git-wip-us.apache.org/repos/asf/lucy/blob/68352179/core/Lucy/Analysis/Token.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Analysis/Token.c b/core/Lucy/Analysis/Token.c
index 5b53043..f5fec54 100644
--- a/core/Lucy/Analysis/Token.c
+++ b/core/Lucy/Analysis/Token.c
@@ -30,34 +30,39 @@ Token_new(const char* text, size_t len, uint32_t start_offset,
 Token*
 Token_init(Token *self, const char* text, size_t len, uint32_t start_offset,
            uint32_t end_offset, float boost, int32_t pos_inc) {
+    TokenIVARS *const ivars = Token_IVARS(self);
+
     // Allocate and assign.
-    self->text      = (char*)MALLOCATE(len + 1);
-    self->text[len] = '\0';
-    memcpy(self->text, text, len);
+    ivars->text      = (char*)MALLOCATE(len + 1);
+    ivars->text[len] = '\0';
+    memcpy(ivars->text, text, len);
 
     // Assign.
-    self->len          = len;
-    self->start_offset = start_offset;
-    self->end_offset   = end_offset;
-    self->boost        = boost;
-    self->pos_inc      = pos_inc;
+    ivars->len          = len;
+    ivars->start_offset = start_offset;
+    ivars->end_offset   = end_offset;
+    ivars->boost        = boost;
+    ivars->pos_inc      = pos_inc;
 
     // Init.
-    self->pos = -1;
+    ivars->pos = -1;
 
     return self;
 }
 
 void
 Token_destroy(Token *self) {
-    FREEMEM(self->text);
+    TokenIVARS *const ivars = Token_IVARS(self);
+    FREEMEM(ivars->text);
     SUPER_DESTROY(self, TOKEN);
 }
 
 int
 Token_compare(void *context, const void *va, const void *vb) {
-    Token *const a = *((Token**)va);
-    Token *const b = *((Token**)vb);
+    Token *const token_a = *((Token**)va);
+    Token *const token_b = *((Token**)vb);
+    TokenIVARS *const a = Token_IVARS(token_a);
+    TokenIVARS *const b = Token_IVARS(token_b);
     size_t min_len = a->len < b->len ? a->len : b->len;
     int comparison = memcmp(a->text, b->text, min_len);
     UNUSED_VAR(context);
@@ -76,43 +81,44 @@ Token_compare(void *context, const void *va, const void *vb) {
 
 uint32_t
 Token_get_start_offset(Token *self) {
-    return self->start_offset;
+    return Token_IVARS(self)->start_offset;
 }
 
 uint32_t
 Token_get_end_offset(Token *self) {
-    return self->end_offset;
+    return Token_IVARS(self)->end_offset;
 }
 
 float
 Token_get_boost(Token *self) {
-    return self->boost;
+    return Token_IVARS(self)->boost;
 }
 
 int32_t
 Token_get_pos_inc(Token *self) {
-    return self->pos_inc;
+    return Token_IVARS(self)->pos_inc;
 }
 
 char*
 Token_get_text(Token *self) {
-    return self->text;
+    return Token_IVARS(self)->text;
 }
 
 size_t
 Token_get_len(Token *self) {
-    return self->len;
+    return Token_IVARS(self)->len;
 }
 
 void
 Token_set_text(Token *self, char *text, size_t len) {
-    if (len > self->len) {
-        FREEMEM(self->text);
-        self->text = (char*)MALLOCATE(len + 1);
+    TokenIVARS *const ivars = Token_IVARS(self);
+    if (len > ivars->len) {
+        FREEMEM(ivars->text);
+        ivars->text = (char*)MALLOCATE(len + 1);
     }
-    memcpy(self->text, text, len);
-    self->text[len] = '\0';
-    self->len = len;
+    memcpy(ivars->text, text, len);
+    ivars->text[len] = '\0';
+    ivars->len = len;
 }
 
 


[lucy-commits] [09/34] git commit: refs/heads/master - Migrate Lucy's util classes to IVARS.

Posted by ma...@apache.org.
Migrate Lucy's util classes to IVARS.

Change all Lucy's util classes to access instance vars via an IVARS
struct rather than via `self`.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/9bff835a
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/9bff835a
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/9bff835a

Branch: refs/heads/master
Commit: 9bff835a8bd62e7202870c05ac510905ec488139
Parents: 458824c
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Fri Jun 28 11:30:50 2013 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Jul 16 15:50:07 2013 -0700

----------------------------------------------------------------------
 core/Lucy/Util/MemoryPool.c    | 100 ++++++++-------
 core/Lucy/Util/PriorityQueue.c | 118 ++++++++++--------
 core/Lucy/Util/SortExternal.c  | 242 +++++++++++++++++++-----------------
 3 files changed, 246 insertions(+), 214 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/9bff835a/core/Lucy/Util/MemoryPool.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Util/MemoryPool.c b/core/Lucy/Util/MemoryPool.c
index d2bfebd..fff1dce 100644
--- a/core/Lucy/Util/MemoryPool.c
+++ b/core/Lucy/Util/MemoryPool.c
@@ -20,7 +20,7 @@
 #include "Lucy/Util/MemoryPool.h"
 
 static void
-S_init_arena(MemoryPool *self, size_t amount);
+S_init_arena(MemoryPool *self, MemoryPoolIVARS *ivars, size_t amount);
 
 #define DEFAULT_BUF_SIZE 0x100000 // 1 MiB
 
@@ -42,32 +42,35 @@ MemPool_new(uint32_t arena_size) {
 
 MemoryPool*
 MemPool_init(MemoryPool *self, uint32_t arena_size) {
-    self->arena_size = arena_size == 0 ? DEFAULT_BUF_SIZE : arena_size;
-    self->arenas     = VA_new(16);
-    self->tick       = -1;
-    self->buf        = NULL;
-    self->limit      = NULL;
-    self->consumed   = 0;
+    MemoryPoolIVARS *const ivars = MemPool_IVARS(self);
+    ivars->arena_size = arena_size == 0 ? DEFAULT_BUF_SIZE : arena_size;
+    ivars->arenas     = VA_new(16);
+    ivars->tick       = -1;
+    ivars->buf        = NULL;
+    ivars->limit      = NULL;
+    ivars->consumed   = 0;
 
     return self;
 }
 
 void
 MemPool_destroy(MemoryPool *self) {
-    DECREF(self->arenas);
+    MemoryPoolIVARS *const ivars = MemPool_IVARS(self);
+    DECREF(ivars->arenas);
     SUPER_DESTROY(self, MEMORYPOOL);
 }
 
 static void
-S_init_arena(MemoryPool *self, size_t amount) {
+S_init_arena(MemoryPool *self, MemoryPoolIVARS *ivars, size_t amount) {
+    UNUSED_VAR(self);
     ByteBuf *bb;
 
     // Indicate which arena we're using at present.
-    self->tick++;
+    ivars->tick++;
 
-    if (self->tick < (int32_t)VA_Get_Size(self->arenas)) {
+    if (ivars->tick < (int32_t)VA_Get_Size(ivars->arenas)) {
         // In recycle mode, use previously acquired memory.
-        bb = (ByteBuf*)VA_Fetch(self->arenas, self->tick);
+        bb = (ByteBuf*)VA_Fetch(ivars->arenas, ivars->tick);
         if (amount >= BB_Get_Size(bb)) {
             BB_Grow(bb, amount);
             BB_Set_Size(bb, amount);
@@ -75,63 +78,65 @@ S_init_arena(MemoryPool *self, size_t amount) {
     }
     else {
         // In add mode, get more mem from system.
-        size_t buf_size = (amount + 1) > self->arena_size
+        size_t buf_size = (amount + 1) > ivars->arena_size
                           ? (amount + 1)
-                          : self->arena_size;
+                          : ivars->arena_size;
         char *ptr = (char*)MALLOCATE(buf_size);
         bb = BB_new_steal_bytes(ptr, buf_size - 1, buf_size);
-        VA_Push(self->arenas, (Obj*)bb);
+        VA_Push(ivars->arenas, (Obj*)bb);
     }
 
     // Recalculate consumption to take into account blocked off space.
-    self->consumed = 0;
-    for (int32_t i = 0; i < self->tick; i++) {
-        ByteBuf *bb = (ByteBuf*)VA_Fetch(self->arenas, i);
-        self->consumed += BB_Get_Size(bb);
+    ivars->consumed = 0;
+    for (int32_t i = 0; i < ivars->tick; i++) {
+        ByteBuf *bb = (ByteBuf*)VA_Fetch(ivars->arenas, i);
+        ivars->consumed += BB_Get_Size(bb);
     }
 
-    self->buf   = BB_Get_Buf(bb);
-    self->limit = self->buf + BB_Get_Size(bb);
+    ivars->buf   = BB_Get_Buf(bb);
+    ivars->limit = ivars->buf + BB_Get_Size(bb);
 }
 
 size_t
 MemPool_get_consumed(MemoryPool *self) {
-    return self->consumed;
+    return MemPool_IVARS(self)->consumed;
 }
 
 void*
 MemPool_grab(MemoryPool *self, size_t amount) {
+    MemoryPoolIVARS *const ivars = MemPool_IVARS(self);
     INCREASE_TO_WORD_MULTIPLE(amount);
-    self->last_buf = self->buf;
+    ivars->last_buf = ivars->buf;
 
     // Verify that we have enough stocked up, otherwise get more.
-    self->buf += amount;
-    if (self->buf >= self->limit) {
+    ivars->buf += amount;
+    if (ivars->buf >= ivars->limit) {
         // Get enough mem from system or die trying.
-        S_init_arena(self, amount);
-        self->last_buf = self->buf;
-        self->buf += amount;
+        S_init_arena(self, ivars, amount);
+        ivars->last_buf = ivars->buf;
+        ivars->buf += amount;
     }
 
     // Track bytes we've allocated from this pool.
-    self->consumed += amount;
+    ivars->consumed += amount;
 
-    return self->last_buf;
+    return ivars->last_buf;
 }
 
 void
 MemPool_resize(MemoryPool *self, void *ptr, size_t new_amount) {
-    const size_t last_amount = self->buf - self->last_buf;
+    MemoryPoolIVARS *const ivars = MemPool_IVARS(self);
+    const size_t last_amount = ivars->buf - ivars->last_buf;
     INCREASE_TO_WORD_MULTIPLE(new_amount);
 
-    if (ptr != self->last_buf) {
+    if (ptr != ivars->last_buf) {
         THROW(ERR, "Not the last pointer allocated.");
     }
     else {
         if (new_amount <= last_amount) {
             const size_t difference = last_amount - new_amount;
-            self->buf      -= difference;
-            self->consumed -= difference;
+            ivars->buf      -= difference;
+            ivars->consumed -= difference;
         }
         else {
             THROW(ERR, "Can't resize to greater amount: %u64 > %u64",
@@ -142,28 +147,31 @@ MemPool_resize(MemoryPool *self, void *ptr, size_t new_amount) {
 
 void
 MemPool_release_all(MemoryPool *self) {
-    self->tick     = -1;
-    self->buf      = NULL;
-    self->last_buf = NULL;
-    self->limit    = NULL;
+    MemoryPoolIVARS *const ivars = MemPool_IVARS(self);
+    ivars->tick     = -1;
+    ivars->buf      = NULL;
+    ivars->last_buf = NULL;
+    ivars->limit    = NULL;
 }
 
 void
 MemPool_eat(MemoryPool *self, MemoryPool *other) {
-    if (self->buf != NULL) {
+    MemoryPoolIVARS *const ivars = MemPool_IVARS(self);
+    MemoryPoolIVARS *const ovars = MemPool_IVARS(other);
+    if (ivars->buf != NULL) {
         THROW(ERR, "Memory pool is not empty");
     }
 
     // Move active arenas from other to self.
-    for (int32_t i = 0; i <= other->tick; i++) {
-        ByteBuf *arena = (ByteBuf*)VA_Shift(other->arenas);
+    for (int32_t i = 0; i <= ovars->tick; i++) {
+        ByteBuf *arena = (ByteBuf*)VA_Shift(ovars->arenas);
         // Maybe displace existing arena.
-        VA_Store(self->arenas, i, (Obj*)arena);
+        VA_Store(ivars->arenas, i, (Obj*)arena);
     }
-    self->tick     = other->tick;
-    self->last_buf = other->last_buf;
-    self->buf      = other->buf;
-    self->limit    = other->limit;
+    ivars->tick     = ovars->tick;
+    ivars->last_buf = ovars->last_buf;
+    ivars->buf      = ovars->buf;
+    ivars->limit    = ovars->limit;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/9bff835a/core/Lucy/Util/PriorityQueue.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Util/PriorityQueue.c b/core/Lucy/Util/PriorityQueue.c
index 048d410..b13bce1 100644
--- a/core/Lucy/Util/PriorityQueue.c
+++ b/core/Lucy/Util/PriorityQueue.c
@@ -24,35 +24,36 @@
 // Add an element to the heap.  Throw an error if too many elements
 // are added.
 static void
-S_put(PriorityQueue *self, Obj *element);
+S_put(PriorityQueue *self, PriorityQueueIVARS *ivars, Obj *element);
 
 // Free all the elements in the heap and set size to 0.
 static void
-S_clear(PriorityQueue *self);
+S_clear(PriorityQueue *self, PriorityQueueIVARS *ivars);
 
 // Heap adjuster.
 static void
-S_up_heap(PriorityQueue *self);
+S_up_heap(PriorityQueue *self, PriorityQueueIVARS *ivars);
 
 // Heap adjuster.  Should be called when the item at the top changes.
 static void
-S_down_heap(PriorityQueue *self);
+S_down_heap(PriorityQueue *self, PriorityQueueIVARS *ivars);
 
 PriorityQueue*
 PriQ_init(PriorityQueue *self, uint32_t max_size) {
+    PriorityQueueIVARS *const ivars = PriQ_IVARS(self);
     if (max_size == UINT32_MAX) {
         THROW(ERR, "max_size too large: %u32", max_size);
     }
     uint32_t heap_size = max_size + 1;
 
     // Init.
-    self->size = 0;
+    ivars->size = 0;
 
     // Assign.
-    self->max_size = max_size;
+    ivars->max_size = max_size;
 
     // Allocate space for the heap, assign all slots to NULL.
-    self->heap = (Obj**)CALLOCATE(heap_size, sizeof(Obj*));
+    ivars->heap = (Obj**)CALLOCATE(heap_size, sizeof(Obj*));
 
     ABSTRACT_CLASS_CHECK(self, PRIORITYQUEUE);
     return self;
@@ -60,32 +61,33 @@ PriQ_init(PriorityQueue *self, uint32_t max_size) {
 
 void
 PriQ_destroy(PriorityQueue *self) {
-    if (self->heap) {
-        S_clear(self);
-        FREEMEM(self->heap);
+    PriorityQueueIVARS *const ivars = PriQ_IVARS(self);
+    if (ivars->heap) {
+        S_clear(self, ivars);
+        FREEMEM(ivars->heap);
     }
     SUPER_DESTROY(self, PRIORITYQUEUE);
 }
 
 uint32_t
 PriQ_get_size(PriorityQueue *self) {
-    return self->size;
+    return PriQ_IVARS(self)->size;
 }
 
 static void
-S_put(PriorityQueue *self, Obj *element) {
+S_put(PriorityQueue *self, PriorityQueueIVARS *ivars, Obj *element) {
     // Increment size.
-    if (self->size >= self->max_size) {
-        THROW(ERR, "PriorityQueue exceeded max_size: %u32 %u32", self->size,
-              self->max_size);
+    if (ivars->size >= ivars->max_size) {
+        THROW(ERR, "PriorityQueue exceeded max_size: %u32 %u32", ivars->size,
+              ivars->max_size);
     }
-    self->size++;
+    ivars->size++;
 
     // Put element into heap.
-    self->heap[self->size] = element;
+    ivars->heap[ivars->size] = element;
 
     // Adjust heap.
-    S_up_heap(self);
+    S_up_heap(self, ivars);
 }
 
 bool
@@ -98,22 +100,24 @@ PriQ_insert(PriorityQueue *self, Obj *element) {
 
 Obj*
 PriQ_jostle(PriorityQueue *self, Obj *element) {
+    PriorityQueueIVARS *const ivars = PriQ_IVARS(self);
+
     // Absorb element if there's a vacancy.
-    if (self->size < self->max_size) {
-        S_put(self, element);
+    if (ivars->size < ivars->max_size) {
+        S_put(self, ivars, element);
         return NULL;
     }
     // Otherwise, compete for the slot.
-    else if (self->size == 0) {
+    else if (ivars->size == 0) {
         return element;
     }
     else {
         Obj *scratch = PriQ_Peek(self);
         if (!PriQ_Less_Than(self, element, scratch)) {
             // If the new element belongs in the queue, replace something.
-            Obj *retval = self->heap[1];
-            self->heap[1] = element;
-            S_down_heap(self);
+            Obj *retval = ivars->heap[1];
+            ivars->heap[1] = element;
+            S_down_heap(self, ivars);
             return retval;
         }
         else {
@@ -124,15 +128,16 @@ PriQ_jostle(PriorityQueue *self, Obj *element) {
 
 Obj*
 PriQ_pop(PriorityQueue *self) {
-    if (self->size > 0) {
+    PriorityQueueIVARS *const ivars = PriQ_IVARS(self);
+    if (ivars->size > 0) {
         // Save the first value.
-        Obj *result = self->heap[1];
+        Obj *result = ivars->heap[1];
 
         // Move last to first and adjust heap.
-        self->heap[1] = self->heap[self->size];
-        self->heap[self->size] = NULL;
-        self->size--;
-        S_down_heap(self);
+        ivars->heap[1] = ivars->heap[ivars->size];
+        ivars->heap[ivars->size] = NULL;
+        ivars->size--;
+        S_down_heap(self, ivars);
 
         // Return the value, leaving a refcount for the caller.
         return result;
@@ -144,11 +149,12 @@ PriQ_pop(PriorityQueue *self) {
 
 VArray*
 PriQ_pop_all(PriorityQueue *self) {
-    VArray *retval = VA_new(self->size);
+    PriorityQueueIVARS *const ivars = PriQ_IVARS(self);
+    VArray *retval = VA_new(ivars->size);
 
     // Map the queue nodes onto the array in reverse order.
-    if (self->size) {
-        for (uint32_t i = self->size; i--;) {
+    if (ivars->size) {
+        for (uint32_t i = ivars->size; i--;) {
             Obj *const elem = PriQ_Pop(self);
             VA_Store(retval, i, elem);
         }
@@ -159,8 +165,9 @@ PriQ_pop_all(PriorityQueue *self) {
 
 Obj*
 PriQ_peek(PriorityQueue *self) {
-    if (self->size > 0) {
-        return self->heap[1];
+    PriorityQueueIVARS *const ivars = PriQ_IVARS(self);
+    if (ivars->size > 0) {
+        return ivars->heap[1];
     }
     else {
         return NULL;
@@ -168,62 +175,63 @@ PriQ_peek(PriorityQueue *self) {
 }
 
 static void
-S_clear(PriorityQueue *self) {
-    Obj **elem_ptr = (self->heap + 1);
+S_clear(PriorityQueue *self, PriorityQueueIVARS *ivars) {
+    UNUSED_VAR(self);
+    Obj **elem_ptr = (ivars->heap + 1);
 
     // Node 0 is held empty, to make the algo clearer.
-    for (uint32_t i = 1; i <= self->size; i++) {
+    for (uint32_t i = 1; i <= ivars->size; i++) {
         DECREF(*elem_ptr);
         *elem_ptr = NULL;
         elem_ptr++;
     }
-    self->size = 0;
+    ivars->size = 0;
 }
 
 static void
-S_up_heap(PriorityQueue *self) {
-    uint32_t i = self->size;
+S_up_heap(PriorityQueue *self, PriorityQueueIVARS *ivars) {
+    uint32_t i = ivars->size;
     uint32_t j = i >> 1;
-    Obj *const node = self->heap[i]; // save bottom node
+    Obj *const node = ivars->heap[i]; // save bottom node
 
     while (j > 0
-           && PriQ_Less_Than(self, node, self->heap[j])
+           && PriQ_Less_Than(self, node, ivars->heap[j])
           ) {
-        self->heap[i] = self->heap[j];
+        ivars->heap[i] = ivars->heap[j];
         i = j;
         j = j >> 1;
     }
-    self->heap[i] = node;
+    ivars->heap[i] = node;
 }
 
 static void
-S_down_heap(PriorityQueue *self) {
+S_down_heap(PriorityQueue *self, PriorityQueueIVARS *ivars) {
     uint32_t i = 1;
     uint32_t j = i << 1;
     uint32_t k = j + 1;
-    Obj *node = self->heap[i]; // save top node
+    Obj *node = ivars->heap[i]; // save top node
 
     // Find smaller child.
-    if (k <= self->size
-        && PriQ_Less_Than(self, self->heap[k], self->heap[j])
+    if (k <= ivars->size
+        && PriQ_Less_Than(self, ivars->heap[k], ivars->heap[j])
        ) {
         j = k;
     }
 
-    while (j <= self->size
-           && PriQ_Less_Than(self, self->heap[j], node)
+    while (j <= ivars->size
+           && PriQ_Less_Than(self, ivars->heap[j], node)
           ) {
-        self->heap[i] = self->heap[j];
+        ivars->heap[i] = ivars->heap[j];
         i = j;
         j = i << 1;
         k = j + 1;
-        if (k <= self->size
-            && PriQ_Less_Than(self, self->heap[k], self->heap[j])
+        if (k <= ivars->size
+            && PriQ_Less_Than(self, ivars->heap[k], ivars->heap[j])
            ) {
             j = k;
         }
     }
-    self->heap[i] = node;
+    ivars->heap[i] = node;
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/9bff835a/core/Lucy/Util/SortExternal.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Util/SortExternal.c b/core/Lucy/Util/SortExternal.c
index 1a220ed..6337ee1 100644
--- a/core/Lucy/Util/SortExternal.c
+++ b/core/Lucy/Util/SortExternal.c
@@ -21,41 +21,44 @@
 
 // Refill the main cache, drawing from the caches of all runs.
 static void
-S_refill_cache(SortExternal *self);
+S_refill_cache(SortExternal *self, SortExternalIVARS *ivars);
 
 // Absorb all the items which are "in-range" from all the Runs into the main
 // cache.
 static void
-S_absorb_slices(SortExternal *self, uint8_t *endpost);
+S_absorb_slices(SortExternal *self, SortExternalIVARS *ivars,
+                uint8_t *endpost);
 
 // Return the address for the item in one of the runs' caches which is the
 // highest in sort order, but which we can guarantee is lower in sort order
 // than any item which has yet to enter a run cache.
 static uint8_t*
-S_find_endpost(SortExternal *self);
+S_find_endpost(SortExternal *self, SortExternalIVARS *ivars);
 
 // Determine how many cache items are less than or equal to [endpost].
 static uint32_t
-S_find_slice_size(SortExternal *self, uint8_t *endpost);
+S_find_slice_size(SortExternal *self, SortExternalIVARS *ivars,
+                  uint8_t *endpost);
 
 SortExternal*
 SortEx_init(SortExternal *self, size_t width) {
+    SortExternalIVARS *const ivars = SortEx_IVARS(self);
     // Assign.
-    self->width        = width;
+    ivars->width        = width;
 
     // Init.
-    self->mem_thresh   = UINT32_MAX;
-    self->cache        = NULL;
-    self->cache_cap    = 0;
-    self->cache_max    = 0;
-    self->cache_tick   = 0;
-    self->scratch      = NULL;
-    self->scratch_cap  = 0;
-    self->runs         = VA_new(0);
-    self->slice_sizes  = NULL;
-    self->slice_starts = NULL;
-    self->num_slices   = 0;
-    self->flipped      = false;
+    ivars->mem_thresh   = UINT32_MAX;
+    ivars->cache        = NULL;
+    ivars->cache_cap    = 0;
+    ivars->cache_max    = 0;
+    ivars->cache_tick   = 0;
+    ivars->scratch      = NULL;
+    ivars->scratch_cap  = 0;
+    ivars->runs         = VA_new(0);
+    ivars->slice_sizes  = NULL;
+    ivars->slice_starts = NULL;
+    ivars->num_slices   = 0;
+    ivars->flipped      = false;
 
     ABSTRACT_CLASS_CHECK(self, SORTEXTERNAL);
     return self;
@@ -63,43 +66,46 @@ SortEx_init(SortExternal *self, size_t width) {
 
 void
 SortEx_destroy(SortExternal *self) {
-    FREEMEM(self->scratch);
-    FREEMEM(self->slice_sizes);
-    FREEMEM(self->slice_starts);
-    if (self->cache) {
+    SortExternalIVARS *const ivars = SortEx_IVARS(self);
+    FREEMEM(ivars->scratch);
+    FREEMEM(ivars->slice_sizes);
+    FREEMEM(ivars->slice_starts);
+    if (ivars->cache) {
         SortEx_Clear_Cache(self);
-        FREEMEM(self->cache);
+        FREEMEM(ivars->cache);
     }
-    DECREF(self->runs);
+    DECREF(ivars->runs);
     SUPER_DESTROY(self, SORTEXTERNAL);
 }
 
 void
 SortEx_clear_cache(SortExternal *self) {
-    self->cache_max    = 0;
-    self->cache_tick   = 0;
+    SortExternalIVARS *const ivars = SortEx_IVARS(self);
+    ivars->cache_max    = 0;
+    ivars->cache_tick   = 0;
 }
 
 void
 SortEx_feed(SortExternal *self, void *data) {
-    const size_t width = self->width;
-    if (self->cache_max == self->cache_cap) {
-        size_t amount = Memory_oversize(self->cache_max + 1, width);
+    SortExternalIVARS *const ivars = SortEx_IVARS(self);
+    const size_t width = ivars->width;
+    if (ivars->cache_max == ivars->cache_cap) {
+        size_t amount = Memory_oversize(ivars->cache_max + 1, width);
         SortEx_Grow_Cache(self, amount);
     }
-    uint8_t *target = self->cache + self->cache_max * width;
+    uint8_t *target = ivars->cache + ivars->cache_max * width;
     memcpy(target, data, width);
-    self->cache_max++;
+    ivars->cache_max++;
 }
 
 static INLINE void*
-SI_peek(SortExternal *self) {
-    if (self->cache_tick >= self->cache_max) {
-        S_refill_cache(self);
+SI_peek(SortExternal *self, SortExternalIVARS *ivars) {
+    if (ivars->cache_tick >= ivars->cache_max) {
+        S_refill_cache(self, ivars);
     }
 
-    if (self->cache_max > 0) {
-        return self->cache + self->cache_tick * self->width;
+    if (ivars->cache_max > 0) {
+        return ivars->cache + ivars->cache_tick * ivars->width;
     }
     else {
         return NULL;
@@ -108,95 +114,100 @@ SI_peek(SortExternal *self) {
 
 void*
 SortEx_fetch(SortExternal *self) {
-    void *address = SI_peek(self);
-    self->cache_tick++;
+    SortExternalIVARS *const ivars = SortEx_IVARS(self);
+    void *address = SI_peek(self, ivars);
+    ivars->cache_tick++;
     return address;
 }
 
 void*
 SortEx_peek(SortExternal *self) {
-    return SI_peek(self);
+    SortExternalIVARS *const ivars = SortEx_IVARS(self);
+    return SI_peek(self, ivars);
 }
 
 void
 SortEx_sort_cache(SortExternal *self) {
-    if (self->cache_tick != 0) {
-        THROW(ERR, "Cant Sort_Cache() after fetching %u32 items", self->cache_tick);
+    SortExternalIVARS *const ivars = SortEx_IVARS(self);
+    if (ivars->cache_tick != 0) {
+        THROW(ERR, "Cant Sort_Cache() after fetching %u32 items", ivars->cache_tick);
     }
-    if (self->cache_max != 0) {
+    if (ivars->cache_max != 0) {
         VTable *vtable = SortEx_Get_VTable(self);
         Cfish_Sort_Compare_t compare
             = (Cfish_Sort_Compare_t)METHOD_PTR(vtable, Lucy_SortEx_Compare);
-        if (self->scratch_cap < self->cache_cap) {
-            self->scratch_cap = self->cache_cap;
-            self->scratch = (uint8_t*)REALLOCATE(
-                                self->scratch,
-                                self->scratch_cap * self->width);
+        if (ivars->scratch_cap < ivars->cache_cap) {
+            ivars->scratch_cap = ivars->cache_cap;
+            ivars->scratch
+                = (uint8_t*)REALLOCATE(ivars->scratch,
+                                       ivars->scratch_cap * ivars->width);
         }
-        Sort_mergesort(self->cache, self->scratch, self->cache_max,
-                       self->width, compare, self);
+        Sort_mergesort(ivars->cache, ivars->scratch, ivars->cache_max,
+                       ivars->width, compare, self);
     }
 }
 
 void
 SortEx_flip(SortExternal *self) {
     SortEx_Flush(self);
-    self->flipped = true;
+    SortEx_IVARS(self)->flipped = true;
 }
 
 void
 SortEx_add_run(SortExternal *self, SortExternal *run) {
-    VA_Push(self->runs, (Obj*)run);
-    uint32_t num_runs = VA_Get_Size(self->runs);
-    self->slice_sizes = (uint32_t*)REALLOCATE(
-                            self->slice_sizes,
-                            num_runs * sizeof(uint32_t));
-    self->slice_starts = (uint8_t**)REALLOCATE(
-                             self->slice_starts,
-                             num_runs * sizeof(uint8_t*));
+    SortExternalIVARS *const ivars = SortEx_IVARS(self);
+    VA_Push(ivars->runs, (Obj*)run);
+    uint32_t num_runs = VA_Get_Size(ivars->runs);
+    ivars->slice_sizes
+        = (uint32_t*)REALLOCATE(ivars->slice_sizes,
+                                num_runs * sizeof(uint32_t));
+    ivars->slice_starts
+        = (uint8_t**)REALLOCATE(ivars->slice_starts,
+                                num_runs * sizeof(uint8_t*));
 }
 
 static void
-S_refill_cache(SortExternal *self) {
+S_refill_cache(SortExternal *self, SortExternalIVARS *ivars) {
     // Reset cache vars.
     SortEx_Clear_Cache(self);
 
     // Make sure all runs have at least one item in the cache.
     uint32_t i = 0;
-    while (i < VA_Get_Size(self->runs)) {
-        SortExternal *const run = (SortExternal*)VA_Fetch(self->runs, i);
+    while (i < VA_Get_Size(ivars->runs)) {
+        SortExternal *const run = (SortExternal*)VA_Fetch(ivars->runs, i);
         if (SortEx_Cache_Count(run) > 0 || SortEx_Refill(run) > 0) {
             i++; // Run has some elements, so keep.
         }
         else {
-            VA_Excise(self->runs, i, 1);
+            VA_Excise(ivars->runs, i, 1);
         }
     }
 
     // Absorb as many elems as possible from all runs into main cache.
-    if (VA_Get_Size(self->runs)) {
-        uint8_t *endpost = S_find_endpost(self);
-        S_absorb_slices(self, endpost);
+    if (VA_Get_Size(ivars->runs)) {
+        uint8_t *endpost = S_find_endpost(self, ivars);
+        S_absorb_slices(self, ivars, endpost);
     }
 }
 
 static uint8_t*
-S_find_endpost(SortExternal *self) {
+S_find_endpost(SortExternal *self, SortExternalIVARS *ivars) {
     uint8_t *endpost = NULL;
-    const size_t width = self->width;
+    const size_t width = ivars->width;
 
-    for (uint32_t i = 0, max = VA_Get_Size(self->runs); i < max; i++) {
+    for (uint32_t i = 0, max = VA_Get_Size(ivars->runs); i < max; i++) {
         // Get a run and retrieve the last item in its cache.
-        SortExternal *const run = (SortExternal*)VA_Fetch(self->runs, i);
-        const uint32_t tick = run->cache_max - 1;
-        if (tick >= run->cache_cap || run->cache_max < 1) {
+        SortExternal *const run = (SortExternal*)VA_Fetch(ivars->runs, i);
+        SortExternalIVARS *const run_ivars = SortEx_IVARS(run);
+        const uint32_t tick = run_ivars->cache_max - 1;
+        if (tick >= run_ivars->cache_cap || run_ivars->cache_max < 1) {
             THROW(ERR, "Invalid SortExternal cache access: %u32 %u32 %u32", tick,
-                  run->cache_max, run->cache_cap);
+                  run_ivars->cache_max, run_ivars->cache_cap);
         }
         else {
             // Cache item with the highest sort value currently held in memory
             // by the run.
-            uint8_t *candidate = run->cache + tick * width;
+            uint8_t *candidate = run_ivars->cache + tick * width;
 
             // If it's the first run, item is automatically the new endpost.
             if (i == 0) {
@@ -213,75 +224,77 @@ S_find_endpost(SortExternal *self) {
 }
 
 static void
-S_absorb_slices(SortExternal *self, uint8_t *endpost) {
-    size_t      width        = self->width;
-    uint32_t    num_runs     = VA_Get_Size(self->runs);
-    uint8_t   **slice_starts = self->slice_starts;
-    uint32_t   *slice_sizes  = self->slice_sizes;
+S_absorb_slices(SortExternal *self, SortExternalIVARS *ivars,
+                uint8_t *endpost) {
+    size_t      width        = ivars->width;
+    uint32_t    num_runs     = VA_Get_Size(ivars->runs);
+    uint8_t   **slice_starts = ivars->slice_starts;
+    uint32_t   *slice_sizes  = ivars->slice_sizes;
     VTable     *vtable       = SortEx_Get_VTable(self);
     Cfish_Sort_Compare_t compare
         = (Cfish_Sort_Compare_t)METHOD_PTR(vtable, Lucy_SortEx_Compare);
 
-    if (self->cache_max != 0) { THROW(ERR, "Can't refill unless empty"); }
+    if (ivars->cache_max != 0) { THROW(ERR, "Can't refill unless empty"); }
 
     // Move all the elements in range into the main cache as slices.
     for (uint32_t i = 0; i < num_runs; i++) {
-        SortExternal *const run = (SortExternal*)VA_Fetch(self->runs, i);
-        uint32_t slice_size = S_find_slice_size(run, endpost);
+        SortExternal *const run = (SortExternal*)VA_Fetch(ivars->runs, i);
+        SortExternalIVARS *const run_ivars = SortEx_IVARS(run);
+        uint32_t slice_size = S_find_slice_size(run, run_ivars, endpost);
 
         if (slice_size) {
             // Move slice content from run cache to main cache.
-            if (self->cache_max + slice_size > self->cache_cap) {
-                size_t cap = Memory_oversize(self->cache_max + slice_size,
+            if (ivars->cache_max + slice_size > ivars->cache_cap) {
+                size_t cap = Memory_oversize(ivars->cache_max + slice_size,
                                              width);
                 SortEx_Grow_Cache(self, cap);
             }
-            memcpy(self->cache + self->cache_max * width,
-                   run->cache + run->cache_tick * width,
+            memcpy(ivars->cache + ivars->cache_max * width,
+                   run_ivars->cache + run_ivars->cache_tick * width,
                    slice_size * width);
-            run->cache_tick += slice_size;
-            self->cache_max += slice_size;
+            run_ivars->cache_tick += slice_size;
+            ivars->cache_max += slice_size;
 
             // Track number of slices and slice sizes.
-            slice_sizes[self->num_slices++] = slice_size;
+            slice_sizes[ivars->num_slices++] = slice_size;
         }
     }
 
     // Transform slice starts from ticks to pointers.
     uint32_t total = 0;
-    for (uint32_t i = 0; i < self->num_slices; i++) {
-        slice_starts[i] = self->cache + total * width;
+    for (uint32_t i = 0; i < ivars->num_slices; i++) {
+        slice_starts[i] = ivars->cache + total * width;
         total += slice_sizes[i];
     }
 
     // The main cache now consists of several slices.  Sort the main cache,
     // but exploit the fact that each slice is already sorted.
-    if (self->scratch_cap < self->cache_cap) {
-        self->scratch_cap = self->cache_cap;
-        self->scratch = (uint8_t*)REALLOCATE(
-                            self->scratch, self->scratch_cap * width);
+    if (ivars->scratch_cap < ivars->cache_cap) {
+        ivars->scratch_cap = ivars->cache_cap;
+        ivars->scratch = (uint8_t*)REALLOCATE(
+                            ivars->scratch, ivars->scratch_cap * width);
     }
 
     // Exploit previous sorting, rather than sort cache naively.
     // Leave the first slice intact if the number of slices is odd. */
-    while (self->num_slices > 1) {
+    while (ivars->num_slices > 1) {
         uint32_t i = 0;
         uint32_t j = 0;
 
-        while (i < self->num_slices) {
-            if (self->num_slices - i >= 2) {
+        while (i < ivars->num_slices) {
+            if (ivars->num_slices - i >= 2) {
                 // Merge two consecutive slices.
                 const uint32_t merged_size = slice_sizes[i] + slice_sizes[i + 1];
                 Sort_merge(slice_starts[i], slice_sizes[i],
-                           slice_starts[i + 1], slice_sizes[i + 1], self->scratch,
-                           self->width, compare, self);
+                           slice_starts[i + 1], slice_sizes[i + 1], ivars->scratch,
+                           ivars->width, compare, self);
                 slice_sizes[j]  = merged_size;
                 slice_starts[j] = slice_starts[i];
-                memcpy(slice_starts[j], self->scratch, merged_size * width);
+                memcpy(slice_starts[j], ivars->scratch, merged_size * width);
                 i += 2;
                 j += 1;
             }
-            else if (self->num_slices - i >= 1) {
+            else if (ivars->num_slices - i >= 1) {
                 // Move single slice pointer.
                 slice_sizes[j]  = slice_sizes[i];
                 slice_starts[j] = slice_starts[i];
@@ -289,26 +302,28 @@ S_absorb_slices(SortExternal *self, uint8_t *endpost) {
                 j += 1;
             }
         }
-        self->num_slices = j;
+        ivars->num_slices = j;
     }
 
-    self->num_slices = 0;
+    ivars->num_slices = 0;
 }
 
 void
 SortEx_grow_cache(SortExternal *self, uint32_t size) {
-    if (size > self->cache_cap) {
-        self->cache = (uint8_t*)REALLOCATE(self->cache, size * self->width);
-        self->cache_cap = size;
+    SortExternalIVARS *const ivars = SortEx_IVARS(self);
+    if (size > ivars->cache_cap) {
+        ivars->cache = (uint8_t*)REALLOCATE(ivars->cache, size * ivars->width);
+        ivars->cache_cap = size;
     }
 }
 
 static uint32_t
-S_find_slice_size(SortExternal *self, uint8_t *endpost) {
-    int32_t          lo      = self->cache_tick - 1;
-    int32_t          hi      = self->cache_max;
-    uint8_t *const   cache   = self->cache;
-    const size_t     width   = self->width;
+S_find_slice_size(SortExternal *self, SortExternalIVARS *ivars,
+                  uint8_t *endpost) {
+    int32_t          lo      = ivars->cache_tick - 1;
+    int32_t          hi      = ivars->cache_max;
+    uint8_t *const   cache   = ivars->cache;
+    const size_t     width   = ivars->width;
     SortEx_Compare_t compare
         = METHOD_PTR(SortEx_Get_VTable(self), Lucy_SortEx_Compare);
 
@@ -323,17 +338,18 @@ S_find_slice_size(SortExternal *self, uint8_t *endpost) {
     // If lo is still -1, we didn't find anything.
     return lo == -1
            ? 0
-           : (lo - self->cache_tick) + 1;
+           : (lo - ivars->cache_tick) + 1;
 }
 
 void
 SortEx_set_mem_thresh(SortExternal *self, uint32_t mem_thresh) {
-    self->mem_thresh = mem_thresh;
+    SortEx_IVARS(self)->mem_thresh = mem_thresh;
 }
 
 uint32_t
 SortEx_cache_count(SortExternal *self) {
-    return self->cache_max - self->cache_tick;
+    SortExternalIVARS *const ivars = SortEx_IVARS(self);
+    return ivars->cache_max - ivars->cache_tick;
 }