Mailing List Archive

r3712 - in trunk: c_src/KinoSearch c_src/KinoSearch/Index perl/lib perl/lib/KinoSearch perl/lib/KinoSearch/Index perl/t
Author: creamyg
Date: 2008-08-04 12:23:35 -0700 (Mon, 04 Aug 2008)
New Revision: 3712

Modified:
trunk/c_src/KinoSearch/Index/IndexReader.bp
trunk/c_src/KinoSearch/Index/IndexReader.c
trunk/c_src/KinoSearch/Searcher.c
trunk/perl/lib/KinoSearch.pm
trunk/perl/lib/KinoSearch/Index/IndexReader.pm
trunk/perl/lib/KinoSearch/Searcher.pm
trunk/perl/t/109-read_locking.t
Log:
Port most of IndexReader->open to C (everything except for the section that
has to use the native exception mechanism). Clear out a bunch of XS code and
turn some methods into static functions. Simplify Searcher constructor, since
IxReader_open() now works from C.


Modified: trunk/c_src/KinoSearch/Index/IndexReader.bp
===================================================================
--- trunk/c_src/KinoSearch/Index/IndexReader.bp 2008-08-04 16:30:44 UTC (rev 3711)
+++ trunk/c_src/KinoSearch/Index/IndexReader.bp 2008-08-04 19:23:35 UTC (rev 3712)
@@ -51,6 +51,13 @@
init(IndexReader *self, InvIndex *invindex, Snapshot *snapshot = NULL,
LockFactory *lock_factory = NULL);

+ static IndexReader*
+ do_open(IndexReader *self, InvIndex *invindex, Snapshot *snapshot = NULL,
+ LockFactory *lock_factory = NULL);
+
+ static CharBuf* race_condition_debug1;
+ static i32_t debug1_num_passes;
+
/** Return the maximum number of documents available to the reader, which
* is also the largest possible document number. Documents which have
* been marked as deleted but not yet purged from the index are included
@@ -147,18 +154,6 @@
void
Close(IndexReader *self);

- /* Obtain/release read locks and commit locks. If self->lock_factory is
- * NULL, do nothing.
- *
- * These should all be static helper methods, but they have to be exposed
- * because they are needed by IxReader_Open and IxReader_Open has to be
- * implemented natively (because it uses the native catch() mechanism).
- */
- void Obtain_Read_Lock(IndexReader *self, const CharBuf *snapshot_filename);
- void Obtain_Commit_Lock(IndexReader *self);
- void Release_Read_Lock(IndexReader *self);
- void Release_Commit_Lock(IndexReader *self);
-
InvIndex*
Get_InvIndex(IndexReader *self);


Modified: trunk/c_src/KinoSearch/Index/IndexReader.c
===================================================================
--- trunk/c_src/KinoSearch/Index/IndexReader.c 2008-08-04 16:30:44 UTC (rev 3711)
+++ trunk/c_src/KinoSearch/Index/IndexReader.c 2008-08-04 19:23:35 UTC (rev 3712)
@@ -8,6 +8,7 @@
#include "KinoSearch/Index/LexCache.h"
#include "KinoSearch/Index/Lexicon.h"
#include "KinoSearch/Index/MultiLexicon.h"
+#include "KinoSearch/Index/MultiReader.h"
#include "KinoSearch/Index/PostingList.h"
#include "KinoSearch/Index/Snapshot.h"
#include "KinoSearch/FieldSpec.h"
@@ -20,16 +21,40 @@
#include "KinoSearch/Util/IntMap.h"
#include "KinoSearch/Util/Native.h"

