1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  *     Copyright 2017 Couchbase, Inc
4  *
5  *   Licensed under the Apache License, Version 2.0 (the "License");
6  *   you may not use this file except in compliance with the License.
7  *   You may obtain a copy of the License at
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *   Unless required by applicable law or agreed to in writing, software
12  *   distributed under the License is distributed on an "AS IS" BASIS,
13  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *   See the License for the specific language governing permissions and
15  *   limitations under the License.
16  */
17 
18 #pragma once
19 
20 #include <memcached/vbucket.h>
21 
22 #include <set>
23 #include <vector>
24 
25 /**
26  * Function object that returns true if the given vbucket is acceptable.
27  */
28 class VBucketFilter {
29 public:
30     /**
31      * Instiatiate a VBucketFilter that always returns true.
32      */
VBucketFilter()33     VBucketFilter() : acceptable() {
34     }
35 
36     /**
37      * Instantiate a VBucketFilter that returns true for any of the
38      * given vbucket IDs.
39      */
VBucketFilter(const std::vector<Vbid>& a)40     VBucketFilter(const std::vector<Vbid>& a) : acceptable(a.begin(), a.end()) {
41     }
42 
VBucketFilter(std::set<Vbid> s)43     VBucketFilter(std::set<Vbid> s) : acceptable(std::move(s)) {
44     }
45 
assign(const std::set<Vbid>& a)46     void assign(const std::set<Vbid>& a) {
47         acceptable = a;
48     }
49 
operator ()(Vbid v) const50     bool operator()(Vbid v) const {
51         return acceptable.empty() || acceptable.find(v) != acceptable.end();
52     }
53 
size() const54     size_t size() const {
55         return acceptable.size();
56     }
57 
empty() const58     bool empty() const {
59         return acceptable.empty();
60     }
61 
reset()62     void reset() {
63         acceptable.clear();
64     }
65 
66     /**
67      * Calculate the difference between this and another filter.
68      * If "this" contains elements, [1,2,3,4] and other contains [3,4,5,6]
69      * the returned filter contains: [1,2,5,6]
70      * @param other the other filter to compare with
71      * @return a new filter with the elements present in only one of the two
72      *         filters.
73      */
74     VBucketFilter filter_diff(const VBucketFilter& other) const;
75 
76     /**
77      * Calculate the intersection between this and another filter.
78      * If "this" contains elements, [1,2,3,4] and other contains [3,4,5,6]
79      * the returned filter contains: [3,4]
80      * @param other the other filter to compare with
81      * @return a new filter with the elements present in both of the two
82      *         filters.
83      */
84     VBucketFilter filter_intersection(const VBucketFilter& other) const;
85 
getVBSet() const86     const std::set<Vbid>& getVBSet() const {
87         return acceptable;
88     }
89 
addVBucket(Vbid vbucket)90     bool addVBucket(Vbid vbucket) {
91         auto rv = acceptable.insert(vbucket);
92         return rv.second;
93     }
94 
removeVBucket(Vbid vbucket)95     void removeVBucket(Vbid vbucket) {
96         acceptable.erase(vbucket);
97     }
98 
99     /**
100      * Dump the filter in a human readable form ( "{ bucket, bucket, bucket }"
101      * to the specified output stream.
102      */
103     friend std::ostream& operator<<(std::ostream& out,
104                                     const VBucketFilter& filter);
105 
106 private:
107     std::set<Vbid> acceptable;
108 };
109