1
/*------------------------------------------------------------------------------
2
* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
4
* Distributable under the terms of either the Apache License (Version 2.0) or
5
* the GNU Lesser General Public License, as specified in the COPYING file.
6
------------------------------------------------------------------------------*/
7
#include "CLucene/_ApiHeader.h"
8
#include "_SegmentHeader.h"
15
SegmentTermPositions::SegmentTermPositions(const SegmentReader* _parent):
16
SegmentTermDocs(_parent), proxStream(NULL)// the proxStream will be cloned lazily when nextPosition() is called for the first time
17
,lazySkipPointer(-1), lazySkipProxCount(0)
19
CND_CONDITION(_parent != NULL, "Parent is NULL");
22
SegmentTermPositions::~SegmentTermPositions() {
26
TermDocs* SegmentTermPositions::__asTermDocs(){
27
return (TermDocs*) this;
29
TermPositions* SegmentTermPositions::__asTermPositions(){
30
return (TermPositions*) this;
33
void SegmentTermPositions::seek(const TermInfo* ti, Term* term) {
34
SegmentTermDocs::seek(ti, term);
36
lazySkipPointer = ti->proxPointer;
38
lazySkipProxCount = 0;
41
needToLoadPayload = false;
44
void SegmentTermPositions::close() {
45
SegmentTermDocs::close();
46
//Check if proxStream still exists
49
_CLDELETE( proxStream );
53
int32_t SegmentTermPositions::nextPosition() {
54
// perform lazy skips if neccessary
57
return position += readDeltaPosition();
60
int32_t SegmentTermPositions::readDeltaPosition() {
61
int32_t delta = proxStream->readVInt();
62
if (currentFieldStoresPayloads) {
63
// if the current field stores payloads then
64
// the position delta is shifted one bit to the left.
65
// if the LSB is set, then we have to read the current
67
if ((delta & 1) != 0) {
68
payloadLength = proxStream->readVInt();
70
delta = (int32_t)((uint32_t)delta >> (uint32_t)1);
71
needToLoadPayload = true;
76
void SegmentTermPositions::skippingDoc() {
77
lazySkipProxCount += _freq;
80
bool SegmentTermPositions::next() {
81
// we remember to skip the remaining positions of the current
83
lazySkipProxCount += proxCount;
85
if (SegmentTermDocs::next()) { // run super
86
proxCount = _freq; // note frequency
87
position = 0; // reset position
93
int32_t SegmentTermPositions::read(int32_t* /*docs*/, int32_t* /*freqs*/, int32_t /*length*/) {
94
_CLTHROWA(CL_ERR_UnsupportedOperation,"TermPositions does not support processing multiple documents in one call. Use TermDocs instead.");
97
void SegmentTermPositions::skipProx(const int64_t proxPointer, const int32_t _payloadLength){
98
// we save the pointer, we might have to skip there lazily
99
lazySkipPointer = proxPointer;
100
lazySkipProxCount = 0;
102
this->payloadLength = _payloadLength;
103
needToLoadPayload = false;
106
void SegmentTermPositions::skipPositions(const int32_t n) {
107
for ( int32_t f = n; f > 0; f-- ) { // skip unread positions
113
void SegmentTermPositions::skipPayload() {
114
if (needToLoadPayload && payloadLength > 0) {
115
proxStream->seek(proxStream->getFilePointer() + payloadLength);
117
needToLoadPayload = false;
120
void SegmentTermPositions::lazySkip() {
121
if (proxStream == NULL) {
123
proxStream = parent->proxStream->clone();
126
// we might have to skip the current payload
127
// if it was not read yet
130
if (lazySkipPointer != -1) {
131
proxStream->seek(lazySkipPointer);
132
lazySkipPointer = -1;
135
if (lazySkipProxCount != 0) {
136
skipPositions(lazySkipProxCount);
137
lazySkipProxCount = 0;
141
int32_t SegmentTermPositions::getPayloadLength() const { return payloadLength; }
143
uint8_t* SegmentTermPositions::getPayload(uint8_t* data) {
144
if (!needToLoadPayload) {
145
_CLTHROWA(CL_ERR_IO, "Payload cannot be loaded more than once for the same term position.");
148
// read payloads lazily
150
// TODO: Complete length logic ( possibly using ValueArray ? )
151
if (data == NULL /*|| data.length - offset < payloadLength*/) {
152
// the array is too small to store the payload data,
153
// so we allocate a new one
154
_CLDELETE_ARRAY(data);
155
retArray = _CL_NEWARRAY(uint8_t, payloadLength);
159
proxStream->readBytes(retArray, payloadLength);
160
needToLoadPayload = false;
163
bool SegmentTermPositions::isPayloadAvailable() const { return needToLoadPayload && (payloadLength > 0); }