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 2009/12/11 06:49:20 UTC

svn commit: r889504 - in /lucene/lucy/trunk: core/Lucy/Index/Segment.bp core/Lucy/Index/Segment.c core/Lucy/Test/Index/ core/Lucy/Test/Index/TestSegment.bp core/Lucy/Test/Index/TestSegment.c perl/lib/Lucy/Test.pm perl/t/core/301-segment.t

Author: marvin
Date: Fri Dec 11 05:49:19 2009
New Revision: 889504

URL: http://svn.apache.org/viewvc?rev=889504&view=rev
Log:
Commit LUCY-87, adding Lucy::Index::Segment.

Added:
    lucene/lucy/trunk/core/Lucy/Index/Segment.bp   (with props)
    lucene/lucy/trunk/core/Lucy/Index/Segment.c   (with props)
    lucene/lucy/trunk/core/Lucy/Test/Index/
    lucene/lucy/trunk/core/Lucy/Test/Index/TestSegment.bp   (with props)
    lucene/lucy/trunk/core/Lucy/Test/Index/TestSegment.c   (with props)
    lucene/lucy/trunk/perl/t/core/301-segment.t   (with props)
Modified:
    lucene/lucy/trunk/perl/lib/Lucy/Test.pm

Added: lucene/lucy/trunk/core/Lucy/Index/Segment.bp
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Index/Segment.bp?rev=889504&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Index/Segment.bp (added)
+++ lucene/lucy/trunk/core/Lucy/Index/Segment.bp Fri Dec 11 05:49:19 2009
@@ -0,0 +1,151 @@
+parcel Lucy;
+
+/** Warehouse for information about one segment of an inverted index.
+ * 
+ * Lucy's indexes are made up of individual "segments", each of which is
+ * is an independent inverted index.  On the file system, each segment is a
+ * directory within the main index directory whose name starts with "seg_":
+ * "seg_2", "seg_5a", etc.
+ *
+ * Each Segment object keeps track of information about an index segment: its
+ * fields, document count, and so on.  The Segment object itself writes one
+ * file, <code>segmeta.json</code>; besides storing info needed by Segment
+ * itself, the "segmeta" file serves as a central repository for metadata
+ * generated by other index components -- relieving them of the burden of
+ * storing metadata themselves.
+ */
+
+class Lucy::Index::Segment cnick Seg extends Lucy::Object::Obj {
+
+    CharBuf     *name;
+    i64_t        count;
+    i64_t        number;
+    Hash        *by_name;   /* field numbers by name */
+    VArray      *by_num;    /* field names by num */
+    Hash        *metadata;
+
+    inert incremented Segment*
+    new(i64_t number);
+
+    public inert Segment*
+    init(Segment *self, i64_t number);
+
+    /** Return a segment name with a base-36-encoded segment number. 
+     */
+    inert incremented CharBuf*
+    num_to_name(i64_t number);
+
+    /** Register a new field and assign it a field number.  If the field was
+     * already known, nothing happens.
+     * 
+     * @param field Field name.
+     * @return the field's field number, which is a positive integer.
+     */
+    public i32_t
+    Add_Field(Segment *self, const CharBuf *field);
+
+    /** Store arbitrary information in the segment's metadata Hash, to be
+     * serialized later.  Throws an error if <code>key</code> is used twice.
+     *
+     * @param key String identifying an index component.
+     * @param metadata JSON-izable data structure.
+     */
+    public void
+    Store_Metadata(Segment *self, const CharBuf *key, 
+                   decremented Obj *metadata);
+
+    void
+    Store_Metadata_Str(Segment *self, const char *key, size_t len, 
+                       decremented Obj *value);
+
+    /** Fetch a value from the Segment's metadata hash.
+     */
+    public Obj*
+    Fetch_Metadata(Segment *self, const CharBuf *key);
+
+    Obj*
+    Fetch_Metadata_Str(Segment *self, const char *key, size_t len);
+
+    /** Given a field name, return its field number for this segment (which
+     * may differ from its number in other segments).  Return 0 (an invalid
+     * field number) if the field name can't be found.  
+     * 
+     * @param field Field name.
+     */
+    public i32_t
+    Field_Num(Segment *self, const CharBuf *field);
+
+    /** Given a field number, return the name of its field, or NULL if the
+     * field name can't be found.
+     */
+    public CharBuf*
+    Field_Name(Segment *self, i32_t field_num);
+
+    /** Getter for the object's seg name.
+     */
+    public CharBuf*
+    Get_Name(Segment *self);
+
+    /** Getter for the segment number. 
+     */
+    public i64_t
+    Get_Number(Segment *self);
+
+    /** Setter for the object's document count.
+     */
+    public void
+    Set_Count(Segment *self, i64_t count);
+
+    /** Getter for the object's document count.
+     */
+    public i64_t 
+    Get_Count(Segment *self);
+
+    /** Add <code>increment</code> to the object's document count, then return
+     * the new, modified total.
+     */
+    i64_t
+    Increment_Count(Segment *self, i64_t increment);
+
+    /** Get the segment metadata.
+     */
+    Hash*
+    Get_Metadata(Segment *self);
+
+    /** Write the segdata file.
+     */
+    public void
+    Write_File(Segment *self, Folder *folder);
+
+    /** Read the segmeta file for this segment.
+     *
+     * @return true if the file is read and decoded successfully, false
+     * otherwise.
+     */
+    public bool_t
+    Read_File(Segment *self, Folder *folder);
+
+    /** Compare by segment number. 
+     */
+    public i32_t
+    Compare_To(Segment *self, Obj *other);
+
+    public void
+    Destroy(Segment *self);
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+

Propchange: lucene/lucy/trunk/core/Lucy/Index/Segment.bp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/lucy/trunk/core/Lucy/Index/Segment.c
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Index/Segment.c?rev=889504&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Index/Segment.c (added)
+++ lucene/lucy/trunk/core/Lucy/Index/Segment.c Fri Dec 11 05:49:19 2009
@@ -0,0 +1,239 @@
+#define C_LUCY_SEGMENT
+#include "Lucy/Util/ToolSet.h"
+
+#include "Lucy/Index/Segment.h"
+#include "Lucy/Store/Folder.h"
+#include "Lucy/Util/Json.h"
+#include "Lucy/Util/StringHelper.h"
+#include "Lucy/Util/IndexFileNames.h"
+
+Segment*
+Seg_new(i64_t number)
+{
+    Segment *self = (Segment*)VTable_Make_Obj(SEGMENT);
+    return Seg_init(self, number);
+}
+
+Segment*
+Seg_init(Segment *self, i64_t number)
+{
+    /* 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);
+
+    /* Start field numbers at 1, not 0. */
+    VA_Push(self->by_num, INCREF(&EMPTY));
+
+    /* Assign. */
+    self->number = number;
+
+    /* Derive. */
+    self->name = Seg_num_to_name(number);
+
+    return self;
+}
+
+CharBuf*
+Seg_num_to_name(i64_t number)
+{
+    char base36[StrHelp_MAX_BASE36_BYTES];
+    StrHelp_to_base36(number, &base36);
+    return CB_newf("seg_%s", &base36);
+}
+
+void
+Seg_destroy(Segment *self)
+{
+    DECREF(self->name);
+    DECREF(self->metadata);
+    DECREF(self->by_name);
+    DECREF(self->by_num);
+    SUPER_DESTROY(self, SEGMENT);
+}
+
+bool_t
+Seg_read_file(Segment *self, Folder *folder)
+{
+    CharBuf *filename = CB_newf("%o/segmeta.json", self->name);
+    Hash    *metadata = (Hash*)Json_slurp_json(folder, filename);
+    Hash    *my_metadata;
+
+    /* Bail unless the segmeta file was read successfully. */
+    DECREF(filename);
+    if (!metadata) { return false; }
+    CERTIFY(metadata, HASH);
+
+    /* Grab metadata for the Segment object itself. */
+    DECREF(self->metadata);
+    self->metadata = metadata;
+    my_metadata = (Hash*)CERTIFY(
+        Hash_Fetch_Str(self->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); }
+    }
+
+    /* Get list of field nums. */
+    {
+        u32_t i;
+        VArray *source_by_num = (VArray*)Hash_Fetch_Str(my_metadata, 
+            "field_names", 11);
+        u32_t num_fields = source_by_num ? VA_Get_Size(source_by_num) : 0;
+        if (source_by_num == NULL) {
+            THROW(ERR, "Failed to extract 'field_names' from metadata");
+        }
+
+        /* Init. */
+        DECREF(self->by_num);
+        DECREF(self->by_name);
+        self->by_num  = VA_new(num_fields);
+        self->by_name = Hash_new(num_fields);
+
+        /* Copy the list of fields from the source. */
+        for (i = 0; i < num_fields; i++) {
+            CharBuf *name = (CharBuf*)VA_Fetch(source_by_num, i);
+            Seg_Add_Field(self, name);
+        }
+    }
+
+    return true;
+}
+
+void
+Seg_write_file(Segment *self, Folder *folder)
+{
+    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));
+    Hash_Store_Str(my_metadata, "format", 6, (Obj*)CB_newf("%i32", 1));
+    Hash_Store_Str(self->metadata, "segmeta", 7, (Obj*)my_metadata);
+
+    {
+        CharBuf *filename = CB_newf("%o/segmeta.json", self->name);
+        bool_t result 
+            = Json_spew_json((Obj*)self->metadata, folder, filename);
+        DECREF(filename);
+        if (!result) { RETHROW(INCREF(Err_get_error())); }
+    }
+}
+
+i32_t 
+Seg_add_field(Segment *self, const CharBuf *field)
+{
+    Integer32 *num = (Integer32*)Hash_Fetch(self->by_name, (Obj*)field);
+    if (num) {
+        return Int32_Get_Value(num);
+    }
+    else {
+        i32_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));
+        return field_num;
+    }
+}
+
+CharBuf*
+Seg_get_name(Segment *self)               { return self->name; }
+i64_t
+Seg_get_number(Segment *self)             { return self->number; }
+void
+Seg_set_count(Segment *self, i64_t count) { self->count = count; }
+i64_t
+Seg_get_count(Segment *self)              { return self->count; }
+
+i64_t
+Seg_increment_count(Segment *self, i64_t increment) 
+{ 
+   self->count += increment;
+   return self->count;
+}
+
+void
+Seg_store_metadata(Segment *self, const CharBuf *key, Obj *value)
+{
+    if (Hash_Fetch(self->metadata, (Obj*)key)) {
+        THROW(ERR, "Metadata key '%o' already registered", key);
+    }
+    Hash_Store(self->metadata, (Obj*)key, value);
+}
+
+void
+Seg_store_metadata_str(Segment *self, const char *key, size_t key_len, 
+                       Obj *value)
+{
+    ZombieCharBuf k = ZCB_make_str((char*)key, key_len);
+    Seg_Store_Metadata(self, (CharBuf*)&k, value);
+}
+
+Obj*
+Seg_fetch_metadata(Segment *self, const CharBuf *key)
+{
+    return Hash_Fetch(self->metadata, (Obj*)key);
+}
+
+Obj*
+Seg_fetch_metadata_str(Segment *self, const char *key, size_t len)
+{
+    return Hash_Fetch_Str(self->metadata, key, len);
+}
+
+Hash*
+Seg_get_metadata(Segment *self) { return self->metadata; }
+    
+i32_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;  }
+}
+
+CharBuf*
+Seg_field_name(Segment *self, i32_t field_num)
+{
+     return field_num 
+        ? (CharBuf*)VA_Fetch(self->by_num, field_num)
+        : NULL;
+}
+
+i32_t
+Seg_field_num(Segment *self, const CharBuf *field)
+{
+    if (field == NULL) {
+        return 0;
+    }
+    else {
+        Integer32 *num = (Integer32*)Hash_Fetch(self->by_name, (Obj*)field);
+        return num ? Int32_Get_Value(num) : 0;
+    }
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+

Propchange: lucene/lucy/trunk/core/Lucy/Index/Segment.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/lucy/trunk/core/Lucy/Test/Index/TestSegment.bp
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Test/Index/TestSegment.bp?rev=889504&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Test/Index/TestSegment.bp (added)
+++ lucene/lucy/trunk/core/Lucy/Test/Index/TestSegment.bp Fri Dec 11 05:49:19 2009
@@ -0,0 +1,22 @@
+parcel Lucy;
+
+inert class Lucy::Test::Index::TestSegment cnick TestSeg {
+    inert void
+    run_tests();
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+

Propchange: lucene/lucy/trunk/core/Lucy/Test/Index/TestSegment.bp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/lucy/trunk/core/Lucy/Test/Index/TestSegment.c
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Test/Index/TestSegment.c?rev=889504&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Test/Index/TestSegment.c (added)
+++ lucene/lucy/trunk/core/Lucy/Test/Index/TestSegment.c Fri Dec 11 05:49:19 2009
@@ -0,0 +1,168 @@
+#define C_LUCY_TESTSEG
+#include "Lucy/Util/ToolSet.h"
+
+#include "Lucy/Test.h"
+#include "Lucy/Test/Index/TestSegment.h"
+#include "Lucy/Index/Segment.h"
+#include "Lucy/Store/RAMFolder.h"
+
+static void
+test_fields(TestBatch *batch)
+{
+    Segment *segment = Seg_new(1);
+    ZombieCharBuf foo = ZCB_LITERAL("foo");
+    ZombieCharBuf bar = ZCB_LITERAL("bar");
+    ZombieCharBuf baz = ZCB_LITERAL("baz");
+    i32_t field_num; 
+    
+    field_num = Seg_Add_Field(segment, (CharBuf*)&foo);
+    ASSERT_TRUE(batch, field_num == 1, 
+        "Add_Field returns field number, and field numbers start at 1");
+    field_num = Seg_Add_Field(segment, (CharBuf*)&bar);
+    ASSERT_TRUE(batch, field_num == 2, "add a second field");
+    field_num = Seg_Add_Field(segment, (CharBuf*)&foo);
+    ASSERT_TRUE(batch, field_num == 1,
+        "Add_Field returns existing field number if field is already known");
+
+    ASSERT_TRUE(batch, ZCB_Equals(&bar, (Obj*)Seg_Field_Name(segment, 2)),
+        "Field_Name");
+    ASSERT_TRUE(batch, Seg_Field_Name(segment, 3) == NULL, 
+        "Field_Name returns NULL for unknown field number");
+    ASSERT_TRUE(batch, Seg_Field_Num(segment, (CharBuf*)&bar) == 2,
+        "Field_Num");
+    ASSERT_TRUE(batch, Seg_Field_Num(segment, (CharBuf*)&baz) == 0, 
+        "Field_Num returns 0 for unknown field name");
+
+    DECREF(segment);
+}
+
+static void
+test_metadata_storage(TestBatch *batch)
+{
+    Segment *segment = Seg_new(1);
+    Obj *got;
+
+    Seg_Store_Metadata_Str(segment, "foo", 3, (Obj*)CB_newf("bar"));
+    got = Seg_Fetch_Metadata_Str(segment, "foo", 3);
+    ASSERT_TRUE(batch, 
+                   got 
+                && Obj_Is_A(got, CHARBUF) 
+                && CB_Equals_Str(got, "bar", 3), 
+                "metadata round trip");
+    DECREF(segment);
+}
+
+static void
+test_seg_name_and_num(TestBatch *batch)
+{
+    Segment *segment_z = Seg_new(35);
+    CharBuf *seg_z_name = Seg_num_to_name(35);
+    ASSERT_TRUE(batch, Seg_Get_Number(segment_z) == I64_C(35), "Get_Number");
+    ASSERT_TRUE(batch, CB_Equals_Str(Seg_Get_Name(segment_z), "seg_z", 5), 
+        "Get_Name");
+    ASSERT_TRUE(batch, CB_Equals_Str(seg_z_name, "seg_z", 5), 
+        "num_to_name");
+    DECREF(seg_z_name);
+    DECREF(segment_z);
+}
+
+static void
+test_count(TestBatch *batch)
+{
+    Segment *segment = Seg_new(100);
+    
+    ASSERT_TRUE(batch, Seg_Get_Count(segment) == 0, "count starts off at 0");
+    Seg_Set_Count(segment, 120);
+    ASSERT_TRUE(batch, Seg_Get_Count(segment) == 120, "Set_Count");
+    ASSERT_TRUE(batch, Seg_Increment_Count(segment, 10) == 130,
+        "Increment_Count");
+
+    DECREF(segment);
+}
+
+static void
+test_Compare_To(TestBatch *batch)
+{
+    Segment *segment_1      = Seg_new(1);
+    Segment *segment_2      = Seg_new(2);
+    Segment *also_segment_2 = Seg_new(2);
+
+    ASSERT_TRUE(batch, Seg_Compare_To(segment_1, (Obj*)segment_2) < 0, 
+        "Compare_To 1 < 2");
+    ASSERT_TRUE(batch, Seg_Compare_To(segment_2, (Obj*)segment_1) > 0, 
+        "Compare_To 1 < 2");
+    ASSERT_TRUE(batch, Seg_Compare_To(segment_1, (Obj*)segment_1) == 0, 
+        "Compare_To identity");
+    ASSERT_TRUE(batch, Seg_Compare_To(segment_2, (Obj*)also_segment_2) == 0, 
+        "Compare_To 2 == 2");
+
+    DECREF(segment_1);
+    DECREF(segment_2);
+    DECREF(also_segment_2);
+}
+
+static void
+test_Write_File_and_Read_File(TestBatch *batch)
+{
+    RAMFolder *folder  = RAMFolder_new(NULL);
+    Segment   *segment = Seg_new(100);
+    Segment   *got     = Seg_new(100);
+    Obj       *meta;
+    ZombieCharBuf flotsam = ZCB_LITERAL("flotsam");
+    ZombieCharBuf jetsam  = ZCB_LITERAL("jetsam");
+
+    Seg_Set_Count(segment, 111);
+    Seg_Store_Metadata_Str(segment, "foo", 3, (Obj*)CB_newf("bar"));
+    Seg_Add_Field(segment, (CharBuf*)&flotsam);
+    Seg_Add_Field(segment, (CharBuf*)&jetsam);
+    
+    RAMFolder_MkDir(folder, Seg_Get_Name(segment));
+    Seg_Write_File(segment, (Folder*)folder);
+    Seg_Read_File(got, (Folder*)folder);
+
+    ASSERT_TRUE(batch, Seg_Get_Count(got) == Seg_Get_Count(segment), 
+        "Round-trip count through file");
+    ASSERT_TRUE(batch, 
+           Seg_Field_Num(got, (CharBuf*)&jetsam) 
+        == Seg_Field_Num(segment, (CharBuf*)&jetsam), 
+        "Round trip field names through file");
+    meta = Seg_Fetch_Metadata_Str(got, "foo", 3);
+    ASSERT_TRUE(batch, meta && Obj_Is_A(meta, CHARBUF) 
+        && CB_Equals_Str(meta, "bar", 3), "Round trip metadata through file");
+
+    DECREF(got);
+    DECREF(segment);
+    DECREF(folder);
+}
+
+void
+TestSeg_run_tests()
+{
+    TestBatch *batch = Test_new_batch("TestSegment", 21, NULL);
+
+    PLAN(batch);
+    test_fields(batch);
+    test_metadata_storage(batch);
+    test_seg_name_and_num(batch);
+    test_count(batch);
+    test_Compare_To(batch);
+    test_Write_File_and_Read_File(batch);
+
+    batch->destroy(batch);
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+

Propchange: lucene/lucy/trunk/core/Lucy/Test/Index/TestSegment.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: lucene/lucy/trunk/perl/lib/Lucy/Test.pm
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/perl/lib/Lucy/Test.pm?rev=889504&r1=889503&r2=889504&view=diff
==============================================================================
--- lucene/lucy/trunk/perl/lib/Lucy/Test.pm (original)
+++ lucene/lucy/trunk/perl/lib/Lucy/Test.pm Fri Dec 11 05:49:19 2009
@@ -14,8 +14,12 @@
     char *package;
 PPCODE:
 {
+    /* Lucy::Index */
+    if (strEQ(package, "TestSegment")) {
+        lucy_TestSeg_run_tests();
+    }
     /* Lucy::Object */
-    if (strEQ(package, "TestObj")) {
+    else if (strEQ(package, "TestObj")) {
         lucy_TestObj_run_tests();
     }
     else if (strEQ(package, "TestBitVector")) {

Added: lucene/lucy/trunk/perl/t/core/301-segment.t
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/perl/t/core/301-segment.t?rev=889504&view=auto
==============================================================================
--- lucene/lucy/trunk/perl/t/core/301-segment.t (added)
+++ lucene/lucy/trunk/perl/t/core/301-segment.t Fri Dec 11 05:49:19 2009
@@ -0,0 +1,6 @@
+use strict;
+use warnings;
+
+use Lucy::Test;
+Lucy::Test::run_tests("TestSegment");
+

Propchange: lucene/lucy/trunk/perl/t/core/301-segment.t
------------------------------------------------------------------------------
    svn:eol-style = native