bitfield: fix bf.from_bytes/1 ( now, bf.from_bytes(b) == bf.from_str(bf.from_bytes(b).str()) )
parent
05f6e8b5aa
commit
c5c310280f
|
@ -12,11 +12,10 @@ Bit arrays are stored in data structures called 'BitField'. The structure is
|
||||||
'opaque', i.e. its internals are not available to the end user. This module
|
'opaque', i.e. its internals are not available to the end user. This module
|
||||||
provides API (functions and methods) for accessing and modifying bit arrays.
|
provides API (functions and methods) for accessing and modifying bit arrays.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pub struct BitField {
|
pub struct BitField {
|
||||||
mut:
|
mut:
|
||||||
size int
|
size int
|
||||||
//field *u32
|
// field *u32
|
||||||
field []u32
|
field []u32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,12 +25,36 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
// public functions
|
// public functions
|
||||||
|
|
||||||
// from_bytes() converts a byte array into a bitfield.
|
// from_bytes() converts a byte array into a bitfield.
|
||||||
pub fn from_bytes(input []byte) BitField {
|
pub fn from_bytes(input []byte) BitField {
|
||||||
mut output := new(input.len * 8)
|
mut output := new(input.len * 8)
|
||||||
for i, b in input {
|
for i, b in input {
|
||||||
output.field[i / 4] |= u32(b) << ((i % 4) * 8)
|
mut ob := byte(0)
|
||||||
|
if b & 0b10000000 > 0 {
|
||||||
|
ob |= 0b00000001
|
||||||
|
}
|
||||||
|
if b & 0b01000000 > 0 {
|
||||||
|
ob |= 0b00000010
|
||||||
|
}
|
||||||
|
if b & 0b00100000 > 0 {
|
||||||
|
ob |= 0b00000100
|
||||||
|
}
|
||||||
|
if b & 0b00010000 > 0 {
|
||||||
|
ob |= 0b00001000
|
||||||
|
}
|
||||||
|
if b & 0b00001000 > 0 {
|
||||||
|
ob |= 0b00010000
|
||||||
|
}
|
||||||
|
if b & 0b00000100 > 0 {
|
||||||
|
ob |= 0b00100000
|
||||||
|
}
|
||||||
|
if b & 0b00000010 > 0 {
|
||||||
|
ob |= 0b01000000
|
||||||
|
}
|
||||||
|
if b & 0b00000001 > 0 {
|
||||||
|
ob |= 0b10000000
|
||||||
|
}
|
||||||
|
output.field[i / 4] |= u32(ob) << ((i % 4) * 8)
|
||||||
}
|
}
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
@ -40,7 +63,7 @@ pub fn from_bytes(input []byte) BitField {
|
||||||
// array. Any character different from '0' is treated as '1'.
|
// array. Any character different from '0' is treated as '1'.
|
||||||
pub fn from_str(input string) BitField {
|
pub fn from_str(input string) BitField {
|
||||||
mut output := new(input.len)
|
mut output := new(input.len)
|
||||||
for i in 0..input.len {
|
for i in 0 .. input.len {
|
||||||
if input[i] != `0` {
|
if input[i] != `0` {
|
||||||
output.set_bit(i)
|
output.set_bit(i)
|
||||||
}
|
}
|
||||||
|
@ -52,11 +75,10 @@ pub fn from_str(input string) BitField {
|
||||||
// return the string
|
// return the string
|
||||||
pub fn (input BitField) str() string {
|
pub fn (input BitField) str() string {
|
||||||
mut output := ''
|
mut output := ''
|
||||||
for i in 0..input.size {
|
for i in 0 .. input.size {
|
||||||
if input.get_bit(i) == 1 {
|
if input.get_bit(i) == 1 {
|
||||||
output = output + '1'
|
output = output + '1'
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
output = output + '0'
|
output = output + '0'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,18 +89,18 @@ pub fn (input BitField) str() string {
|
||||||
pub fn new(size int) BitField {
|
pub fn new(size int) BitField {
|
||||||
output := BitField{
|
output := BitField{
|
||||||
size: size
|
size: size
|
||||||
//field: *u32(calloc(zbitnslots(size) * slot_size / 8))
|
// field: *u32(calloc(zbitnslots(size) * slot_size / 8))
|
||||||
field: []u32{len:zbitnslots(size)}
|
field: []u32{len: zbitnslots(size)}
|
||||||
}
|
}
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
pub fn del(instance *BitField) {
|
pub fn del(instance *BitField) {
|
||||||
free(instance.field)
|
free(instance.field)
|
||||||
free(instance)
|
free(instance)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// get_bit returns the value (0 or 1) of bit number 'bit_nr' (count from 0).
|
// get_bit returns the value (0 or 1) of bit number 'bit_nr' (count from 0).
|
||||||
pub fn (instance BitField) get_bit(bitnr int) int {
|
pub fn (instance BitField) get_bit(bitnr int) int {
|
||||||
if bitnr >= instance.size {
|
if bitnr >= instance.size {
|
||||||
|
@ -105,7 +127,7 @@ pub fn (mut instance BitField) clear_bit(bitnr int) {
|
||||||
|
|
||||||
// set_all sets all bits in the array to 1.
|
// set_all sets all bits in the array to 1.
|
||||||
pub fn (mut instance BitField) set_all() {
|
pub fn (mut instance BitField) set_all() {
|
||||||
for i in 0..zbitnslots(instance.size) {
|
for i in 0 .. zbitnslots(instance.size) {
|
||||||
instance.field[i] = u32(-1)
|
instance.field[i] = u32(-1)
|
||||||
}
|
}
|
||||||
instance.clear_tail()
|
instance.clear_tail()
|
||||||
|
@ -113,7 +135,7 @@ pub fn (mut instance BitField) set_all() {
|
||||||
|
|
||||||
// clear_all clears (sets to zero) all bits in the array.
|
// clear_all clears (sets to zero) all bits in the array.
|
||||||
pub fn (mut instance BitField) clear_all() {
|
pub fn (mut instance BitField) clear_all() {
|
||||||
for i in 0..zbitnslots(instance.size) {
|
for i in 0 .. zbitnslots(instance.size) {
|
||||||
instance.field[i] = u32(0)
|
instance.field[i] = u32(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,7 +156,7 @@ pub fn bf_and(input1 BitField, input2 BitField) BitField {
|
||||||
size := min(input1.size, input2.size)
|
size := min(input1.size, input2.size)
|
||||||
bitnslots := zbitnslots(size)
|
bitnslots := zbitnslots(size)
|
||||||
mut output := new(size)
|
mut output := new(size)
|
||||||
for i in 0..bitnslots {
|
for i in 0 .. bitnslots {
|
||||||
output.field[i] = input1.field[i] & input2.field[i]
|
output.field[i] = input1.field[i] & input2.field[i]
|
||||||
}
|
}
|
||||||
output.clear_tail()
|
output.clear_tail()
|
||||||
|
@ -146,7 +168,7 @@ pub fn bf_not(input BitField) BitField {
|
||||||
size := input.size
|
size := input.size
|
||||||
bitnslots := zbitnslots(size)
|
bitnslots := zbitnslots(size)
|
||||||
mut output := new(size)
|
mut output := new(size)
|
||||||
for i in 0..bitnslots {
|
for i in 0 .. bitnslots {
|
||||||
output.field[i] = ~input.field[i]
|
output.field[i] = ~input.field[i]
|
||||||
}
|
}
|
||||||
output.clear_tail()
|
output.clear_tail()
|
||||||
|
@ -160,7 +182,7 @@ pub fn bf_or(input1 BitField, input2 BitField) BitField {
|
||||||
size := min(input1.size, input2.size)
|
size := min(input1.size, input2.size)
|
||||||
bitnslots := zbitnslots(size)
|
bitnslots := zbitnslots(size)
|
||||||
mut output := new(size)
|
mut output := new(size)
|
||||||
for i in 0..bitnslots {
|
for i in 0 .. bitnslots {
|
||||||
output.field[i] = input1.field[i] | input2.field[i]
|
output.field[i] = input1.field[i] | input2.field[i]
|
||||||
}
|
}
|
||||||
output.clear_tail()
|
output.clear_tail()
|
||||||
|
@ -174,7 +196,7 @@ pub fn bf_xor(input1 BitField, input2 BitField) BitField {
|
||||||
size := min(input1.size, input2.size)
|
size := min(input1.size, input2.size)
|
||||||
bitnslots := zbitnslots(size)
|
bitnslots := zbitnslots(size)
|
||||||
mut output := new(size)
|
mut output := new(size)
|
||||||
for i in 0..bitnslots {
|
for i in 0 .. bitnslots {
|
||||||
output.field[i] = input1.field[i] ^ input2.field[i]
|
output.field[i] = input1.field[i] ^ input2.field[i]
|
||||||
}
|
}
|
||||||
output.clear_tail()
|
output.clear_tail()
|
||||||
|
@ -186,19 +208,15 @@ pub fn join(input1 BitField, input2 BitField) BitField {
|
||||||
output_size := input1.size + input2.size
|
output_size := input1.size + input2.size
|
||||||
mut output := new(output_size)
|
mut output := new(output_size)
|
||||||
// copy the first input to output as is
|
// copy the first input to output as is
|
||||||
for i in 0..zbitnslots(input1.size) {
|
for i in 0 .. zbitnslots(input1.size) {
|
||||||
output.field[i] = input1.field[i]
|
output.field[i] = input1.field[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
// find offset bit and offset slot
|
// find offset bit and offset slot
|
||||||
offset_bit := input1.size % slot_size
|
offset_bit := input1.size % slot_size
|
||||||
offset_slot := input1.size / slot_size
|
offset_slot := input1.size / slot_size
|
||||||
|
for i in 0 .. zbitnslots(input2.size) {
|
||||||
for i in 0..zbitnslots(input2.size) {
|
output.field[i + offset_slot] |= u32(input2.field[i] << u32(offset_bit))
|
||||||
output.field[i + offset_slot] |=
|
|
||||||
u32(input2.field[i] << u32(offset_bit))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If offset_bit is not zero, additional operations are needed.
|
* If offset_bit is not zero, additional operations are needed.
|
||||||
* Number of iterations depends on the nr of slots in output. Two
|
* Number of iterations depends on the nr of slots in output. Two
|
||||||
|
@ -213,14 +231,12 @@ pub fn join(input1 BitField, input2 BitField) BitField {
|
||||||
* If offset_bit is zero, no additional copies needed.
|
* If offset_bit is zero, no additional copies needed.
|
||||||
*/
|
*/
|
||||||
if (output_size - 1) % slot_size < (input2.size - 1) % slot_size {
|
if (output_size - 1) % slot_size < (input2.size - 1) % slot_size {
|
||||||
for i in 0..zbitnslots(input2.size) {
|
for i in 0 .. zbitnslots(input2.size) {
|
||||||
output.field[i + offset_slot + 1] |=
|
output.field[i + offset_slot + 1] |= u32(input2.field[i] >> u32(slot_size - offset_bit))
|
||||||
u32(input2.field[i] >> u32(slot_size - offset_bit))
|
|
||||||
}
|
}
|
||||||
} else if (output_size - 1) % slot_size > (input2.size - 1) % slot_size {
|
} else if (output_size - 1) % slot_size > (input2.size - 1) % slot_size {
|
||||||
for i in 0..zbitnslots(input2.size) - 1 {
|
for i in 0 .. zbitnslots(input2.size) - 1 {
|
||||||
output.field[i + offset_slot + 1] |=
|
output.field[i + offset_slot + 1] |= u32(input2.field[i] >> u32(slot_size - offset_bit))
|
||||||
u32(input2.field[i] >> u32(slot_size - offset_bit))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return output
|
return output
|
||||||
|
@ -235,7 +251,7 @@ pub fn (instance BitField) get_size() int {
|
||||||
pub fn (instance BitField) clone() BitField {
|
pub fn (instance BitField) clone() BitField {
|
||||||
bitnslots := zbitnslots(instance.size)
|
bitnslots := zbitnslots(instance.size)
|
||||||
mut output := new(instance.size)
|
mut output := new(instance.size)
|
||||||
for i in 0..bitnslots {
|
for i in 0 .. bitnslots {
|
||||||
output.field[i] = instance.field[i]
|
output.field[i] = instance.field[i]
|
||||||
}
|
}
|
||||||
return output
|
return output
|
||||||
|
@ -244,9 +260,13 @@ pub fn (instance BitField) clone() BitField {
|
||||||
// cmp compares two bit arrays bit by bit and returns 'true' if they are
|
// cmp compares two bit arrays bit by bit and returns 'true' if they are
|
||||||
// identical by length and contents and 'false' otherwise.
|
// identical by length and contents and 'false' otherwise.
|
||||||
pub fn (instance BitField) cmp(input BitField) bool {
|
pub fn (instance BitField) cmp(input BitField) bool {
|
||||||
if instance.size != input.size {return false}
|
if instance.size != input.size {
|
||||||
for i in 0..zbitnslots(instance.size) {
|
return false
|
||||||
if instance.field[i] != input.field[i] {return false}
|
}
|
||||||
|
for i in 0 .. zbitnslots(instance.size) {
|
||||||
|
if instance.field[i] != input.field[i] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -257,14 +277,14 @@ pub fn (instance BitField) pop_count() int {
|
||||||
bitnslots := zbitnslots(size)
|
bitnslots := zbitnslots(size)
|
||||||
tail := size % slot_size
|
tail := size % slot_size
|
||||||
mut count := 0
|
mut count := 0
|
||||||
for i in 0..bitnslots - 1 {
|
for i in 0 .. bitnslots - 1 {
|
||||||
for j in 0..slot_size {
|
for j in 0 .. slot_size {
|
||||||
if u32(instance.field[i] >> u32(j)) & u32(1) == u32(1) {
|
if u32(instance.field[i] >> u32(j)) & u32(1) == u32(1) {
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for j in 0..tail {
|
for j in 0 .. tail {
|
||||||
if u32(instance.field[bitnslots - 1] >> u32(j)) & u32(1) == u32(1) {
|
if u32(instance.field[bitnslots - 1] >> u32(j)) & u32(1) == u32(1) {
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
|
@ -284,7 +304,6 @@ pub fn (haystack BitField) pos(needle BitField) int {
|
||||||
heystack_size := haystack.size
|
heystack_size := haystack.size
|
||||||
needle_size := needle.size
|
needle_size := needle.size
|
||||||
diff := heystack_size - needle_size
|
diff := heystack_size - needle_size
|
||||||
|
|
||||||
// needle longer than haystack; return error code -2
|
// needle longer than haystack; return error code -2
|
||||||
if diff < 0 {
|
if diff < 0 {
|
||||||
return -2
|
return -2
|
||||||
|
@ -312,53 +331,41 @@ pub fn (input BitField) slice(_start int, _end int) BitField {
|
||||||
if start > end {
|
if start > end {
|
||||||
start = end // or panic?
|
start = end // or panic?
|
||||||
}
|
}
|
||||||
|
|
||||||
mut output := new(end - start)
|
mut output := new(end - start)
|
||||||
start_offset := start % slot_size
|
start_offset := start % slot_size
|
||||||
end_offset := (end - 1) % slot_size
|
end_offset := (end - 1) % slot_size
|
||||||
start_slot := start / slot_size
|
start_slot := start / slot_size
|
||||||
end_slot := (end - 1) / slot_size
|
end_slot := (end - 1) / slot_size
|
||||||
output_slots := zbitnslots(end - start)
|
output_slots := zbitnslots(end - start)
|
||||||
|
|
||||||
if output_slots > 1 {
|
if output_slots > 1 {
|
||||||
if start_offset != 0 {
|
if start_offset != 0 {
|
||||||
for i in 0..output_slots - 1 {
|
for i in 0 .. output_slots - 1 {
|
||||||
output.field[i] =
|
output.field[i] = u32(input.field[start_slot + i] >> u32(start_offset))
|
||||||
u32(input.field[start_slot + i] >> u32(start_offset))
|
output.field[i] = output.field[i] | u32(input.field[start_slot + i + 1] << u32(slot_size -
|
||||||
output.field[i] = output.field[i] |
|
start_offset))
|
||||||
u32(input.field[start_slot + i + 1] <<
|
|
||||||
u32(slot_size - start_offset))
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
for i in 0 .. output_slots - 1 {
|
||||||
for i in 0..output_slots - 1 {
|
output.field[i] = u32(input.field[start_slot + i])
|
||||||
output.field[i] =
|
|
||||||
u32(input.field[start_slot + i])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if start_offset > end_offset {
|
if start_offset > end_offset {
|
||||||
output.field[(end - start - 1) / slot_size] =
|
output.field[(end - start - 1) / slot_size] = u32(input.field[end_slot - 1] >> u32(start_offset))
|
||||||
u32(input.field[end_slot - 1] >> u32(start_offset))
|
|
||||||
mut mask := u32((1 << (end_offset + 1)) - 1)
|
mut mask := u32((1 << (end_offset + 1)) - 1)
|
||||||
mask = input.field[end_slot] & mask
|
mask = input.field[end_slot] & mask
|
||||||
mask = u32(mask << u32(slot_size - start_offset))
|
mask = u32(mask << u32(slot_size - start_offset))
|
||||||
output.field[(end - start - 1) / slot_size] |= mask
|
output.field[(end - start - 1) / slot_size] |= mask
|
||||||
}
|
} else if start_offset == 0 {
|
||||||
else if start_offset == 0 {
|
|
||||||
mut mask := u32(0)
|
mut mask := u32(0)
|
||||||
if end_offset == slot_size - 1 {
|
if end_offset == slot_size - 1 {
|
||||||
mask = u32(-1)
|
mask = u32(-1)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
mask = u32(u32(1) << u32(end_offset + 1))
|
mask = u32(u32(1) << u32(end_offset + 1))
|
||||||
mask = mask - u32(1)
|
mask = mask - u32(1)
|
||||||
}
|
}
|
||||||
output.field[(end - start - 1) / slot_size] =
|
output.field[(end - start - 1) / slot_size] = (input.field[end_slot] & mask)
|
||||||
(input.field[end_slot] & mask)
|
} else {
|
||||||
}
|
|
||||||
else {
|
|
||||||
mut mask := u32(((1 << (end_offset - start_offset + 1)) - 1) << start_offset)
|
mut mask := u32(((1 << (end_offset - start_offset + 1)) - 1) << start_offset)
|
||||||
mask = input.field[end_slot] & mask
|
mask = input.field[end_slot] & mask
|
||||||
mask = u32(mask >> u32(start_offset))
|
mask = u32(mask >> u32(start_offset))
|
||||||
|
@ -373,15 +380,15 @@ pub fn (instance BitField) reverse() BitField {
|
||||||
size := instance.size
|
size := instance.size
|
||||||
bitnslots := zbitnslots(size)
|
bitnslots := zbitnslots(size)
|
||||||
mut output := new(size)
|
mut output := new(size)
|
||||||
for i:= 0; i < (bitnslots - 1); i++ {
|
for i := 0; i < (bitnslots - 1); i++ {
|
||||||
for j in 0..slot_size {
|
for j in 0 .. slot_size {
|
||||||
if u32(instance.field[i] >> u32(j)) & u32(1) == u32(1) {
|
if u32(instance.field[i] >> u32(j)) & u32(1) == u32(1) {
|
||||||
output.set_bit(size - i * slot_size - j - 1)
|
output.set_bit(size - i * slot_size - j - 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bits_in_last_input_slot := (size - 1) % slot_size + 1
|
bits_in_last_input_slot := (size - 1) % slot_size + 1
|
||||||
for j in 0..bits_in_last_input_slot {
|
for j in 0 .. bits_in_last_input_slot {
|
||||||
if u32(instance.field[bitnslots - 1] >> u32(j)) & u32(1) == u32(1) {
|
if u32(instance.field[bitnslots - 1] >> u32(j)) & u32(1) == u32(1) {
|
||||||
output.set_bit(bits_in_last_input_slot - j - 1)
|
output.set_bit(bits_in_last_input_slot - j - 1)
|
||||||
}
|
}
|
||||||
|
@ -394,7 +401,7 @@ pub fn (mut instance BitField) resize(new_size int) {
|
||||||
new_bitnslots := zbitnslots(new_size)
|
new_bitnslots := zbitnslots(new_size)
|
||||||
old_size := instance.size
|
old_size := instance.size
|
||||||
old_bitnslots := zbitnslots(old_size)
|
old_bitnslots := zbitnslots(old_size)
|
||||||
mut field := []u32{len:new_bitnslots}
|
mut field := []u32{len: new_bitnslots}
|
||||||
for i := 0; i < old_bitnslots && i < new_bitnslots; i++ {
|
for i := 0; i < old_bitnslots && i < new_bitnslots; i++ {
|
||||||
field[i] = instance.field[i]
|
field[i] = instance.field[i]
|
||||||
}
|
}
|
||||||
|
@ -408,14 +415,15 @@ pub fn (mut instance BitField) resize(new_size int) {
|
||||||
// rotate circular-shifts the bits by 'offset' positions (move
|
// rotate circular-shifts the bits by 'offset' positions (move
|
||||||
// 'offset' bit to 0, 'offset+1' bit to 1, and so on).
|
// 'offset' bit to 0, 'offset+1' bit to 1, and so on).
|
||||||
pub fn (instance BitField) rotate(offset int) BitField {
|
pub fn (instance BitField) rotate(offset int) BitField {
|
||||||
/**
|
/*
|
||||||
|
*
|
||||||
* This function "cuts" the bitfield into two and swaps them.
|
* This function "cuts" the bitfield into two and swaps them.
|
||||||
* If the offset is positive, the cutting point is counted from the
|
* If the offset is positive, the cutting point is counted from the
|
||||||
* beginning of the bit array, otherwise from the end.
|
* beginning of the bit array, otherwise from the end.
|
||||||
**/
|
*
|
||||||
|
*/
|
||||||
size := instance.size
|
size := instance.size
|
||||||
// removing extra rotations
|
// removing extra rotations
|
||||||
|
|
||||||
mut offset_internal := offset % size
|
mut offset_internal := offset % size
|
||||||
if offset_internal == 0 {
|
if offset_internal == 0 {
|
||||||
// nothing to shift
|
// nothing to shift
|
||||||
|
@ -424,7 +432,6 @@ pub fn (instance BitField) rotate(offset int) BitField {
|
||||||
if offset_internal < 0 {
|
if offset_internal < 0 {
|
||||||
offset_internal = offset_internal + size
|
offset_internal = offset_internal + size
|
||||||
}
|
}
|
||||||
|
|
||||||
first_chunk := instance.slice(0, offset_internal)
|
first_chunk := instance.slice(0, offset_internal)
|
||||||
second_chunk := instance.slice(offset_internal, size)
|
second_chunk := instance.slice(offset_internal, size)
|
||||||
output := join(second_chunk, first_chunk)
|
output := join(second_chunk, first_chunk)
|
||||||
|
@ -432,14 +439,14 @@ pub fn (instance BitField) rotate(offset int) BitField {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal functions
|
// Internal functions
|
||||||
|
|
||||||
fn (mut instance BitField) clear_tail() {
|
fn (mut instance BitField) clear_tail() {
|
||||||
tail := instance.size % slot_size
|
tail := instance.size % slot_size
|
||||||
if tail != 0 {
|
if tail != 0 {
|
||||||
// create a mask for the tail
|
// create a mask for the tail
|
||||||
mask := u32((1 << tail) - 1)
|
mask := u32((1 << tail) - 1)
|
||||||
// clear the extra bits
|
// clear the extra bits
|
||||||
instance.field[zbitnslots(instance.size) - 1] = instance.field[zbitnslots(instance.size) - 1] & mask
|
instance.field[zbitnslots(instance.size) - 1] = instance.field[zbitnslots(instance.size) -
|
||||||
|
1] & mask
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,8 +461,7 @@ fn bitslot(size int) int {
|
||||||
fn min(input1 int, input2 int) int {
|
fn min(input1 int, input2 int) int {
|
||||||
if input1 < input2 {
|
if input1 < input2 {
|
||||||
return input1
|
return input1
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return input2
|
return input2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import bitfield
|
import bitfield
|
||||||
|
|
||||||
import rand
|
import rand
|
||||||
|
|
||||||
fn test_bf_new_size() {
|
fn test_bf_new_size() {
|
||||||
|
@ -26,7 +25,7 @@ fn test_bf_and_not_or_xor() {
|
||||||
if rand.intn(2) == 1 {
|
if rand.intn(2) == 1 {
|
||||||
input1.set_bit(i)
|
input1.set_bit(i)
|
||||||
}
|
}
|
||||||
if rand.intn(2) == 1{
|
if rand.intn(2) == 1 {
|
||||||
input2.set_bit(i)
|
input2.set_bit(i)
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
|
@ -38,7 +37,9 @@ fn test_bf_and_not_or_xor() {
|
||||||
output2 := bitfield.bf_and(bf_or, bf_not)
|
output2 := bitfield.bf_and(bf_or, bf_not)
|
||||||
mut result := 1
|
mut result := 1
|
||||||
for i < len {
|
for i < len {
|
||||||
if output1.get_bit(i) != output2.get_bit(i) {result = 0}
|
if output1.get_bit(i) != output2.get_bit(i) {
|
||||||
|
result = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
assert result == 1
|
assert result == 1
|
||||||
}
|
}
|
||||||
|
@ -46,7 +47,7 @@ fn test_bf_and_not_or_xor() {
|
||||||
fn test_clone_cmp() {
|
fn test_clone_cmp() {
|
||||||
len := 80
|
len := 80
|
||||||
mut input := bitfield.new(len)
|
mut input := bitfield.new(len)
|
||||||
for i in 0..len {
|
for i in 0 .. len {
|
||||||
if rand.intn(2) == 1 {
|
if rand.intn(2) == 1 {
|
||||||
input.set_bit(i)
|
input.set_bit(i)
|
||||||
}
|
}
|
||||||
|
@ -59,7 +60,7 @@ fn test_clone_cmp() {
|
||||||
fn test_slice_join() {
|
fn test_slice_join() {
|
||||||
len := 80
|
len := 80
|
||||||
mut input := bitfield.new(len)
|
mut input := bitfield.new(len)
|
||||||
for i in 0..len {
|
for i in 0 .. len {
|
||||||
if rand.intn(2) == 1 {
|
if rand.intn(2) == 1 {
|
||||||
input.set_bit(i)
|
input.set_bit(i)
|
||||||
}
|
}
|
||||||
|
@ -82,7 +83,7 @@ fn test_pop_count() {
|
||||||
len := 80
|
len := 80
|
||||||
mut count0 := 0
|
mut count0 := 0
|
||||||
mut input := bitfield.new(len)
|
mut input := bitfield.new(len)
|
||||||
for i in 0..len {
|
for i in 0 .. len {
|
||||||
if rand.intn(2) == 1 {
|
if rand.intn(2) == 1 {
|
||||||
input.set_bit(i)
|
input.set_bit(i)
|
||||||
count0++
|
count0++
|
||||||
|
@ -97,7 +98,7 @@ fn test_hamming() {
|
||||||
mut count := 0
|
mut count := 0
|
||||||
mut input1 := bitfield.new(len)
|
mut input1 := bitfield.new(len)
|
||||||
mut input2 := bitfield.new(len)
|
mut input2 := bitfield.new(len)
|
||||||
for i in 0..len {
|
for i in 0 .. len {
|
||||||
match rand.intn(4) {
|
match rand.intn(4) {
|
||||||
0, 1 {
|
0, 1 {
|
||||||
input1.set_bit(i)
|
input1.set_bit(i)
|
||||||
|
@ -111,40 +112,33 @@ fn test_hamming() {
|
||||||
input1.set_bit(i)
|
input1.set_bit(i)
|
||||||
input2.set_bit(i)
|
input2.set_bit(i)
|
||||||
}
|
}
|
||||||
else {
|
else {}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert count == bitfield.hamming(input1, input2)
|
assert count == bitfield.hamming(input1, input2)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_bf_from_bytes() {
|
fn test_bf_from_bytes() {
|
||||||
input := [byte(0xF0), byte(0x0F), byte(0xF0), byte(0xFF)]
|
input := [byte(0x01), 0xF0, 0x0F, 0xF0, 0xFF]
|
||||||
output := bitfield.from_bytes(input)
|
output := bitfield.from_bytes(input).str()
|
||||||
mut result := 1
|
assert output == '00000001' + '11110000' + '00001111' + '11110000' + '11111111'
|
||||||
for i in 0..input.len * 8 {
|
newoutput := bitfield.from_str(output).str()
|
||||||
if (input[i / 8] >> (i % 8)) & 1 != output.get_bit(i) {
|
assert newoutput == output
|
||||||
result = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert result == 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_bf_from_str() {
|
fn test_bf_from_str() {
|
||||||
len := 80
|
len := 80
|
||||||
mut input := ''
|
mut input := ''
|
||||||
for _ in 0..len {
|
for _ in 0 .. len {
|
||||||
if rand.intn(2) == 1 {
|
if rand.intn(2) == 1 {
|
||||||
input = input + '1'
|
input = input + '1'
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
input = input + '0'
|
input = input + '0'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
output := bitfield.from_str(input)
|
output := bitfield.from_str(input)
|
||||||
mut result := 1
|
mut result := 1
|
||||||
for i in 0..len {
|
for i in 0 .. len {
|
||||||
if input[i] != output.get_bit(i) + 48 {
|
if input[i] != output.get_bit(i) + 48 {
|
||||||
result = 0
|
result = 0
|
||||||
}
|
}
|
||||||
|
@ -155,23 +149,22 @@ fn test_bf_from_str() {
|
||||||
fn test_bf_bf2str() {
|
fn test_bf_bf2str() {
|
||||||
len := 80
|
len := 80
|
||||||
mut input := bitfield.new(len)
|
mut input := bitfield.new(len)
|
||||||
for i in 0..len {
|
for i in 0 .. len {
|
||||||
if rand.intn(2) == 1 {
|
if rand.intn(2) == 1 {
|
||||||
input.set_bit(i)
|
input.set_bit(i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mut check := ''
|
mut check := ''
|
||||||
for i in 0..len {
|
for i in 0 .. len {
|
||||||
if input.get_bit(i) == 1 {
|
if input.get_bit(i) == 1 {
|
||||||
check = check + '1'
|
check = check + '1'
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
check = check + '0'
|
check = check + '0'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
output := input.str()
|
output := input.str()
|
||||||
mut result := 1
|
mut result := 1
|
||||||
for i in 0..len {
|
for i in 0 .. len {
|
||||||
if check[i] != output[i] {
|
if check[i] != output[i] {
|
||||||
result = 0
|
result = 0
|
||||||
}
|
}
|
||||||
|
@ -184,7 +177,7 @@ fn test_bf_set_all() {
|
||||||
mut input := bitfield.new(len)
|
mut input := bitfield.new(len)
|
||||||
input.set_all()
|
input.set_all()
|
||||||
mut result := 1
|
mut result := 1
|
||||||
for i in 0..len {
|
for i in 0 .. len {
|
||||||
if input.get_bit(i) != 1 {
|
if input.get_bit(i) != 1 {
|
||||||
result = 0
|
result = 0
|
||||||
}
|
}
|
||||||
|
@ -195,14 +188,14 @@ fn test_bf_set_all() {
|
||||||
fn test_bf_clear_all() {
|
fn test_bf_clear_all() {
|
||||||
len := 80
|
len := 80
|
||||||
mut input := bitfield.new(len)
|
mut input := bitfield.new(len)
|
||||||
for i in 0..len {
|
for i in 0 .. len {
|
||||||
if rand.intn(2) == 1 {
|
if rand.intn(2) == 1 {
|
||||||
input.set_bit(i)
|
input.set_bit(i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input.clear_all()
|
input.clear_all()
|
||||||
mut result := 1
|
mut result := 1
|
||||||
for i in 0..len {
|
for i in 0 .. len {
|
||||||
if input.get_bit(i) != 0 {
|
if input.get_bit(i) != 0 {
|
||||||
result = 0
|
result = 0
|
||||||
}
|
}
|
||||||
|
@ -213,7 +206,7 @@ fn test_bf_clear_all() {
|
||||||
fn test_bf_reverse() {
|
fn test_bf_reverse() {
|
||||||
len := 80
|
len := 80
|
||||||
mut input := bitfield.new(len)
|
mut input := bitfield.new(len)
|
||||||
for i in 0..len {
|
for i in 0 .. len {
|
||||||
if rand.intn(2) == 1 {
|
if rand.intn(2) == 1 {
|
||||||
input.set_bit(i)
|
input.set_bit(i)
|
||||||
}
|
}
|
||||||
|
@ -221,7 +214,7 @@ fn test_bf_reverse() {
|
||||||
check := input.clone()
|
check := input.clone()
|
||||||
output := input.reverse()
|
output := input.reverse()
|
||||||
mut result := 1
|
mut result := 1
|
||||||
for i in 0..len {
|
for i in 0 .. len {
|
||||||
if output.get_bit(i) != check.get_bit(len - i - 1) {
|
if output.get_bit(i) != check.get_bit(len - i - 1) {
|
||||||
result = 0
|
result = 0
|
||||||
}
|
}
|
||||||
|
@ -232,7 +225,7 @@ fn test_bf_reverse() {
|
||||||
fn test_bf_resize() {
|
fn test_bf_resize() {
|
||||||
len := 80
|
len := 80
|
||||||
mut input := bitfield.new(rand.intn(len) + 1)
|
mut input := bitfield.new(rand.intn(len) + 1)
|
||||||
for _ in 0..100 {
|
for _ in 0 .. 100 {
|
||||||
input.resize(rand.intn(len) + 1)
|
input.resize(rand.intn(len) + 1)
|
||||||
input.set_bit(input.get_size() - 1)
|
input.set_bit(input.get_size() - 1)
|
||||||
}
|
}
|
||||||
|
@ -240,48 +233,44 @@ fn test_bf_resize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_bf_pos() {
|
fn test_bf_pos() {
|
||||||
/**
|
/*
|
||||||
|
*
|
||||||
* set haystack size to 80
|
* set haystack size to 80
|
||||||
* test different sizes of needle, from 1 to 80
|
* test different sizes of needle, from 1 to 80
|
||||||
* test different positions of needle, from 0 to where it fits
|
* test different positions of needle, from 0 to where it fits
|
||||||
* all haystacks here contain exactly one instanse of needle,
|
* all haystacks here contain exactly one instanse of needle,
|
||||||
* so search should return non-negative-values
|
* so search should return non-negative-values
|
||||||
**/
|
*
|
||||||
|
*/
|
||||||
len := 80
|
len := 80
|
||||||
mut result := 1
|
mut result := 1
|
||||||
for i := 1; i < len; i++ { // needle size
|
for i := 1; i < len; i++ { // needle size
|
||||||
for j in 0..len - i { // needle position in the haystack
|
for j in 0 .. len - i { // needle position in the haystack
|
||||||
// create the needle
|
// create the needle
|
||||||
mut needle := bitfield.new(i)
|
mut needle := bitfield.new(i)
|
||||||
|
|
||||||
// fill the needle with random values
|
// fill the needle with random values
|
||||||
for k in 0..i {
|
for k in 0 .. i {
|
||||||
if rand.intn(2) == 1 {
|
if rand.intn(2) == 1 {
|
||||||
needle.set_bit(k)
|
needle.set_bit(k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure the needle contains at least one set bit, selected randomly
|
// make sure the needle contains at least one set bit, selected randomly
|
||||||
r := rand.intn(i)
|
r := rand.intn(i)
|
||||||
needle.set_bit(r)
|
needle.set_bit(r)
|
||||||
|
|
||||||
// create the haystack, make sure it contains the needle
|
// create the haystack, make sure it contains the needle
|
||||||
mut haystack := needle.clone()
|
mut haystack := needle.clone()
|
||||||
|
|
||||||
// if there is space between the start of the haystack and the sought needle, fill it with zeroes
|
// if there is space between the start of the haystack and the sought needle, fill it with zeroes
|
||||||
if j > 0 {
|
if j > 0 {
|
||||||
start := bitfield.new(j)
|
start := bitfield.new(j)
|
||||||
tmp := bitfield.join(start, haystack)
|
tmp := bitfield.join(start, haystack)
|
||||||
haystack = tmp
|
haystack = tmp
|
||||||
}
|
}
|
||||||
|
|
||||||
// if there is space between the sought needle and the end of haystack, fill it with zeroes
|
// if there is space between the sought needle and the end of haystack, fill it with zeroes
|
||||||
if j + i < len {
|
if j + i < len {
|
||||||
end := bitfield.new(len - j - i)
|
end := bitfield.new(len - j - i)
|
||||||
tmp2 := bitfield.join(haystack, end)
|
tmp2 := bitfield.join(haystack, end)
|
||||||
haystack = tmp2
|
haystack = tmp2
|
||||||
}
|
}
|
||||||
|
|
||||||
// now let's test
|
// now let's test
|
||||||
// the result should be equal to j
|
// the result should be equal to j
|
||||||
if haystack.pos(needle) != j {
|
if haystack.pos(needle) != j {
|
||||||
|
@ -308,10 +297,10 @@ fn test_bf_rotate() {
|
||||||
assert result == 1
|
assert result == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_bf_printing(){
|
fn test_bf_printing() {
|
||||||
len := 80
|
len := 80
|
||||||
mut input := bitfield.new(len)
|
mut input := bitfield.new(len)
|
||||||
for i in 0..len {
|
for i in 0 .. len {
|
||||||
if rand.intn(2) == 0 {
|
if rand.intn(2) == 0 {
|
||||||
input.set_bit(i)
|
input.set_bit(i)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue