Dobby  3.0
Dobby “Docker based Thingy” is a tool for managing and running OCI containers using crun
IDGenerator.h
1 /*
2 * If not stated otherwise in this file or this component's LICENSE file the
3 * following copyright and licenses apply:
4 *
5 * Copyright 2016 Sky UK
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19 /*
20  * File: IDGenerator.h
21  *
22  */
23 #ifndef IDGENERATOR_H
24 #define IDGENERATOR_H
25 
26 #include <bitset>
27 #include <mutex>
28 
29 #include <math.h>
30 #include <stdlib.h>
31 
32 namespace AICommon
33 {
34 
35 // -----------------------------------------------------------------------------
60 template< std::size_t N >
62 {
63  static_assert(((N >= 4) && (N <= 20)), "N template value is invalid (3 < N < 21)");
64 
65 private:
66  // The total number of possible values to generate
67  static const unsigned mSize = (1u << N);
68 
69  // Polynomial values from https://users.ece.cmu.edu/~koopman/lfsr/index.html
70  static const unsigned mPolynomial = (N == 4) ? 0x9 :
71  (N == 5) ? 0x1B :
72  (N == 6) ? 0x36 :
73  (N == 7) ? 0x5F :
74  (N == 8) ? 0xE1 :
75  (N == 9) ? 0x1B0 :
76  (N == 10) ? 0x3A6 :
77  (N == 11) ? 0x574 :
78  (N == 12) ? 0xC48 :
79  (N == 13) ? 0x11D4 :
80  (N == 14) ? 0x214E :
81  (N == 15) ? 0x41A6 :
82  (N == 16) ? 0x84BE :
83  (N == 17) ? 0x1022E :
84  (N == 18) ? 0x20196 :
85  (N == 19) ? 0x4032F :
86  (N == 20) ? 0x80534 : 0;
87 
88 public:
89  IDGenerator(unsigned offset = 0)
90  : mOffset(offset)
91  , mLfsr(1 + (rand() % (mSize- 2)))
92  { }
93 
94 public:
95  int get()
96  {
97  std::lock_guard<std::mutex> locker(mLock);
98 
99  // sanity check we haven't used up all the container ids
100  if (mUsed.count() >= (mSize - 1))
101  return -1;
102 
103  // use a fibonacci LFSR to cycle through the possible numbers rather
104  // than just a random number generator or a sequential search
105  do
106  {
107  unsigned lsb = (mLfsr & 0x1u);
108  mLfsr >>= 1;
109 
110  if (lsb)
111  mLfsr ^= mPolynomial;
112 
113  } while (mUsed.test(mLfsr) == true);
114 
115 
116  // reserve the id and return it
117  mUsed.set(mLfsr);
118  return static_cast<int>(mOffset + mLfsr);
119  }
120 
121  bool put(int id)
122  {
123  std::lock_guard<std::mutex> locker(mLock);
124 
125  // sanity check the id is within the valid range
126  if ((id < 0) || (id <= static_cast<int>(mOffset)) ||
127  ((id - mOffset) >= static_cast<int>(mSize)))
128  return false;
129 
130  // sanity check the bit is set in the 'used' set
131  if (!mUsed.test(id - mOffset))
132  return false;
133 
134  mUsed.reset(id - mOffset);
135  return true;
136  }
137 
138  void clear()
139  {
140  std::lock_guard<std::mutex> locker(mLock);
141 
142  // clear all the 'used' bits which effectively makes all id's available
143  // again
144  mUsed.reset();
145  }
146 
147 private:
148  const unsigned mOffset;
149  unsigned mLfsr;
150 
151  mutable std::mutex mLock;
152  std::bitset<mSize> mUsed;
153 };
154 
155 
156 } // namespace AICommon
157 
158 
159 #endif // !defined(IDGENERATOR_H)
Class used to generate unique numbers.
Definition: IDGenerator.h:62