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