// Add appends the bits given its size to the vector. func (v *BitVector) Add(bits uint64, size int) { if size <= 0 || size > 64 { panic("ranksel: bit size must be in range [1,64]") } // Add bits v.bits.Add(bits, size) vlength := v.bits.Len() // Increment popcount popcnt := bit.PopCount(bits) v.popcount += popcnt // Update rank sampling lenranks := len(v.ranks) overflow := vlength - (lenranks * v.opts.Sr) if overflow > 0 { v.ranks = append(v.ranks, 0) rank := bit.Rank(bits, size-overflow-1) v.ranks[lenranks] = v.popcount - popcnt + rank } // Update select sampling lenidx := len(v.indices) overflow = v.popcount - (lenidx * v.opts.Ss) if overflow > 0 { v.indices = append(v.indices, 0) sel := bit.Select(bits, popcnt-overflow+1) v.indices[lenidx] = (vlength - size + sel) & ^0x3F } }
// Select0 returns the index of the ith zero. Panics // if i is zero or greater than the number of zeroes. // This is slower than Select1 in most cases. func (v *BitVector) Select0(i int) int { if i > (v.bits.Len() - v.popcount) { panic("ranksel: input exceeds number of 0s") } else if i == 0 { panic("ranksel: input must be greater than 0") } // Do a binary search on the rank samples to find // the largest rank sample that is less than i. // From https://en.wikipedia.org/wiki/Binary_search_algorithm imin := 1 imax := len(v.ranks) - 1 for imin < imax { imid := imin + ((imax - imin) >> 1) rmid0 := (imid * v.opts.Sr) - v.ranks[imid] if rmid0 < i { imin = imid + 1 } else { imax = imid } } imin-- idx := 0 vbits := v.bits.Bits() aidx := (imin * v.opts.Sr) >> 6 rank0 := (imin * v.opts.Sr) - v.ranks[imin] for ii, b := range vbits[aidx:] { b = ^b rank0 += bit.PopCount(b) if rank0 >= i { overflow := rank0 - i popcnt := bit.PopCount(b) idx = (aidx + ii) << 6 idx += bit.Select(b, popcnt-overflow) break } } return idx }
// Select1 returns the index of the ith set bit. // Panics if i is zero or greater than the number // of set bits. func (v *BitVector) Select1(i int) int { if i > v.popcount { panic("ranksel: input exceeds number of 1s") } else if i == 0 { panic("ranksel: input must be greater than 0") } j := (i - 1) / v.opts.Ss q := v.indices[j] / v.opts.Sr k := 0 r := 0 rq := v.ranks[q:] for k, r = range rq { if r >= i { k-- break } } idx := 0 rank := rq[k] vbits := v.bits.Bits() aidx := ((q + k) * v.opts.Sr) >> 6 for ii, b := range vbits[aidx:] { rank += bit.PopCount(b) if rank >= i { overflow := rank - i popcnt := bit.PopCount(b) idx = (aidx + ii) << 6 idx += bit.Select(b, popcnt-overflow) break } } return idx }
// popcount11 counts the number of 11 pairs // in v. This assumes that v doesn't contain // more than 3 consecutive 1s. This assumption // is satisfied since the minimum encoded value // is 011. func popcount11_64(v uint64) int { // Reduce cluster of 1s by 1. // This makes 11 to 01, 111 to 011, // and unsets all 1s. v &= v >> 1 // Reduces all 11s to 10s // while maintaining all lone 1s. v &= ^(v >> 1) // Proceed to regular bit counting return bit.PopCount(v) }
// Rank1 counts the number of 1s from // the beginning up to the ith index. func (v *BitVector) Rank1(i int) int { if i >= v.bits.Len() { panic("ranksel: index out of range") } j := i / v.opts.Sr ip := (j * v.opts.Sr) >> 6 rank := v.ranks[j] aidx := i & 63 bidx := i >> 6 vbits := v.bits.Bits() for _, b := range vbits[ip:bidx] { rank += bit.PopCount(b) } return rank + bit.Rank(vbits[bidx], aidx) }