bitmask

package module
v1.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 12, 2024 License: MIT Imports: 6 Imported by: 0

README

bitmask

Go Reference Coverage Badge

Arbitrary size bitmask (aka bitset) with efficient Slice method.

.Slice doesn't create copies of the underlying buffer, just like Go slices
bm := bitmask.New(4)        // [4]{0000}
bm.Set(3)                   // [4]{0001}
bm.Slice(2, 4).ToggleAll()  // [4]{0010}
bm.Slice(1, 3).ToggleAll()  // [4]{0100}
bm.Slice(0, 2).ToggleAll()  // [4]{1000}
bm.ClearAll()               // [4]{0000}
It's safe to copy overlapping bitmasks, which were created by slicing the original one
base := bitmask.New(10)
base.Set(0)
base.Set(9)                 // [10]{1000000001}

src := base.Slice(0, 8)     // [8]{10000000}
dst := base.Slice(2, 10)    // [8]{00000001}

bitmask.Copy(dst, src)

fmt.Println(base)
[10]{1010000000}
Iterator

Go >=1.23 iterator is exposed by .Bits() method:

bm := bitmask.New(5)
bm.Set(0)
bm.Set(3)

for idx, isSet := range bm.Bits() {
    // use the value
    fmt.Printf("%v) %v\n", index, value)
}

There's also an old-style equivalent:

it := bm.Iterator()
for {
    ok, value, index := it.Next()
    if !ok {
        break
    }

    // use the value
    fmt.Printf("%v) %v\n", index, value)
}
0) true
1) false
2) false
3) true
4) false
.String() is O(1), it starts stripping after 512 bits
bm := bitmask.New(513)
bm.Slice(255, 321).SetAll()
fmt.Println(bm)
[513]{0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000001 <more 64 bits> 1000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0}
Non-copying constructor to avoid heap-allocating bit buffer
bm := bitmask.NewFromUintRawNocopy(1, 2, 3)

From go build -gcflags=-m

inlining call to bitmask.NewFromUintRawNocopy
... argument does not escape
&bitmask.BitMask{...} does not escape

Documentation

Overview

Package bitmask is an implementation of an arbitrary size sequence of bits with Go-like Slice method.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Copy

func Copy(dst *BitMask, src *BitMask) uint

Copies bits from a source bit mask into a destination bit mask. It's safe to copy overlapping bitmasks (which were created by slicing the original one). Returns the number of bits copied, which will be the minimum of src.Len() and dst.Len().

Types

type BitIterator added in v0.2.0

type BitIterator struct {
	// Atttempts to get the next item from the iterator.
	// If there're no more values left, ok will be false.
	Next func() (ok bool, isSet bool, index uint)

	// Resets iterator, so it can be reused
	Reset func()
}

Stateful iterator. Example of usage:

it := bm.Iterator()
for {
	ok, value, index := it.Next()
	if !ok {
		break;
	}
	// use the value
}

type BitMask

type BitMask struct {
	// contains filtered or unexported fields
}

Represents a fixed-size array of 0/1 bits.

func New

func New(len uint) *BitMask

Creates new BitMask of specified length (number of bits). All bits will be cleared.

func NewFromUint

func NewFromUint(values ...uint) *BitMask

Create a bitmask from uints, automatically reversing endianness, so that NewFromUint(1) produces the bitmask with the lowest (leftmost) bit set. Len() of the resulting bitmask will always be equal to len(values) * sizeof(uint).

func NewFromUintRaw added in v1.2.0

func NewFromUintRaw(values ...uint) *BitMask

Create a bitmask from uints, without endianness reversal, more effective version of NewFromUint

func NewFromUintRawNocopy added in v1.3.0

func NewFromUintRawNocopy(values ...uint) *BitMask

Works like NewFromUintRaw, but doesn't create own buffer for bits. Helps reducing heap allocations. Use with caution, since shared buffer is the likely source of complex bugs.

func (*BitMask) Bits added in v1.3.0

func (bm *BitMask) Bits() iter.Seq2[uint, bool]

Go >=1.23 iterator. Equivalent of Iterator().

func (*BitMask) Clear

func (bm *BitMask) Clear(bitIndex uint)

Clears the bit by bitIndex (sets it to 0).

func (*BitMask) ClearAll added in v0.2.0

func (bm *BitMask) ClearAll()

Clears all bits. Use in combination with Slice to clear the range of bits.

func (*BitMask) IsSet

func (bm *BitMask) IsSet(bitIndex uint) bool

Checks, whether the bit by bitIndex is set or cleared. Returns true if bit is set, and false if it's cleared.

func (*BitMask) Iterator

func (bm *BitMask) Iterator() BitIterator

Creates stateful iterator to iterate through all the bits. See BitIterator doc for an example. It is an equivalent of just calling IsSet for each bit of a BitMask. For Go >=1.23 also consider Bits(), which is equivalent.

func (*BitMask) Len

func (bm *BitMask) Len() uint

Returns the legth of bitmask in bits. It will never be changed for the given receiver.

func (*BitMask) LenUint added in v1.2.0

func (bm *BitMask) LenUint() int

Returns the legth of bitmask in uints. Result is always positive and multiple of size(uint), e.g.: 32, 64, 96, 128, ...

func (*BitMask) Set

func (bm *BitMask) Set(bitIndex uint)

Sets the bit by bitIndex to 1.

func (*BitMask) SetAll added in v0.2.0

func (bm *BitMask) SetAll()

Sets all bits to 1. Use in combination with Slice to set the range of bits.

func (*BitMask) Slice

func (bm *BitMask) Slice(fromBit uint, toBit uint) *BitMask

Effectively creates a new BitMask, without copying elements, just like regular slices work. As a side-effect, change to the sliced bitmask will be visible to original bitmask (and other way around), as well as to other "overlapping" slices. Selects a half-open range which includes the "from" bit, but excludes the "to" one.

func (*BitMask) String added in v0.2.0

func (bm *BitMask) String() string

Returns string representation of a bitmask in the form "[length]{bits}". For example: [4]{0100} It is O(1) operation and it will skip bits after some amount of them. Should not be parsed, format is not fixed.

func (*BitMask) Toggle

func (bm *BitMask) Toggle(bitIndex uint)

Reverses the value of the bit by bitIndex.

func (*BitMask) ToggleAll added in v0.2.0

func (bm *BitMask) ToggleAll()

Reverses the value of all bits. Use in combination with Slice to reverse the range of bits.

func (*BitMask) Uint added in v1.2.0

func (bm *BitMask) Uint(index int) uint

Returns uint by index, reversing the endianness, so that {1000...} bitmask is represented by uint(1)

func (*BitMask) UintRaw added in v1.2.0

func (bm *BitMask) UintRaw(index int) uint

Returns uint without reversing, more effective version of Uint method

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL