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:25 UTC

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

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;
 }