+static IndexReader*
+open_multi_or_segreader(IndexReader *self);
+
+/* Obtain/release read locks and commit locks. If self->lock_factory is
+ * NULL, do nothing */
+static void
+obtain_read_lock(IndexReader *self, const CharBuf *snapshot_filename);
+static void
+obtain_commit_lock(IndexReader *self);
+static void
+release_read_lock(IndexReader *self);
+static void
+release_commit_lock(IndexReader *self);
+
IndexReader*
IxReader_open(InvIndex *invindex, Snapshot *snapshot,
LockFactory *lock_factory)
{
- return (IndexReader*)Native_callback_obj(&INDEXREADER, "open", 3,
- ARG_OBJ("invindex", invindex), ARG_OBJ("snapshot", snapshot),
- ARG_OBJ("lock_factory", lock_factory));
+ IndexReader *temp_self = (IndexReader*)CREATE(NULL, INDEXREADER);
+ return IxReader_do_open(temp_self, invindex, snapshot, lock_factory);
}

IndexReader*
+IxReader_do_open(IndexReader *temp_self, InvIndex *invindex, Snapshot *snapshot,
+ LockFactory *lock_factory)
+{
+ IndexReader *self;
+ IxReader_init(temp_self, invindex, snapshot, lock_factory);
+ self = open_multi_or_segreader(temp_self);
+ REFCOUNT_DEC(temp_self);
+ return self;
+}
+
+IndexReader*
IxReader_init(IndexReader *self, InvIndex *invindex, Snapshot *snapshot,
LockFactory *lock_factory)
{
@@ -47,6 +72,147 @@
return self;
}

