/* 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_NUMERICSORTCACHE
#define C_LUCY_INT32SORTCACHE
#define C_LUCY_INT64SORTCACHE
#define C_LUCY_FLOAT32SORTCACHE
#define C_LUCY_FLOAT64SORTCACHE
#include "Lucy/Util/ToolSet.h"
#include "Lucy/Index/SortCache/NumericSortCache.h"
#include "Lucy/Index/Segment.h"
#include "Lucy/Plan/FieldType.h"
#include "Lucy/Plan/NumericType.h"
#include "Lucy/Plan/Schema.h"
#include "Lucy/Store/InStream.h"
#include "Lucy/Store/Folder.h"
NumericSortCache*
NumSortCache_init(NumericSortCache *self, const CharBuf *field,
FieldType *type, int32_t cardinality, int32_t doc_max,
int32_t null_ord, int32_t ord_width, InStream *ord_in,
InStream *dat_in) {
// Validate.
if (!type || !FType_Sortable(type) || !FType_Is_A(type, NUMERICTYPE)) {
DECREF(self);
THROW(ERR, "'%o' isn't a sortable NumericType field", field);
}
// Mmap ords and super-init.
int64_t ord_len = InStream_Length(ord_in);
void *ords = InStream_Buf(ord_in, (size_t)ord_len);
SortCache_init((SortCache*)self, field, type, ords, cardinality, doc_max,
null_ord, ord_width);
// Assign.
self->ord_in = (InStream*)INCREF(ord_in);
self->dat_in = (InStream*)INCREF(dat_in);
// Validate ord file length.
double BITS_PER_BYTE = 8.0;
double docs_per_byte = BITS_PER_BYTE / self->ord_width;
double max_ords = ord_len * docs_per_byte;
if (max_ords < self->doc_max + 1) {
DECREF(self);
THROW(ERR, "Conflict between ord count max %f64 and doc_max %i32 for "
"field %o", max_ords, self->doc_max, field);
}
ABSTRACT_CLASS_CHECK(self, NUMERICSORTCACHE);
return self;
}
void
NumSortCache_destroy(NumericSortCache *self) {
if (self->ord_in) {
InStream_Close(self->ord_in);
InStream_Dec_RefCount(self->ord_in);
}
if (self->dat_in) {
InStream_Close(self->dat_in);
InStream_Dec_RefCount(self->dat_in);
}
SUPER_DESTROY(self, NUMERICSORTCACHE);
}
/***************************************************************************/
Float64SortCache*
F64SortCache_new(const CharBuf *field, FieldType *type, int32_t cardinality,
int32_t doc_max, int32_t null_ord, int32_t ord_width,
InStream *ord_in, InStream *dat_in) {
Float64SortCache *self
= (Float64SortCache*)VTable_Make_Obj(FLOAT64SORTCACHE);
return F64SortCache_init(self, field, type, cardinality, doc_max,
null_ord, ord_width, ord_in, dat_in);
}
Float64SortCache*
F64SortCache_init(Float64SortCache *self, const CharBuf *field,
FieldType *type, int32_t cardinality, int32_t doc_max,
int32_t null_ord, int32_t ord_width, InStream *ord_in,
InStream *dat_in) {
NumSortCache_init((NumericSortCache*)self, field, type, cardinality,
doc_max, null_ord, ord_width, ord_in, dat_in);
return self;
}
Obj*
F64SortCache_value(Float64SortCache *self, int32_t ord, Obj *blank) {
if (ord == self->null_ord) {
return NULL;
}
else if (ord < 0) {
THROW(ERR, "Ordinal less than 0 for %o: %i32", self->field, ord);
}
else {
Float64 *num_blank = (Float64*)CERTIFY(blank, FLOAT64);
InStream_Seek(self->dat_in, ord * sizeof(double));
Float64_Set_Value(num_blank, InStream_Read_F64(self->dat_in));
}
return blank;
}
Float64*
F64SortCache_make_blank(Float64SortCache *self) {
UNUSED_VAR(self);
return Float64_new(0.0);
}
/***************************************************************************/
Float32SortCache*
F32SortCache_new(const CharBuf *field, FieldType *type, int32_t cardinality,
int32_t doc_max, int32_t null_ord, int32_t ord_width,
InStream *ord_in, InStream *dat_in) {
Float32SortCache *self
= (Float32SortCache*)VTable_Make_Obj(FLOAT32SORTCACHE);
return F32SortCache_init(self, field, type, cardinality, doc_max,
null_ord, ord_width, ord_in, dat_in);
}
Float32SortCache*
F32SortCache_init(Float32SortCache *self, const CharBuf *field,
FieldType *type, int32_t cardinality, int32_t doc_max,
int32_t null_ord, int32_t ord_width, InStream *ord_in,
InStream *dat_in) {
NumSortCache_init((NumericSortCache*)self, field, type, cardinality,
doc_max, null_ord, ord_width, ord_in, dat_in);
return self;
}
Obj*
F32SortCache_value(Float32SortCache *self, int32_t ord, Obj *blank) {
if (ord == self->null_ord) {
return NULL;
}
else if (ord < 0) {
THROW(ERR, "Ordinal less than 0 for %o: %i32", self->field, ord);
}
else {
Float32 *num_blank = (Float32*)CERTIFY(blank, FLOAT32);
InStream_Seek(self->dat_in, ord * sizeof(float));
Float32_Set_Value(num_blank, InStream_Read_F32(self->dat_in));
}
return blank;
}
Float32*
F32SortCache_make_blank(Float32SortCache *self) {
UNUSED_VAR(self);
return Float32_new(0.0f);
}
/***************************************************************************/
Int32SortCache*
I32SortCache_new(const CharBuf *field, FieldType *type, int32_t cardinality,
int32_t doc_max, int32_t null_ord, int32_t ord_width,
InStream *ord_in, InStream *dat_in) {
Int32SortCache *self
= (Int32SortCache*)VTable_Make_Obj(INT32SORTCACHE);
return I32SortCache_init(self, field, type, cardinality, doc_max,
null_ord, ord_width, ord_in, dat_in);
}
Int32SortCache*
I32SortCache_init(Int32SortCache *self, const CharBuf *field,
FieldType *type, int32_t cardinality, int32_t doc_max,
int32_t null_ord, int32_t ord_width, InStream *ord_in,
InStream *dat_in) {
NumSortCache_init((NumericSortCache*)self, field, type, cardinality,
doc_max, null_ord, ord_width, ord_in, dat_in);
return self;
}
Obj*
I32SortCache_value(Int32SortCache *self, int32_t ord, Obj *blank) {
if (ord == self->null_ord) {
return NULL;
}
else if (ord < 0) {
THROW(ERR, "Ordinal less than 0 for %o: %i32", self->field, ord);
}
else {
Integer32 *int_blank = (Integer32*)CERTIFY(blank, INTEGER32);
InStream_Seek(self->dat_in, ord * sizeof(int32_t));
Int32_Set_Value(int_blank, InStream_Read_I32(self->dat_in));
}
return blank;
}
Integer32*
I32SortCache_make_blank(Int32SortCache *self) {
UNUSED_VAR(self);
return Int32_new(0);
}
/***************************************************************************/
Int64SortCache*
I64SortCache_new(const CharBuf *field, FieldType *type, int32_t cardinality,
int32_t doc_max, int32_t null_ord, int32_t ord_width,
InStream *ord_in, InStream *dat_in) {
Int64SortCache *self
= (Int64SortCache*)VTable_Make_Obj(INT64SORTCACHE);
return I64SortCache_init(self, field, type, cardinality, doc_max,
null_ord, ord_width, ord_in, dat_in);
}
Int64SortCache*
I64SortCache_init(Int64SortCache *self, const CharBuf *field,
FieldType *type, int32_t cardinality, int32_t doc_max,
int32_t null_ord, int32_t ord_width, InStream *ord_in,
InStream *dat_in) {
NumSortCache_init((NumericSortCache*)self, field, type, cardinality,
doc_max, null_ord, ord_width, ord_in, dat_in);
return self;
}
Obj*
I64SortCache_value(Int64SortCache *self, int32_t ord, Obj *blank) {
if (ord == self->null_ord) {
return NULL;
}
else if (ord < 0) {
THROW(ERR, "Ordinal less than 0 for %o: %i32", self->field, ord);
}
else {
Integer64 *int_blank = (Integer64*)CERTIFY(blank, INTEGER64);
InStream_Seek(self->dat_in, ord * sizeof(int64_t));
Int64_Set_Value(int_blank, InStream_Read_I64(self->dat_in));
}
return blank;
}
Integer64*
I64SortCache_make_blank(Int64SortCache *self) {
UNUSED_VAR(self);
return Int64_new(0);
}