aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib/src/vespa/searchlib/attribute/postingstore.hpp
blob: 8a88a38124c02bdc8679c4b3258b7f8cc4e2ef96 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once

#include "postingstore.h"
#include <vespa/searchlib/common/growablebitvector.h>

namespace search::attribute {

template<typename DataT>
template<typename FunctionType>
void
PostingStore<DataT>::foreach_frozen_key(EntryRef ref, FunctionType func) const {
    if (!ref.valid())
        return;
    RefType iRef(ref);
    uint32_t typeId = getTypeId(iRef);
    uint32_t clusterSize = getClusterSize(typeId);
    if (clusterSize == 0) {
        if (isBitVector(typeId)) {
            const BitVectorEntry *bve = getBitVectorEntry(iRef);
            EntryRef ref2(bve->_tree);
            RefType iRef2(ref2);
            if (iRef2.valid()) {
                assert(isBTree(iRef2));
                const BTreeType *tree = getTreeEntry(iRef2);
                _allocator.getNodeStore().foreach_key(tree->getFrozenRoot(), func);
            } else {
                const BitVector *bv = &bve->_bv->reader();
                uint32_t docIdLimit = bv->size();
                uint32_t docId = bv->getFirstTrueBit(1);
                while (docId < docIdLimit) {
                    func(docId);
                    docId = bv->getNextTrueBit(docId + 1);
                }
            }
        } else {
            assert(isBTree(typeId));
            const BTreeType *tree = getTreeEntry(iRef);
            _allocator.getNodeStore().foreach_key(tree->getFrozenRoot(), func);
        }
    } else {
        const KeyDataType *p = getKeyDataEntry(iRef, clusterSize);
        const KeyDataType *pe = p + clusterSize;
        for (; p != pe; ++p) {
            func(p->_key);
        }
    }
}


template<typename DataT>
template<typename FunctionType>
void
PostingStore<DataT>::foreach_frozen(EntryRef ref, FunctionType func) const {
    if (!ref.valid())
        return;
    RefType iRef(ref);
    uint32_t typeId = getTypeId(iRef);
    uint32_t clusterSize = getClusterSize(typeId);
    if (clusterSize == 0) {
        if (isBitVector(typeId)) {
            const BitVectorEntry *bve = getBitVectorEntry(iRef);
            EntryRef ref2(bve->_tree);
            RefType iRef2(ref2);
            if (iRef2.valid()) {
                assert(isBTree(iRef2));
                const BTreeType *tree = getTreeEntry(iRef2);
                _allocator.getNodeStore().foreach(tree->getFrozenRoot(), func);
            } else {
                const BitVector *bv = &bve->_bv->reader();
                uint32_t docIdLimit = bv->size();
                uint32_t docId = bv->getFirstTrueBit(1);
                while (docId < docIdLimit) {
                    func(docId, bitVectorWeight());
                    docId = bv->getNextTrueBit(docId + 1);
                }
            }
        } else {
            const BTreeType *tree = getTreeEntry(iRef);
            _allocator.getNodeStore().foreach(tree->getFrozenRoot(), func);
        }
    } else {
        const KeyDataType *p = getKeyDataEntry(iRef, clusterSize);
        const KeyDataType *pe = p + clusterSize;
        for (; p != pe; ++p) {
            func(p->_key, p->getData());
        }
    }
}

}