[KinoSearch] Merging indexes, etc
henka at cityweb.co.za
henka at cityweb.co.za
Mon Oct 30 11:23:13 PST 2006
>
> On Oct 26, 2006, at 6:36 AM, henka at cityweb.co.za wrote:
>
>> Splitting the process into two steps (delete_docs_by_term() and
>> add_invindexes()) unfortunately results in the error:
>>
>> Can't locate object method "_release_locks" via package
>> "self" (perhaps
>> you forgot to load "self"?) at
>> /usr/lib/perl5/site_perl/5.8.7/i486-linux/KinoSearch/InvIndexer.pm
>> line
>> 273.
>
> Hmm. What the hell is "self" doing there? That really suggests
> memory corruption of some kind -- the pointer that used to lead Perl
> to the class name has been reused and is now pointing to something
> completely different and wrong. That's why I suspected problems with
> DESTROY.
>
> I have one more idea, but after that, I'm going to need a failing
> test case I can go tear into.
>
>> The logic I used:
>>
>> my $iv;
>> foreach (sub-indexes) {
>> $iv= KinoSearch::InvIndexer->new(...);
>> $iv->delete_docs_by_term(...);
>> $iv->finish(optimize=>0);
>> $iv= KinoSearch::InvIndexer->new(...); # same sub-index as previous
>> $iv->add_invindexes(...);
>> $iv->finish(optimize=>0);
>> }
>
> Try undef-ing the InvIndexer before assigning another one on top of
> it. Take a look at the create_test_invindex() function in <http://
> www.rectangular.com/svn/kinosearch/trunk/buildlib/
> KinoSearchTestInvIndex.pm> for a template.
>
> I'm not sure that you're seeing the same problem I've been seeing,
> but code like in your example, where a new InvIndexer instance is
> created in the same scalar variable, has caused me problems in the
> past. The symptoms were slightly different: it was lock contention
> rather than a failed call to _release_locks.
>
> The sequence "$invindexer = new_invindexer(); $invindexer =
> new_invindexer();" is problematic, because the second assignment
> statement triggers this order of operations:
>
> 1) Create new InvIndexer, put it in a mortal SV on
> the Perl stack.
> 2) Assign the new InvIndexer object to the scalar
> which previously held another invindexer.
> 3) The old scalar's reference count is decremented
> and the old InvIndexer's DESTROY method gets called.
>
> In step 1, the new InvIndexer requests a lock. But the old
> InvIndexer doesn't release its lock until step 3.
>
> I'd like to solve this problem, but I'm not sure how to do it in the
> general case. I've thought of doing something like this, using
> closures:
>
> # in new()
> $self->{release_locks} = sub { $self->do_release_locks };
>
> # in finish()
> $self->{release_locks}->();
> undef $self->{release_locks};
>
> # in DESTROY
> $self->{release_locks}->() if defined $self->{release_locks};
>
> But I think that would still fail if finish() never gets called.
Thanks for the detailed response. Will try the undef approach and let you
know.
_______________________________________________
KinoSearch mailing list
KinoSearch at rectangular.com
http://www.rectangular.com/mailman/listinfo/kinosearch
More information about the kinosearch
mailing list