// 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 } }
// select11 returns the index of the ith 11 pair. func select11_64(v uint64, i int) int { // Same with popcount11 v &= v >> 1 v &= ^(v >> 1) // Perform regular select return bit.Select(v, i) }
// Get returns the value at index i. func (a *Array) Get(i int) int { start := a.selector.Select1(i + 1) bits := a.selector.Get(start, min(64, a.selector.Len()-start)) length := bit.Select(bits, 2) code := a.bits.Get(start, length) return decode(code, length) }
// 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 }