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 "config.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<uint16_t>& a)40     VBucketFilter(const std::vector<uint16_t>& a)
41         : acceptable(a.begin(), a.end()) {
42     }
43 
VBucketFilter(std::set<uint16_t> s)44     VBucketFilter(std::set<uint16_t> s) : acceptable(std::move(s)) {
45     }
46 
assign(const std::set<uint16_t>& a)47     void assign(const std::set<uint16_t>& a) {
48         acceptable = a;
49     }
50 
operator ()(uint16_t v) const51     bool operator()(uint16_t v) const {
52         return acceptable.empty() || acceptable.find(v) != acceptable.end();
53     }
54 
size() const55     size_t size() const {
56         return acceptable.size();
57     }
58 
empty() const59     bool empty() const {
60         return acceptable.empty();
61     }
62 
reset()63     void reset() {
64         acceptable.clear();
65     }
66 
67     /**
68      * Calculate the difference between this and another filter.
69      * If "this" contains elements, [1,2,3,4] and other contains [3,4,5,6]
70      * the returned filter contains: [1,2,5,6]
71      * @param other the other filter to compare with
72      * @return a new filter with the elements present in only one of the two
73      *         filters.
74      */
75     VBucketFilter filter_diff(const VBucketFilter& other) const;
76 
77     /**
78      * Calculate the intersection between this and another filter.
79      * If "this" contains elements, [1,2,3,4] and other contains [3,4,5,6]
80      * the returned filter contains: [3,4]
81      * @param other the other filter to compare with
82      * @return a new filter with the elements present in both of the two
83      *         filters.
84      */
85     VBucketFilter filter_intersection(const VBucketFilter& other) const;
86 
getVBSet() const87     const std::set<uint16_t>& getVBSet() const {
88         return acceptable;
89     }
90 
addVBucket(uint16_t vbucket)91     bool addVBucket(uint16_t vbucket) {
92         auto rv = acceptable.insert(vbucket);
93         return rv.second;
94     }
95 
removeVBucket(uint16_t vbucket)96     void removeVBucket(uint16_t vbucket) {
97         acceptable.erase(vbucket);
98     }
99 
100     /**
101      * Dump the filter in a human readable form ( "{ bucket, bucket, bucket }"
102      * to the specified output stream.
103      */
104     friend std::ostream& operator<<(std::ostream& out,
105                                     const VBucketFilter& filter);
106 
107 private:
108     std::set<uint16_t> acceptable;
109 };
110