+/** Attempt to open a SegReader for each SegInfo that the Snapshot knows
+ * about. If an exception occurs, catch it and return its error message. If
+ * the opening succeeds, return a VArray full of SegReaders.
+ */
+static Obj*
+try_open_segreaders(InvIndex *invindex, Snapshot *snapshot,
+ LockFactory *lock_factory)
+{
+ return Native_callback_obj(&INDEXREADER, "try_open_segreaders", 3,
+ ARG_OBJ("invindex", invindex), ARG_OBJ("snapshot", snapshot),
+ ARG_OBJ("lock_factory", lock_factory));
+}
+
+/* For test suite. */
+CharBuf* IxReader_race_condition_debug1 = NULL;
+i32_t IxReader_debug1_num_passes = 0;
+
+static IndexReader*
+open_multi_or_segreader(IndexReader *self)
+{
+ InvIndex *invindex = self->invindex;
+ Schema *schema = InvIndex_Get_Schema(invindex);
+ Folder *folder = InvIndex_Get_Folder(invindex);
+ LockFactory *lock_factory = self->lock_factory;
+ i32_t last_gen = -1;
+ VArray *seg_readers;
+ IndexReader *true_self;
+
+ if (lock_factory) obtain_commit_lock(self);
+
+ while (1) {
+ CharBuf *latest_snapshot_file = Folder_Latest_Snapshot_File(folder);
+ i32_t gen = 0;
+ Snapshot *snapshot;
+
+ if (!latest_snapshot_file) {
+ CONFESS("Index doesn't seem to contain any data");
+ }
+ else {
+ /* Derive generation from filename. */
+ ZombieCharBuf temp = ZCB_make(latest_snapshot_file);
+ ZCB_Nip(&temp, sizeof("snapshot_") - 1);
+ gen = ZCB_BaseX_To_I64(&temp, 36);
+ }
+
+ /* Get a read lock on the most recent snapshot file if indicated. */
+ if (lock_factory) {
+ obtain_read_lock(self, latest_snapshot_file);
+ }
+
+ /* Testing only. */
+ if (IxReader_race_condition_debug1) {
+ ZombieCharBuf temp = ZCB_LITERAL("temp");
+ if (Folder_File_Exists(folder, (CharBuf*)&temp)) {
+ Folder_Rename_File(folder, (CharBuf*)&temp,
+ IxReader_race_condition_debug1);
+ }
+ IxReader_debug1_num_passes++;
+ }
+
+ if (self->snapshot) {
+ /* Either use the passed-in snapshot... */
+ snapshot = REFCOUNT_INC(self->snapshot);
+ }
+ else {
+ /* ... or read the most recent snapshot file. */
+ snapshot = Snapshot_new(schema);
+ Snapshot_Read_Snapshot(snapshot, folder, NULL);
+ }
+
+ /* Throw an error if index doesn't exist. */
+ if (!Snapshot_Size(snapshot)) {
+ REFCOUNT_DEC(snapshot);
+ REFCOUNT_DEC(latest_snapshot_file);
+ CONFESS("Index doesn't seem to contain any data");
+ }
+
+ /* Deal with race condition between locking and reading snapshot. */
+ if ((i32_t)snapshot->generation > gen) {
+ release_read_lock(self);
+ REFCOUNT_DEC(snapshot);
+ REFCOUNT_DEC(latest_snapshot_file);
+ continue;
+ }
+
+ /* It's possible, though unlikely, for an InvIndexer to delete files
+ * out from underneath us after the snapshot file is read but before
+ * we've got SegReaders holding open all the required files. If we
+ * failed to open something, see if we can find a newer snapshot file.
+ * If we can, then the exception was due to the race condition. If
+ * not, we have a real exception, so throw an error. */
+ {
+ Obj *result = try_open_segreaders(invindex, snapshot, lock_factory);
+ if (OBJ_IS_A(result, CHARBUF)) { /* Error occurred. */
+ release_read_lock(self);
+ if (last_gen == gen) {
+ if (lock_factory) release_commit_lock(self);
+ Carp_do_confess((CharBuf*)result);
+ }
+ last_gen = gen;
+ REFCOUNT_DEC(latest_snapshot_file);
+ REFCOUNT_DEC(snapshot);
+ snapshot = NULL;
+ }
+ else { /* Succeeded. */
+ seg_readers = (VArray*)result;
+ REFCOUNT_DEC(latest_snapshot_file);
+ REFCOUNT_DEC(self->snapshot);
+ self->snapshot = snapshot;
+ break;
+ }
+ }
+ }
+
+ if (lock_factory) release_commit_lock(self);
+
+ /** If there's one SegReader use it; otherwise make a MultiReader. */
+ if (seg_readers->size == 1) {
+ true_self = (IndexReader*)VA_Fetch(seg_readers, 0);
+ REFCOUNT_INC(true_self);
+ }
+ else {
+ true_self = (IndexReader*)MultiReader_new(invindex, self->snapshot,
+ lock_factory, seg_readers);
+ }
+
+ /* Copy crucial elements. */
+ if (self->read_lock) true_self->read_lock = REFCOUNT_INC(self->read_lock);
+
+ /* Thwart release of lock on destruction of temp self. */
+ REFCOUNT_DEC(self->read_lock);
+ REFCOUNT_DEC(self->commit_lock);
+ REFCOUNT_DEC(self->lock_factory);
+ self->read_lock = NULL;
+ self->commit_lock = NULL;
+ self->lock_factory = NULL;
+
+ REFCOUNT_DEC(seg_readers);
+ return true_self;
+}
+
IntMap*
IxReader_fetch_sort_cache(IndexReader *self, const CharBuf *field_name)
{
@@ -90,8 +256,8 @@
return sort_cache;
}

-void
-IxReader_obtain_commit_lock(IndexReader *self)
+static void
+obtain_commit_lock(IndexReader *self)
{
self->commit_lock = LockFact_Make_Lock(self->lock_factory,
(CharBuf*)&IxFileNames_commit_lock_name, IxFileNames_commit_lock_timeout);
@@ -103,8 +269,8 @@
}
}

-void
-IxReader_obtain_read_lock(IndexReader *self, const CharBuf *snapshot_file_name)
+static void
+obtain_read_lock(IndexReader *self, const CharBuf *snapshot_file_name)
{
ZombieCharBuf lock_name = ZCB_BLANK;

@@ -134,9 +300,8 @@
}
}

-
-void
-IxReader_release_read_lock(IndexReader *self)
+static void
+release_read_lock(IndexReader *self)
{
if (self->read_lock) {
Lock_Release(self->read_lock);
@@ -145,8 +310,8 @@
}
}

