YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/util/uint_set.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) YugaByte, Inc.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
4
// in compliance with the License.  You may obtain a copy of the License at
5
//
6
// http://www.apache.org/licenses/LICENSE-2.0
7
//
8
// Unless required by applicable law or agreed to in writing, software distributed under the License
9
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
10
// or implied.  See the License for the specific language governing permissions and limitations
11
// under the License.
12
//
13
#ifndef YB_UTIL_UINT_SET_H
14
#define YB_UTIL_UINT_SET_H
15
16
#include <boost/icl/discrete_interval.hpp>
17
#include <boost/icl/interval_set.hpp>
18
#include <google/protobuf/repeated_field.h>
19
20
#include "yb/gutil/strings/join.h"
21
22
#include "yb/util/status.h"
23
#include "yb/util/status_format.h"
24
25
namespace yb {
26
27
// Tracks the on/off state of a set of unsigned integers. Initially, all integers are in the "off"
28
// state, and ranges of integers can be set to "on". Individual integers can then be tested. This
29
// class currently does not support turning indexes "off".
30
//
31
// This class is designed to support efficient encoding/decoding of state into any valid numeric
32
// google::protobuf::RepeatedField<T>.
33
//
34
// Under the hood, this class tracks the state of integer indexes in both an interval_set to enable
35
// efficient serialization into a numeric RepeatedField.
36
template <class T>
37
class UnsignedIntSet {
38
 public:
39
15.4M
  UnsignedIntSet() {}
_ZN2yb14UnsignedIntSetIjEC2Ev
Line
Count
Source
39
15.4M
  UnsignedIntSet() {}
_ZN2yb14UnsignedIntSetItEC2Ev
Line
Count
Source
39
10
  UnsignedIntSet() {}
40
41
  // Set the indexes of this set in [lo, hi] to "on". It is perfectly valid to call SetRange with
42
  // lo = hi.
43
88.0k
  CHECKED_STATUS SetRange(T lo, T hi) {
44
88.0k
    SCHECK_LE(lo, hi, InvalidArgument, Format("Called SetRange with lo ($0) > hi ($1).", lo, hi));
45
88.0k
    interval_set_ += ElementRange::closed(lo, hi);
46
88.0k
    return Status::OK();
47
88.0k
  }
48
49
  // Return true if index at val is "on".
50
173M
  bool Test(T val) const {
51
173M
    return interval_set_.find(val) != interval_set_.end();
52
173M
  }
53
54
  // Returns true if this set is empty.
55
1.40k
  bool IsEmpty() const {
56
1.40k
    return interval_set_.empty();
57
1.40k
  }
58
59
  template <class Container>
60
3.04M
  static Result<UnsignedIntSet<T>> FromPB(const Container& container) {
61
3.04M
    UnsignedIntSet set;
62
63
3.04M
    auto run_length_size = container.size();
64
65
3.04M
    if (run_length_size == 0) {
66
2.97M
      return set;
67
2.97M
    }
68
69
68.6k
    if (run_length_size % 2 != 0) {
70
0
      return STATUS(
71
0
        InvalidArgument,
72
0
        Format("Expect even number of run lengths in container, got $0", run_length_size));
73
0
    }
74
75
68.6k
    uint32_t prev = 0;
76
132k
    for (auto run = container.begin(); run != container.end();) {
77
63.7k
      auto start = prev += *run++;
78
63.7k
      auto finish = (prev += *run++) - 1;
79
63.7k
      RETURN_NOT_OK(set.SetRange(start, finish));
80
63.7k
    }
81
82
68.6k
    return set;
83
68.6k
  }
84
85
64.2k
  void ToPB(google::protobuf::RepeatedField<T>* mutable_container) const {
86
64.2k
    uint32_t last_unset = 0;
87
63.1k
    for (const auto& elem : interval_set_) {
88
63.1k
      mutable_container->Add(elem.lower() - last_unset);
89
63.1k
      mutable_container->Add(elem.upper() - elem.lower() + 1);
90
63.1k
      last_unset = elem.upper() + 1;
91
63.1k
    }
92
64.2k
  }
93
94
0
  std::string ToString() const {
95
0
    std::vector<std::string> parts;
96
0
    for (const auto& elem : interval_set_) {
97
0
      parts.push_back(Format("[$0, $1]", elem.lower(), elem.upper()));
98
0
    }
99
0
    return JoinStrings(parts, ", ");
100
0
  }
101
102
 private:
103
  using ElementType = uint32_t;
104
  using ElementRange = boost::icl::discrete_interval<ElementType>;
105
  using ElementRangeSet = boost::icl::interval_set<ElementType>;
106
  ElementRangeSet interval_set_;
107
};
108
109
} // namespace yb
110
111
#endif // YB_UTIL_UINT_SET_H