From 236b06a88f709ca6c70ce0c7adfb57f9f0b2a60d Mon Sep 17 00:00:00 2001 From: Thibaut Horel Date: Wed, 11 May 2016 22:03:53 -0400 Subject: Add final code used during experiments --- graph.go | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.py | 36 +++++++++++ proof.py | 33 ++++++++++ proof2.py | 36 +++++++++++ test.sh | 28 ++++++++ 5 files changed, 349 insertions(+) create mode 100644 graph.go create mode 100644 main.py create mode 100644 proof.py create mode 100644 proof2.py create mode 100644 test.sh diff --git a/graph.go b/graph.go new file mode 100644 index 0000000..92f44a1 --- /dev/null +++ b/graph.go @@ -0,0 +1,216 @@ +package posgraph + +import ( + "encoding/binary" + "fmt" + "os" + + "github.com/boltdb/bolt" + // "reflect" + // "unsafe" +) + +const ( + TYPE1 = iota + EGS = iota + TYPE2 = iota +) + +// creating another DB type so it's easier to change underlying DB later +type DB struct { + db *bolt.DB +} + +type Graph_ struct { + fn string + db DB + + index int64 + log2 int64 + pow2 int64 + size int64 + + t int //type of the graph +} + +type Graph interface { + NewNodeP(id int64, parents []int64) + GetParents(id int64) []int64 + NewNodeA(id int64, adjlist []int64) + GetAdjacency(id int64) []int64 + GetSize() int64 + GetDB() DB + ChangeDB(DB) + Close() +} + +// Generate a new PoS graph of index +// Currently only supports the weaker PoS graph +// Note that this graph will have O(2^index) nodes +func NewGraph(t int, dir string, index int64) Graph { + var fn string + if t == TYPE1 { + fn = fmt.Sprintf("%s/T1-%d", dir, index) + } else if t == EGS { + fn = fmt.Sprintf("%s/EGS-%d", dir, index) + } else if t == TYPE2 { + fn = fmt.Sprintf("%s/T2-%d", dir, index) + } + + _, err := os.Stat(fn) + fileExists := err == nil + + var db *bolt.DB + if fileExists { //open it as read only + db, err = bolt.Open(fn, 0600, &bolt.Options{ReadOnly: true}) + } else { + db, err = bolt.Open(fn, 0600, nil) + } + if err != nil { + panic("Failed to open database") + } + + db.Update(func(tx *bolt.Tx) error { + _, err := tx.CreateBucket([]byte("Parents")) + if err != nil { + return fmt.Errorf("create bucket: %s", err) + } + return nil + }) + db.Update(func(tx *bolt.Tx) error { + _, err := tx.CreateBucket([]byte("Adjlist")) + if err != nil { + return fmt.Errorf("create bucket: %s", err) + } + return nil + }) + + var g Graph + if t == TYPE1 { + g = NewType1Graph(t, !fileExists, index, DB{db}) + } else if t == EGS { + //'index' for EGS is overloaded to be size + g = NewEGSGraph(t, !fileExists, index, DB{db}) + } else if t == TYPE2 { + g = NewType2Graph(t, !fileExists, index, DB{db}) + } + + // a hack for testing; graph should be opened for read only after gen + g.Close() + db, err = bolt.Open(fn, 0600, &bolt.Options{ReadOnly: true}) + if err != nil { + panic("Failed to open database") + } + g.ChangeDB(DB{db}) + + return g +} + +func (g *Graph_) NewNodeP(node int64, parents []int64) { + // header := *(*reflect.SliceHeader)(unsafe.Pointer(&parents)) + // header.Len *= 8 + // header.Cap *= 8 + // data := *(*[]byte)(unsafe.Pointer(&header)) + // log.Println("New node:", node, parents) + + key := make([]byte, 8) + binary.PutVarint(key, node) + data := make([]byte, len(parents)*8) + for i := range parents { + binary.PutVarint(data[i*8:(i+1)*8], parents[i]) + } + + g.db.db.Update(func(tx *bolt.Tx) error { + b := tx.Bucket([]byte("Parents")) + err := b.Put(key, data) + return err + }) +} + +func (g *Graph_) NewNodeA(id int64, adjlist []int64) { + // header := *(*reflect.SliceHeader)(unsafe.Pointer(&parents)) + // header.Len *= 8 + // header.Cap *= 8 + // data := *(*[]byte)(unsafe.Pointer(&header)) + // log.Println("New node:", id, parents) + + key := make([]byte, 8) + binary.PutVarint(key, id) + data := make([]byte, len(adjlist)*8) + for i := range adjlist { + binary.PutVarint(data[i*8:(i+1)*8], adjlist[i]) + } + + g.db.db.Update(func(tx *bolt.Tx) error { + b := tx.Bucket([]byte("Adjlist")) + err := b.Put(key, data) + return err + }) +} + +func (g *Graph_) GetParents(id int64) []int64 { + // first pow2 nodes are srcs in TYPE1 + if g.t == TYPE1 && id < int64(1<