Skip to content

Commit

Permalink
bitset : remove all replication code
Browse files Browse the repository at this point in the history
Moving all replication related code to a different package built on top of
bitset.
  • Loading branch information
nikhilgarg28 committed Aug 1, 2015
1 parent 57c20c2 commit e9eba76
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 100 deletions.
97 changes: 4 additions & 93 deletions bitset.go
Original file line number Diff line number Diff line change
@@ -1,109 +1,23 @@
package bitset

import (
"bufio"
"encoding/binary"
"fmt"
"os"
"time"
)

const word = uint64(64)
const logword = uint(6)
const bufsize = 1 << 16

// each channel write is 9 bytes, so if we were to write full disk sector
// of 64K bytes at once, we'd flush ~7112 writes
const channelsize = 7200

const (
new = iota
set
clear
flip
)

type command struct {
code uint8
index uint64
}

type BitSet struct {
length uint64
bits []uint64
writes chan command
binlogfile string
length uint64
bits []uint64
}

func getSize(length uint64) uint64 {
return uint64((length + word - 1) / word)
}

func flush(filename string, writes chan command) {
f, err := os.Create(filename)
if err != nil {
panic(err)
}

defer func() {
if err := f.Close(); err != nil {
panic(err)
}
}()

// make a buffered writer
w := bufio.NewWriterSize(f, bufsize)

ticker := time.NewTimer(time.Second)

buf := make([]byte, bufsize)
long := make([]byte, 8)

put := func(w *command) {
binary.BigEndian.PutUint64(long, w.index)
buf = append(buf, w.code)
buf = append(buf, long...)
}

for t := range ticker.C {
_ = t
b := 0

drain:
for b+9 < bufsize {
select {
case write := <-writes:
put(&write)
b += 9
default:
break drain
}
}

if b > 0 {
// write a chunk
if _, err := w.Write(buf[:b]); err != nil {
panic(err)
}

if err = w.Flush(); err != nil {
panic(err)
}
}
}
}

func New(length uint64, binlogfile string) *BitSet {
func New(length uint64) *BitSet {
size := getSize(length)
ret := &BitSet{
return &BitSet{
length,
make([]uint64, size),
make(chan command, channelsize),
binlogfile,
}
ret.writes <- command{new, length}
go flush(binlogfile, ret.writes)
return ret
}

func getIndex(pos uint64) (q uint64, r uint) {
Expand All @@ -126,22 +40,19 @@ func (b *BitSet) Set(pos uint64) bool {
current := b.Get(pos)
q, r := getIndex(pos)
b.bits[q] |= (1 << r)
b.writes <- command{set, pos}
return current
}

func (b *BitSet) Clear(pos uint64) bool {
current := b.Get(pos)
q, r := getIndex(pos)
b.bits[q] &= ^(1 << r)
b.writes <- command{clear, pos}
return current
}

func (b *BitSet) Flip(pos uint64) bool {
current := b.Get(pos)
q, r := getIndex(pos)
b.bits[q] ^= (1 << r)
b.writes <- command{flip, pos}
return current
}
13 changes: 6 additions & 7 deletions bitset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ package bitset

import (
"testing"
"time"
)

func TestInit(t *testing.T) {
bs := New(1000, "/tmp/bitset.log")
bs := New(1000)
// initially all bits should be zero
for i := uint64(0); i < 1000; i++ {
if bs.Get(i) {
Expand All @@ -16,7 +15,7 @@ func TestInit(t *testing.T) {
}

func TestGetSet(t *testing.T) {
bs := New(1000, "/tmp/bitset.log")
bs := New(1000)
if bs.Set(0) == true {
t.Error("Set on bit %d returned true when it should return false", 0)
}
Expand All @@ -32,7 +31,7 @@ func TestGetSet(t *testing.T) {

func TestLargeSetGet(t *testing.T) {
size := uint64(1) << 35
bs := New(size, "/tmp/bitset.log")
bs := New(size)

positions := []uint64{0, 1, 10, 1000, 1 << 32, size - 1}
for _, position := range positions {
Expand All @@ -52,15 +51,15 @@ func TestLength(t *testing.T) {

sizes := []uint64{0, 1, 10, 1000, 1 << 32, 1 << 33}
for _, size := range sizes {
bs := New(size, "/tmp/bitset.log")
bs := New(size)
if bs.Length() != size {
t.Errorf("Length should be %d", size)
}
}
}

func TestClear(t *testing.T) {
bs := New(1000, "/tmp/bitset.log")
bs := New(1000)
pos := uint64(1)
bs.Set(pos)

Expand All @@ -78,7 +77,7 @@ func TestClear(t *testing.T) {
}

func TestFlip(t *testing.T) {
bs := New(1000, "/tmp/bitset.log")
bs := New(1000)
pos := uint64(1)

if bs.Get(pos) {
Expand Down

0 comments on commit e9eba76

Please sign in to comment.