-void
-IxReader_release_commit_lock(IndexReader *self)
+static void
+release_commit_lock(IndexReader *self)
{
if (self->commit_lock) {
Lock_Release(self->commit_lock);
@@ -168,7 +333,7 @@
void
IxReader_close(IndexReader *self)
{
- if (self->read_lock) IxReader_release_read_lock(self);
+ if (self->read_lock) release_read_lock(self);
}

void

Modified: trunk/c_src/KinoSearch/Searcher.c
===================================================================
--- trunk/c_src/KinoSearch/Searcher.c 2008-08-04 16:30:44 UTC (rev 3711)
+++ trunk/c_src/KinoSearch/Searcher.c 2008-08-04 19:23:35 UTC (rev 3712)
@@ -23,12 +23,19 @@
Searcher*
Searcher_init(Searcher *self, InvIndex *invindex, IndexReader *reader)
{
- if (reader) invindex = reader->invindex;
+ if (!invindex) {
+ if (reader) invindex = reader->invindex;
+ else CONFESS("either invindex or reader is required");
+ }
/* else reader = IndexReader_open(invindex, NULL); */ /* TODO */
- else CONFESS("reader is required");
Searchable_init((Searchable*)self, InvIndex_Get_Schema(invindex));
- self->reader = REFCOUNT_INC(reader);
- self->invindex = REFCOUNT_INC(invindex);
+ self->invindex = REFCOUNT_INC(invindex);
+ if (reader) {
+ self->reader = REFCOUNT_INC(reader);
+ }
+ else {
+ self->reader = IxReader_open(invindex, NULL, NULL);
+ }
return self;
}


Modified: trunk/perl/lib/KinoSearch/Index/IndexReader.pm
===================================================================
--- trunk/perl/lib/KinoSearch/Index/IndexReader.pm 2008-08-04 16:30:44 UTC (rev 3711)
+++ trunk/perl/lib/KinoSearch/Index/IndexReader.pm 2008-08-04 19:23:35 UTC (rev 3712)
@@ -9,85 +9,21 @@
MODULE = KinoSearch PACKAGE = KinoSearch::Index::IndexReader

void
-delete_by_term(self, field, term)
- kino_IndexReader *self;
- kino_CharBuf *field;
- kino_Obj *term;
+set_race_condition_debug1(val_sv)
+ SV *val_sv;
PPCODE:
- ABSTRACT_METHOD_CHECK(self, IxReader, Delete_By_Term, delete_by_term);
- Kino_IxReader_Delete_By_Term(self, field, term);
+ REFCOUNT_DEC(kino_IxReader_race_condition_debug1);
+ kino_IxReader_race_condition_debug1 =
+ (kino_CharBuf*)MAYBE_SV_TO_KOBJ(val_sv, &KINO_CHARBUF);
+ if (kino_IxReader_race_condition_debug1)
+ REFCOUNT_INC(kino_IxReader_race_condition_debug1);

-void
-_set_or_get(self, ...)
- kino_IndexReader *self;
-ALIAS:
- get_invindex = 2
- set_lock_factory = 3
- get_lock_factory = 4
- get_schema = 6
- get_lex_caches = 8
- set_snapshot = 9
- get_snapshot = 10
- set_read_lock = 11
- get_read_lock = 12
- set_commit_lock = 13
- get_commit_lock = 14
-PPCODE:
-{
- START_SET_OR_GET_SWITCH
+chy_i32_t
+debug1_num_passes()
+CODE:
+ RETVAL = kino_IxReader_debug1_num_passes;
+OUTPUT: RETVAL

- case 2: retval = Kino_Obj_To_Native(self->invindex);
- break;
-
- case 3: REFCOUNT_DEC(self->lock_factory);
- self->lock_factory = (kino_LockFactory*)MAYBE_SV_TO_KOBJ(
- ST(1), &KINO_LOCKFACTORY);
- if (self->lock_factory != NULL)
- (void)REFCOUNT_INC(self->lock_factory);
- break;
-
- case 4: KOBJ_TO_SV(self->lock_factory, retval);
- break;
-
- case 6: retval = Kino_Obj_To_Native(self->invindex->schema);
- break;
-
- case 8: retval = Kino_Obj_To_Native(self->lex_caches);
- break;
-
- case 9: REFCOUNT_DEC(self->snapshot);
- self->snapshot = (kino_Snapshot*)MAYBE_SV_TO_KOBJ(
- ST(1), &KINO_SNAPSHOT);
- if (self->snapshot != NULL)
- (void)REFCOUNT_INC(self->snapshot);
- break;
-
- case 10: KOBJ_TO_SV(self->snapshot, retval);
- break;
-
- case 11: REFCOUNT_DEC(self->read_lock);
- self->read_lock = (kino_SharedLock*)MAYBE_SV_TO_KOBJ(
- ST(1), &KINO_SHAREDLOCK );
- if (self->read_lock != NULL)
- (void)REFCOUNT_INC(self->read_lock);
- break;
-
- case 12: KOBJ_TO_SV(self->read_lock, retval);
- break;
-
- case 13: REFCOUNT_DEC(self->commit_lock);
- self->commit_lock = (kino_Lock*)MAYBE_SV_TO_KOBJ(
- ST(1), &KINO_LOCK );
- if (self->commit_lock != NULL)
- (void)REFCOUNT_INC(self->commit_lock);
- break;
-
- case 14: KOBJ_TO_SV(self->commit_lock, retval);
- break;
-
- END_SET_OR_GET_SWITCH
-}
-
__AUTO_XS__

my $synopsis = <<'END_SYNOPSIS';
@@ -119,12 +55,12 @@
segreaders
fetch_sort_cache
close
- obtain_read_lock
- obtain_commit_lock
- release_read_lock
- release_commit_lock )
+ get_invindex
+ get_folder
+ get_schema
+ )
],
- make_constructors => ["_new"],
+ make_constructors => ['open|do_open'],
make_pod => {
synopsis => $synopsis,
constructor => {

Modified: trunk/perl/lib/KinoSearch/Searcher.pm
===================================================================
--- trunk/perl/lib/KinoSearch/Searcher.pm 2008-08-04 16:30:44 UTC (rev 3711)
+++ trunk/perl/lib/KinoSearch/Searcher.pm 2008-08-04 19:23:35 UTC (rev 3712)
@@ -27,7 +27,7 @@

{ "KinoSearch::Searcher" => {
bind_methods => [qw( get_reader )],
- make_constructors => ["_new"],
+ make_constructors => ["new"],
make_pod => {
synopsis => $synopsis,
constructor => { sample => $constructor },

Modified: trunk/perl/lib/KinoSearch.pm
===================================================================
--- trunk/perl/lib/KinoSearch.pm 2008-08-04 16:30:44 UTC (rev 3711)
+++ trunk/perl/lib/KinoSearch.pm 2008-08-04 19:23:35 UTC (rev 3712)
@@ -373,161 +373,35 @@
package KinoSearch::Index::IndexReader;
use KinoSearch::Util::ToolSet qw( confess a_isa_b );

- # Test code will define these as coderefs.
- our $debug1;
- our $debug2;
-
- use KinoSearch::Util::StringHelper qw( from_base36 );
-
- sub open {
- my $temp = _new(@_);
- return $temp->_open_multi_or_segreader;
- }
-
sub new {
confess(
- "IndexReader is an abstract class; use IndexReader->open instead")
- if $_[0] eq __PACKAGE__;
- return _new(@_);
+ "IndexReader is an abstract class; use open() instead of new()" );
}

- # Returns a subclass of IndexReader: either a MultiReader or a SegReader,
- # depending on whether an InvIndex contains more than one segment.
- sub _open_multi_or_segreader {
- my $self = shift;
-
- # Verify InvIndex and extract schema.
- my $invindex = $self->get_invindex;
- confess("Missing required arg 'invindex'")
- unless a_isa_b( $invindex, "KinoSearch::InvIndex" );
- my $schema = $invindex->get_schema;
- my $folder = $invindex->get_folder;
-
- # Confirm lock factory if supplied.
- my $lock_factory = $self->get_lock_factory;
- if ( defined $lock_factory ) {
- confess("Not a KinoSearch::Store::LockFactory")
- unless a_isa_b( $lock_factory,
- "KinoSearch::Store::LockFactory" );
- }
-
- $self->obtain_commit_lock if defined $lock_factory;
-
- my $snapshot;
- my @seg_readers;
- my ( $gen, $last_gen );
- while (1) {
- eval {
- # Find the most recent snapshot file.
- my $latest_snapshot_file = $folder->latest_snapshot_file;
- confess("Index doesn't seem to contain any data")
- unless defined $latest_snapshot_file;
- $latest_snapshot_file =~ /snapshot_(\w+)/
- or die "Strange snapshot name: $latest_snapshot_file";
- $gen = from_base36($1);
-
- # Get a read lock on the most recent snapshot file if
- # indicated.
- if ( defined $lock_factory ) {
- $self->obtain_read_lock($latest_snapshot_file);
- }
-
- $debug1->() if defined $debug1;
-
- if ( defined $self->get_snapshot ) {
- # Either use the passed-in snapshot...
- $snapshot = $self->get_snapshot;
- }
- else {
- # ... or read the most recent snapshot file.
- $snapshot = KinoSearch::Index::Snapshot->new(
- schema => $schema );
- my $folder = $invindex->get_folder;
- $snapshot->read_snapshot( folder => $folder );
- }
-
- # Throw an error if index doesn't exist.
- confess("Index doesn't seem to contain any data")
- unless $snapshot->size;
-
- # Deal with race condition between locking and reading
- # snapshot file.
- if ( $snapshot->get_generation > $gen ) {
- confess("More recent snapshot file than $gen detected");
- }
-
- for my $seg_info (
- sort { $a->get_seg_name cmp $b->get_seg_name }
- @{ $snapshot->infos->to_perl } )
- {
- # Create a SegReader for each segment in the InvIndex.
- push @seg_readers,
- KinoSearch::Index::SegReader->new(
- invindex => $invindex,
- seg_info => $seg_info,
- lock_factory => $lock_factory,
- );
- }
- };
-
- # It's possible, though unlikely, for an InvIndexer to delete
- # files out from underneath us after the snapshot file is read but
- # before we've got SegReaders holding open all the required files.
- # If we failed to open something, see if we can find a newer
- # snapshot file. If we can, then the exception was due to the
- # race condition. If not, we have a real exception, so throw an
- # error.
- if ($@) {
- my $saved_error = $@;
- $self->release_read_lock;
- if ( !defined $snapshot
- or ( defined $last_gen and $last_gen == $gen ) )
- {
- $self->release_commit_lock if defined $lock_factory;
- confess($saved_error);
- }
- $last_gen = $gen;
- @seg_readers = ();
- undef $snapshot;
+ sub try_open_segreaders {
+ my ( undef, %args ) = @_;
+ my ( $snapshot, $invindex, $lock_factory )
+ = @args{qw( snapshot invindex lock_factory )};
+ my @seg_infos = sort { $a->get_seg_name cmp $b->get_seg_name }
+ @{ $snapshot->infos->to_perl };
+ my $seg_readers
+ = KinoSearch::Util::VArray->new( capacity => scalar @seg_infos );
+ eval {
+ for my $seg_info (@seg_infos) {
+ # Create a SegReader for each segment in the InvIndex.
+ my $seg_reader = KinoSearch::Index::SegReader->new(
+ invindex => $invindex,
+ seg_info => $seg_info,
+ lock_factory => $lock_factory,
+ );
+ $seg_readers->push($seg_reader);
}
- else {
- $self->set_snapshot($snapshot);
- last;
- }
+ };
+ if ($@) {
+ return KinoSearch::Util::CharBuf->new($@);
}
-
- $self->release_commit_lock if defined $lock_factory;
-
- # If there's one SegReader use it; otherwise make a MultiReader.
- my $true_self;
- if ( @seg_readers == 1 ) {
- $true_self = $seg_readers[0];
- }
- else {
- my $sub_readers = KinoSearch::Util::VArray->new(
- capacity => scalar @seg_readers );
- $sub_readers->push($_) for @seg_readers;
- $true_self = KinoSearch::Index::MultiReader->new(
- invindex => $invindex,
- sub_readers => $sub_readers,
- lock_factory => $lock_factory,
- );
- }
-
- # Copy crucial elements.
- $true_self->set_read_lock( $self->get_read_lock );
-
- # Thwart release of lock on destruction of temp self.
- $self->set_read_lock(undef);
- $self->set_commit_lock(undef);
- $self->set_lock_factory(undef);
-
- return $true_self;
+ return $seg_readers;
}
-
- our %doc_freq_args = ( field => undef, term => undef );
- our %lexicon_args = ( field => undef, term => undef );
- our %posting_list_args = ( field => undef, term => undef );
}

{
@@ -633,29 +507,6 @@
}

{
- package KinoSearch::Searcher;
- use KinoSearch::Util::ToolSet qw( a_isa_b confess );
-
- sub new {
- my ( $either, %args ) = @_;
-
- # Require either invindex or reader.
- if ( a_isa_b( $args{reader}, 'KinoSearch::Index::IndexReader' ) ) {
- $args{invindex} = $args{reader}->get_invindex;
- }
- elsif ( a_isa_b( $args{invindex}, 'KinoSearch::InvIndex' ) ) {
- $args{reader} = KinoSearch::Index::IndexReader->open(
- invindex => $args{invindex} );
- }
- else {
- confess("Either 'invindex' or 'reader' is required");
- }
-
- return $either->_new(%args);
- }
-}
-
-{
package KinoSearch::Store::Folder;

sub list { shift->_list->to_perl }

Modified: trunk/perl/t/109-read_locking.t
===================================================================
--- trunk/perl/t/109-read_locking.t 2008-08-04 16:30:44 UTC (rev 3711)
+++ trunk/perl/t/109-read_locking.t 2008-08-04 19:23:35 UTC (rev 3712)
@@ -67,13 +67,8 @@
Test_race_condition_1: {
my $latest_snapshot_file = $folder->latest_snapshot_file;
$folder->rename_file( from => $latest_snapshot_file, to => 'temp' );
- my $num_passes = 0;
- local $KinoSearch::Index::IndexReader::debug1 = sub {
- my $self = shift;
- $folder->rename_file( from => 'temp', to => $latest_snapshot_file )
- if $folder->file_exists('temp');
- $num_passes++;
- };
+ KinoSearch::Index::IndexReader::set_race_condition_debug1(
+ KinoSearch::Util::CharBuf->new($latest_snapshot_file) );
$reader = KinoSearch::Index::IndexReader->open(
invindex => $invindex,
lock_factory => $lock_factory,
@@ -81,8 +76,11 @@
is( $reader->num_docs, 4,
"reader overcomes race condition of "
. "new segs file appearing after read lock" );
- is( $num_passes, 2, "reader retried before succeeding" );
+ is( KinoSearch::Index::IndexReader::debug1_num_passes(),
+ 2, "reader retried before succeeding" );

+ KinoSearch::Index::IndexReader::set_race_condition_debug1(undef);
+
$reader->close;
}



_______________________________________________
kinosearch-commits mailing list
kinosearch-commits@rectangular.com
http://www.rectangular.com/mailman/listinfo/kinosearch-commits