blob: 391bf636e4941a88c3eeab15e1e3c6fe160b6162 [file] [log] [blame]
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define C_LUCY_DELETIONSREADER
#define C_LUCY_POLYDELETIONSREADER
#define C_LUCY_DEFAULTDELETIONSREADER
#include "Lucy/Util/ToolSet.h"
#include "Lucy/Index/DeletionsReader.h"
#include "Lucy/Index/BitVecDelDocs.h"
#include "Lucy/Index/DeletionsWriter.h"
#include "Lucy/Index/Segment.h"
#include "Lucy/Index/Snapshot.h"
#include "Lucy/Plan/Schema.h"
#include "Lucy/Search/BitVecMatcher.h"
#include "Lucy/Search/SeriesMatcher.h"
#include "Lucy/Store/Folder.h"
#include "Lucy/Store/InStream.h"
#include "Lucy/Util/IndexFileNames.h"
DeletionsReader*
DelReader_init(DeletionsReader *self, Schema *schema, Folder *folder,
Snapshot *snapshot, VArray *segments, int32_t seg_tick) {
DataReader_init((DataReader*)self, schema, folder, snapshot, segments,
seg_tick);
ABSTRACT_CLASS_CHECK(self, DELETIONSREADER);
return self;
}
DeletionsReader*
DelReader_aggregator(DeletionsReader *self, VArray *readers,
I32Array *offsets) {
UNUSED_VAR(self);
return (DeletionsReader*)PolyDelReader_new(readers, offsets);
}
PolyDeletionsReader*
PolyDelReader_new(VArray *readers, I32Array *offsets) {
PolyDeletionsReader *self
= (PolyDeletionsReader*)VTable_Make_Obj(POLYDELETIONSREADER);
return PolyDelReader_init(self, readers, offsets);
}
PolyDeletionsReader*
PolyDelReader_init(PolyDeletionsReader *self, VArray *readers,
I32Array *offsets) {
DelReader_init((DeletionsReader*)self, NULL, NULL, NULL, NULL, -1);
self->del_count = 0;
for (uint32_t i = 0, max = VA_Get_Size(readers); i < max; i++) {
DeletionsReader *reader = (DeletionsReader*)CERTIFY(
VA_Fetch(readers, i), DELETIONSREADER);
self->del_count += DelReader_Del_Count(reader);
}
self->readers = (VArray*)INCREF(readers);
self->offsets = (I32Array*)INCREF(offsets);
return self;
}
void
PolyDelReader_close(PolyDeletionsReader *self) {
if (self->readers) {
for (uint32_t i = 0, max = VA_Get_Size(self->readers); i < max; i++) {
DeletionsReader *reader
= (DeletionsReader*)VA_Fetch(self->readers, i);
if (reader) { DelReader_Close(reader); }
}
VA_Clear(self->readers);
}
}
void
PolyDelReader_destroy(PolyDeletionsReader *self) {
DECREF(self->readers);
DECREF(self->offsets);
SUPER_DESTROY(self, POLYDELETIONSREADER);
}
int32_t
PolyDelReader_del_count(PolyDeletionsReader *self) {
return self->del_count;
}
Matcher*
PolyDelReader_iterator(PolyDeletionsReader *self) {
SeriesMatcher *deletions = NULL;
if (self->del_count) {
uint32_t num_readers = VA_Get_Size(self->readers);
VArray *matchers = VA_new(num_readers);
for (uint32_t i = 0; i < num_readers; i++) {
DeletionsReader *reader
= (DeletionsReader*)VA_Fetch(self->readers, i);
Matcher *matcher = DelReader_Iterator(reader);
if (matcher) { VA_Store(matchers, i, (Obj*)matcher); }
}
deletions = SeriesMatcher_new(matchers, self->offsets);
DECREF(matchers);
}
return (Matcher*)deletions;
}
DefaultDeletionsReader*
DefDelReader_new(Schema *schema, Folder *folder, Snapshot *snapshot,
VArray *segments, int32_t seg_tick) {
DefaultDeletionsReader *self
= (DefaultDeletionsReader*)VTable_Make_Obj(DEFAULTDELETIONSREADER);
return DefDelReader_init(self, schema, folder, snapshot, segments,
seg_tick);
}
DefaultDeletionsReader*
DefDelReader_init(DefaultDeletionsReader *self, Schema *schema,
Folder *folder, Snapshot *snapshot, VArray *segments,
int32_t seg_tick) {
DelReader_init((DeletionsReader*)self, schema, folder, snapshot, segments,
seg_tick);
DefDelReader_Read_Deletions(self);
if (!self->deldocs) {
self->del_count = 0;
self->deldocs = BitVec_new(0);
}
return self;
}
void
DefDelReader_close(DefaultDeletionsReader *self) {
DECREF(self->deldocs);
self->deldocs = NULL;
}
void
DefDelReader_destroy(DefaultDeletionsReader *self) {
DECREF(self->deldocs);
SUPER_DESTROY(self, DEFAULTDELETIONSREADER);
}
BitVector*
DefDelReader_read_deletions(DefaultDeletionsReader *self) {
VArray *segments = DefDelReader_Get_Segments(self);
Segment *segment = DefDelReader_Get_Segment(self);
CharBuf *my_seg_name = Seg_Get_Name(segment);
CharBuf *del_file = NULL;
int32_t del_count = 0;
// Start with deletions files in the most recently added segments and work
// backwards. The first one we find which addresses our segment is the
// one we need.
for (int32_t i = VA_Get_Size(segments) - 1; i >= 0; i--) {
Segment *other_seg = (Segment*)VA_Fetch(segments, i);
Hash *metadata
= (Hash*)Seg_Fetch_Metadata_Str(other_seg, "deletions", 9);
if (metadata) {
Hash *files = (Hash*)CERTIFY(
Hash_Fetch_Str(metadata, "files", 5), HASH);
Hash *seg_files_data
= (Hash*)Hash_Fetch(files, (Obj*)my_seg_name);
if (seg_files_data) {
Obj *count = (Obj*)CERTIFY(
Hash_Fetch_Str(seg_files_data, "count", 5),
OBJ);
del_count = (int32_t)Obj_To_I64(count);
del_file = (CharBuf*)CERTIFY(
Hash_Fetch_Str(seg_files_data, "filename", 8),
CHARBUF);
break;
}
}
}
DECREF(self->deldocs);
if (del_file) {
self->deldocs = (BitVector*)BitVecDelDocs_new(self->folder, del_file);
self->del_count = del_count;
}
else {
self->deldocs = NULL;
self->del_count = 0;
}
return self->deldocs;
}
Matcher*
DefDelReader_iterator(DefaultDeletionsReader *self) {
return (Matcher*)BitVecMatcher_new(self->deldocs);
}
int32_t
DefDelReader_del_count(DefaultDeletionsReader *self) {
return self->del_count;
}