2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_UTIL_MULTIBITSET_H_
18 #define incl_HPHP_UTIL_MULTIBITSET_H_
23 #include <unordered_map>
27 ///////////////////////////////////////////////////////////////////////////////
30 * Like a bitset, but we have N bits at each position instead of 1.
35 * Create an empty multibitset with no bits allocated.
40 * Allocate a multibitset with room for `nelms' N-bits, and zero it.
42 explicit multibitset(size_t nelms
);
45 * Free the allocated bits.
50 * Make room for `nelms' N-bits in the set, shrinking it if `nelms' is
51 * smaller than the current size.
53 void resize(size_t nelms
);
56 * Set all N-bits to zero.
60 /////////////////////////////////////////////////////////////////////////////
63 * Reference to an N-bit.
65 * Behaves analogously to std::bitset::reference.
68 /* implicit */ operator uint64_t() const;
69 reference
& operator=(uint64_t);
71 friend struct multibitset
<N
>;
74 reference(multibitset
<N
>& mbs
, size_t pos
);
77 multibitset
<N
>& m_mbs
;
82 static constexpr size_t npos
= std::numeric_limits
<uint64_t>::max();
84 /////////////////////////////////////////////////////////////////////////////
87 * Access a specific N-bit.
89 * This asserts that `pos <= N'; as such, we do not implement a test().
91 uint64_t operator[](size_t pos
) const;
92 reference
operator[](size_t pos
);
95 * Returns the number of N-bits the multibitset can hold.
100 * Find the position of the first or last N-bit set to a nonzero value,
101 * starting at `pos'. Note that `pos' is an inclusive bound, so `pos' itself
104 * Returns `npos' if no set N-bit is found.
106 size_t ffs(size_t pos
= 0) const;
107 size_t fls(size_t pos
= npos
) const;
109 /////////////////////////////////////////////////////////////////////////////
112 static_assert(N
> 0 && N
< 64, "must have 0 < N < 64");
115 uint64_t* m_bits
{nullptr};
121 constexpr size_t multibitset
<N
>::npos
;
123 ///////////////////////////////////////////////////////////////////////////////
126 * An alternate multibitset interface intended for use patterns with sparse
127 * clusters of marked bits.
129 * Has roughly the same interface as multibitset, with exceptions noted.
132 struct chunked_multibitset
{
134 * Create an empty multibitset.
136 * chunked_multibitset automatically expands storage as bits are set. Thus,
137 * it does not accept a size restriction; instead, it takes a chunk size.
139 explicit chunked_multibitset(size_t chunk_sz
);
141 /////////////////////////////////////////////////////////////////////////////
144 /* implicit */ operator uint64_t() const;
145 reference
& operator=(uint64_t);
147 friend struct chunked_multibitset
<N
>;
150 reference(chunked_multibitset
<N
>& cmbs
, size_t pos
);
153 chunked_multibitset
<N
>& m_cmbs
;
157 static constexpr size_t npos
= std::numeric_limits
<uint64_t>::max();
159 /////////////////////////////////////////////////////////////////////////////
164 * Return a reference to an N-bit.
166 * Setting an N-bit may cause new chunks to be allocated.
168 uint64_t operator[](size_t pos
) const;
169 reference
operator[](size_t pos
);
172 * Find set bit; see multibitset::f{f,l}s().
174 * The time complexity of these routines is linearly bounded by the number of
175 * chunks in which bits have been touched during the lifetime of the object.
176 * No other guarantees are made.
178 size_t ffs(size_t pos
= 0) const;
179 size_t fls(size_t pos
= npos
) const;
181 /////////////////////////////////////////////////////////////////////////////
184 static_assert(N
> 0 && N
<= 64, "must have 0 < N <= 64");
186 multibitset
<N
>& chunk_for(size_t pos
);
189 std::unordered_map
<size_t,multibitset
<N
>> m_chunks
;
190 const size_t m_chunk_sz
;
191 size_t m_highwater
{0};
192 size_t m_lowwater
{npos
};
196 constexpr size_t chunked_multibitset
<N
>::npos
;
198 ///////////////////////////////////////////////////////////////////////////////
202 #include "hphp/util/multibitset-inl.h"