71 lines
2.9 KiB
Go
Vendored
71 lines
2.9 KiB
Go
Vendored
// +build !go1.9
|
|
|
|
package roaring
|
|
|
|
// Reuse of portions of go/src/math/big standard lib code
|
|
// under this license:
|
|
/*
|
|
Copyright (c) 2009 The Go Authors. All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions are
|
|
met:
|
|
|
|
* Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
* Redistributions in binary form must reproduce the above
|
|
copyright notice, this list of conditions and the following disclaimer
|
|
in the documentation and/or other materials provided with the
|
|
distribution.
|
|
* Neither the name of Google Inc. nor the names of its
|
|
contributors may be used to endorse or promote products derived from
|
|
this software without specific prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
const deBruijn32 = 0x077CB531
|
|
|
|
var deBruijn32Lookup = []byte{
|
|
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
|
|
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9,
|
|
}
|
|
|
|
const deBruijn64 = 0x03f79d71b4ca8b09
|
|
|
|
var deBruijn64Lookup = []byte{
|
|
0, 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4,
|
|
62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5,
|
|
63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11,
|
|
54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6,
|
|
}
|
|
|
|
// trailingZeroBits returns the number of consecutive least significant zero
|
|
// bits of x.
|
|
func countTrailingZeros(x uint64) int {
|
|
// x & -x leaves only the right-most bit set in the word. Let k be the
|
|
// index of that bit. Since only a single bit is set, the value is two
|
|
// to the power of k. Multiplying by a power of two is equivalent to
|
|
// left shifting, in this case by k bits. The de Bruijn constant is
|
|
// such that all six bit, consecutive substrings are distinct.
|
|
// Therefore, if we have a left shifted version of this constant we can
|
|
// find by how many bits it was shifted by looking at which six bit
|
|
// substring ended up at the top of the word.
|
|
// (Knuth, volume 4, section 7.3.1)
|
|
if x == 0 {
|
|
// We have to special case 0; the fomula
|
|
// below doesn't work for 0.
|
|
return 64
|
|
}
|
|
return int(deBruijn64Lookup[((x&-x)*(deBruijn64))>>58])
|
|
}
|