From e12d17e4827a522ca475835de13d5f83ec545453 Mon Sep 17 00:00:00 2001 From: Manish R Jain <manishrjain@gmail.com> Date: Tue, 13 Oct 2015 19:28:10 +1100 Subject: [PATCH] Transform to Flatbuffer + write to and read from leveldb --- plist/.gitignore | 1 + plist/main.go | 101 +++++++++++++++++++++++++++++++++++++++++++++++ types.fbs | 8 ++++ types/Uid.go | 43 ++++++++++++++++++++ x/x.go | 60 ++++++++++++++++++++++++++++ 5 files changed, 213 insertions(+) create mode 100644 plist/.gitignore create mode 100644 plist/main.go create mode 100644 types.fbs create mode 100644 types/Uid.go create mode 100644 x/x.go diff --git a/plist/.gitignore b/plist/.gitignore new file mode 100644 index 00000000..2634eed2 --- /dev/null +++ b/plist/.gitignore @@ -0,0 +1 @@ +/plist diff --git a/plist/main.go b/plist/main.go new file mode 100644 index 00000000..f118cfe6 --- /dev/null +++ b/plist/main.go @@ -0,0 +1,101 @@ +package main + +import ( + "fmt" + "io/ioutil" + "time" + + "github.com/Sirupsen/logrus" + "github.com/google/flatbuffers/go" + "github.com/manishrjain/dgraph/types" + "github.com/syndtr/goleveldb/leveldb" + "github.com/syndtr/goleveldb/leveldb/filter" + "github.com/syndtr/goleveldb/leveldb/opt" +) + +var log = logrus.WithField("package", "plist") + +type Triple struct { + Entity string + Attribute string + Value interface{} + ValueId string + Source string + Timestamp time.Time +} + +/* +func addTriple(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + x.SetStatus(w, x.E_INVALID_METHOD, "Should be POST") + return + } + + var t Triple + if ok := x.ParseRequest(w, r, &t); !ok { + return + } + + log.Debug(t) +} +*/ + +func main() { + path, err := ioutil.TempDir("", "dgraphldb_") + if err != nil { + log.Fatal(err) + return + } + opt := &opt.Options{ + Filter: filter.NewBloomFilter(10), + } + db, err := leveldb.OpenFile(path, opt) + if err != nil { + log.Fatal(err) + return + } + fmt.Println("Using path", path) + + batch := new(leveldb.Batch) + b := flatbuffers.NewBuilder(0) + oi := b.CreateString("mrjn is a smart kid") + on := b.CreateString("His name is jain") + types.UidStart(b) + types.UidAddId(b, oi) + types.UidAddName(b, on) + oe := types.UidEnd(b) + b.Finish(oe) + fmt.Println("Value byte size:", len(b.Bytes)) + + key := "Some long id" + batch.Put([]byte(key), b.Bytes[b.Head():]) + if err := db.Write(batch, nil); err != nil { + log.Fatal(err) + return + } + fmt.Println("Wrote key value out to leveldb. Reading back") + if err := db.Close(); err != nil { + log.Fatal(err) + return + } + + db, err = leveldb.OpenFile(path, opt) + if err != nil { + log.Fatal(err) + return + } + + val, err := db.Get([]byte(key), nil) + if err != nil { + log.Fatal(err) + return + } + fmt.Println("Value byte size from Leveldb:", len(val)) + + uid := types.GetRootAsUid(val, 0) + fmt.Println("buffer.uid id =", string(uid.Id())) + fmt.Println("buffer.uid name =", string(uid.Name())) + // http.HandleFunc("/add", addTriple) + // http.ListenAndServe(":8080", nil) + +} diff --git a/types.fbs b/types.fbs new file mode 100644 index 00000000..d25c25bb --- /dev/null +++ b/types.fbs @@ -0,0 +1,8 @@ +namespace types; + +table Uid { + id:string; + name:string; +} + +root_type Uid; diff --git a/types/Uid.go b/types/Uid.go new file mode 100644 index 00000000..4695ecc3 --- /dev/null +++ b/types/Uid.go @@ -0,0 +1,43 @@ +// automatically generated, do not modify + +package types + +import ( + flatbuffers "github.com/google/flatbuffers/go" +) +type Uid struct { + _tab flatbuffers.Table +} + +func GetRootAsUid(buf []byte, offset flatbuffers.UOffsetT) *Uid { + n := flatbuffers.GetUOffsetT(buf[offset:]) + x := &Uid{} + x.Init(buf, n + offset) + return x +} + +func (rcv *Uid) Init(buf []byte, i flatbuffers.UOffsetT) { + rcv._tab.Bytes = buf + rcv._tab.Pos = i +} + +func (rcv *Uid) Id() []byte { + o := flatbuffers.UOffsetT(rcv._tab.Offset(4)) + if o != 0 { + return rcv._tab.ByteVector(o + rcv._tab.Pos) + } + return nil +} + +func (rcv *Uid) Name() []byte { + o := flatbuffers.UOffsetT(rcv._tab.Offset(6)) + if o != 0 { + return rcv._tab.ByteVector(o + rcv._tab.Pos) + } + return nil +} + +func UidStart(builder *flatbuffers.Builder) { builder.StartObject(2) } +func UidAddId(builder *flatbuffers.Builder, id flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(id), 0) } +func UidAddName(builder *flatbuffers.Builder, name flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(1, flatbuffers.UOffsetT(name), 0) } +func UidEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT { return builder.EndObject() } diff --git a/x/x.go b/x/x.go new file mode 100644 index 00000000..3ea34bb2 --- /dev/null +++ b/x/x.go @@ -0,0 +1,60 @@ +package x + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/Sirupsen/logrus" +) + +const ( + E_OK = "E_OK" + E_UNAUTHORIZED = "E_UNAUTHORIZED" + E_INVALID_METHOD = "E_INVALID_METHOD" + E_INVALID_REQUEST = "E_INVALID_REQUEST" + E_MISSING_REQUIRED = "E_MISSING_REQUIRED" + E_ERROR = "E_ERROR" + E_NODATA = "E_NODATA" + E_UPTODATE = "E_UPTODATE" + E_NOPERMISSION = "E_NOPERMISSION" + + DUMMY_UUID = "00000000-0000-0000-0000-000000000000" +) + +type Status struct { + Code string `json:"code"` + Message string `json:"message"` +} + +func Err(entry *logrus.Entry, err error) *logrus.Entry { + return entry.WithField("error", err) +} + +func SetStatus(w http.ResponseWriter, code, msg string) { + r := &Status{Code: code, Message: msg} + if js, err := json.Marshal(r); err == nil { + fmt.Fprint(w, string(js)) + } else { + panic(fmt.Sprintf("Unable to marshal: %+v", r)) + } +} + +func Reply(w http.ResponseWriter, rep interface{}) { + if js, err := json.Marshal(rep); err == nil { + w.Header().Set("Content-Type", "application/json") + fmt.Fprint(w, string(js)) + } else { + SetStatus(w, E_ERROR, "Internal server error") + } +} + +func ParseRequest(w http.ResponseWriter, r *http.Request, data interface{}) bool { + defer r.Body.Close() + decoder := json.NewDecoder(r.Body) + if err := decoder.Decode(&data); err != nil { + SetStatus(w, E_ERROR, fmt.Sprintf("While parsing request: %v", err)) + return false + } + return true +} -- GitLab