1 /////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2009-2014 Alan Wright. All rights reserved.
3 // Distributable under the terms of either the Apache License (Version 2.0)
4 // or the GNU Lesser General Public License.
5 /////////////////////////////////////////////////////////////////////////////
6
7 #include "LuceneInc.h"
8 #include "BufferedDeletes.h"
9 #include "MergeDocIDRemapper.h"
10
11 namespace Lucene {
12
BufferedDeletes(bool doTermSort)13 BufferedDeletes::BufferedDeletes(bool doTermSort) {
14 // doTermSort not used: always use sorted term map
15 terms = MapTermNum::newInstance();
16 queries = MapQueryInt::newInstance();
17 docIDs = Collection<int32_t>::newInstance();
18 numTerms = 0;
19 bytesUsed = 0;
20 }
21
~BufferedDeletes()22 BufferedDeletes::~BufferedDeletes() {
23 }
24
size()25 int32_t BufferedDeletes::size() {
26 // We use numTerms not terms.size() intentionally, so that deletes by the same term
27 // multiple times "count", ie if you ask to flush every 1000 deletes then even dup'd
28 // terms are counted towards that 1000
29 return numTerms + queries.size() + docIDs.size();
30 }
31
update(const BufferedDeletesPtr & in)32 void BufferedDeletes::update(const BufferedDeletesPtr& in) {
33 numTerms += in->numTerms;
34 bytesUsed += in->bytesUsed;
35 terms.putAll(in->terms.begin(), in->terms.end());
36 queries.putAll(in->queries.begin(), in->queries.end());
37 docIDs.addAll(in->docIDs.begin(), in->docIDs.end());
38 in->clear();
39 }
40
clear()41 void BufferedDeletes::clear() {
42 terms.clear();
43 queries.clear();
44 docIDs.clear();
45 numTerms = 0;
46 bytesUsed = 0;
47 }
48
addBytesUsed(int64_t b)49 void BufferedDeletes::addBytesUsed(int64_t b) {
50 bytesUsed += b;
51 }
52
any()53 bool BufferedDeletes::any() {
54 return (!terms.empty() || !docIDs.empty() || !queries.empty());
55 }
56
remap(const MergeDocIDRemapperPtr & mapper,const SegmentInfosPtr & infos,Collection<Collection<int32_t>> docMaps,Collection<int32_t> delCounts,const OneMergePtr & merge,int32_t mergedDocCount)57 void BufferedDeletes::remap(const MergeDocIDRemapperPtr& mapper, const SegmentInfosPtr& infos, Collection< Collection<int32_t> > docMaps, Collection<int32_t> delCounts, const OneMergePtr& merge, int32_t mergedDocCount) {
58 SyncLock syncLock(this);
59
60 MapTermNum newDeleteTerms;
61
62 // Remap delete-by-term
63 if (!terms.empty()) {
64 newDeleteTerms = MapTermNum::newInstance();
65 for (MapTermNum::iterator entry = terms.begin(); entry != terms.end(); ++entry) {
66 newDeleteTerms.put(entry->first, newLucene<Num>(mapper->remap(entry->second->getNum())));
67 }
68 }
69
70 // Remap delete-by-docID
71 Collection<int32_t> newDeleteDocIDs;
72
73 if (!docIDs.empty()) {
74 newDeleteDocIDs = Collection<int32_t>::newInstance();
75 for (Collection<int32_t>::iterator num = docIDs.begin(); num != docIDs.end(); ++num) {
76 newDeleteDocIDs.add(mapper->remap(*num));
77 }
78 }
79
80 // Remap delete-by-query
81 MapQueryInt newDeleteQueries;
82
83 if (!queries.empty()) {
84 newDeleteQueries = MapQueryInt::newInstance();
85 for (MapQueryInt::iterator entry = queries.begin(); entry != queries.end(); ++entry) {
86 newDeleteQueries.put(entry->first, mapper->remap(entry->second));
87 }
88 }
89
90 if (newDeleteTerms) {
91 terms = newDeleteTerms;
92 }
93 if (newDeleteDocIDs) {
94 docIDs = newDeleteDocIDs;
95 }
96 if (newDeleteQueries) {
97 queries = newDeleteQueries;
98 }
99 }
100
Num(int32_t num)101 Num::Num(int32_t num) {
102 this->num = num;
103 }
104
getNum()105 int32_t Num::getNum() {
106 return num;
107 }
108
setNum(int32_t num)109 void Num::setNum(int32_t num) {
110 // Only record the new number if it's greater than the current one. This is important
111 // because if multiple threads are replacing the same doc at nearly the same time, it's
112 // possible that one thread that got a higher docID is scheduled before the other threads.
113 this->num = std::max(this->num, num);
114 }
115
116 }
117