1
0
mirror of https://github.com/sjwhitworth/golearn.git synced 2025-04-26 13:49:14 +08:00
golearn/base/bag.go

106 lines
2.3 KiB
Go
Raw Normal View History

package base
import (
"bytes"
"fmt"
)
// BinaryAttributeGroups contain only BinaryAttributes
// Compact each Attribute to a bit for better storage
type BinaryAttributeGroup struct {
parent DataGrid
attributes []Attribute
size int
alloc []byte
maxRow int
}
// String returns a human-readable summary.
2014-09-18 22:04:05 +01:00
func (b *BinaryAttributeGroup) String() string {
return "BinaryAttributeGroup"
}
// RowSizeInBytes returns the size of each row in bytes
// (rounded up to nearest byte).
func (b *BinaryAttributeGroup) RowSizeInBytes() int {
2014-09-18 22:04:05 +01:00
return (len(b.attributes) + 7) / 8
}
// Attributes returns a slice of Attributes in this BinaryAttributeGroup.
func (b *BinaryAttributeGroup) Attributes() []Attribute {
ret := make([]Attribute, len(b.attributes))
for i, a := range b.attributes {
ret[i] = a
}
return ret
}
// AddAttribute adds an Attribute to this BinaryAttributeGroup
func (b *BinaryAttributeGroup) AddAttribute(a Attribute) error {
b.attributes = append(b.attributes, a)
return nil
}
// Storage returns a reference to the underlying storage.
//
// IMPORTANT: don't modify
func (b *BinaryAttributeGroup) Storage() []byte {
return b.alloc
}
//
// internal methods
//
func (b *BinaryAttributeGroup) setStorage(a []byte) {
b.alloc = a
}
func (b *BinaryAttributeGroup) getByteOffset(col, row int) int {
return row*b.RowSizeInBytes() + col/8
}
func (b *BinaryAttributeGroup) set(col, row int, val []byte) {
offset := b.getByteOffset(col, row)
// If the value is 1, OR it
if val[0] > 0 {
b.alloc[offset] |= (1 << (uint(col) % 8))
} else {
// Otherwise, AND its complement
b.alloc[offset] &= ^(1 << (uint(col) % 8))
}
row++
if row > b.maxRow {
b.maxRow = row
}
}
func (b *BinaryAttributeGroup) get(col, row int) []byte {
offset := b.getByteOffset(col, row)
if b.alloc[offset]&(1<<(uint(col%8))) > 0 {
return []byte{1}
} else {
return []byte{0}
}
}
func (b *BinaryAttributeGroup) appendToRowBuf(row int, buffer *bytes.Buffer) {
for i, a := range b.attributes {
postfix := " "
if i == len(b.attributes)-1 {
postfix = ""
}
buffer.WriteString(fmt.Sprintf("%s%s",
a.GetStringFromSysVal(b.get(i, row)), postfix))
}
}
func (b *BinaryAttributeGroup) resize(add int) {
newAlloc := make([]byte, len(b.alloc)+add)
copy(newAlloc, b.alloc)
b.alloc = newAlloc
}