From f17930eb4661721cd0e1b92765448c589441907b Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 30 Dec 2013 01:09:57 +0100 Subject: [PATCH] Split up db and trie and added interface --- database.go | 58 ++++++++------------------------------------- database_test.go | 38 +----------------------------- server.go | 4 ++-- trie.go | 50 +++++++++++++++++++++++++++++++++++++++ trie.test.go | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 124 insertions(+), 87 deletions(-) create mode 100644 trie.go create mode 100644 trie.test.go diff --git a/database.go b/database.go index f74c1dc7f..c056e70af 100644 --- a/database.go +++ b/database.go @@ -7,12 +7,12 @@ import ( "fmt" ) -type Database struct { +type LDBDatabase struct { db *leveldb.DB trie *Trie } -func NewDatabase() (*Database, error) { +func NewLDBDatabase() (*LDBDatabase, error) { // This will eventually have to be something like a resource folder. // it works on my system for now. Probably won't work on Windows usr, _ := user.Current() @@ -24,7 +24,7 @@ func NewDatabase() (*Database, error) { return nil, err } - database := &Database{db: db} + database := &LDBDatabase{db: db} // Bootstrap database. Sets a few defaults; such as the last block database.Bootstrap() @@ -32,63 +32,25 @@ func NewDatabase() (*Database, error) { return database, nil } -func (db *Database) Bootstrap() error { +func (db *LDBDatabase) Bootstrap() error { db.trie = NewTrie(db) return nil } -func (db *Database) Put(key []byte, value []byte) { +func (db *LDBDatabase) Put(key []byte, value []byte) { err := db.db.Put(key, value, nil) if err != nil { fmt.Println("Error put", err) } } -func (db *Database) Close() { +func (db *LDBDatabase) Get(key []byte) ([]byte, error) { + return nil, nil +} + +func (db *LDBDatabase) Close() { // Close the leveldb database db.db.Close() } -type Trie struct { - root string - db *Database -} - -func NewTrie(db *Database) *Trie { - return &Trie{db: db, root: ""} -} - -func (t *Trie) Update(key string, value string) { - k := CompactHexDecode(key) - - t.root = t.UpdateState(t.root, k, value) -} - -func (t *Trie) Get(key []byte) ([]byte, error) { - return nil, nil -} - -// Inserts a new sate or delete a state based on the value -func (t *Trie) UpdateState(node, key, value string) string { - if value != "" { - return t.InsertState(node, key, value) - } else { - // delete it - } - - return "" -} - -func (t *Trie) InsertState(node, key, value string) string { - return "" -} - -func (t *Trie) Put(node []byte) []byte { - enc := Encode(node) - sha := Sha256Bin(enc) - - t.db.Put([]byte(sha), enc) - - return sha -} diff --git a/database_test.go b/database_test.go index c1a6c7d16..1a46eb95e 100644 --- a/database_test.go +++ b/database_test.go @@ -1,43 +1,7 @@ package main import ( - "testing" + _"testing" _"fmt" ) -func TestTriePut(t *testing.T) { - db, err := NewDatabase() - defer db.Close() - - if err != nil { - t.Error("Error starting db") - } - - key := db.trie.Put([]byte("testing node")) - - data, err := db.db.Get(key, nil) - if err != nil { - t.Error("Nothing at node") - } - - s, _ := Decode(data, 0) - if str, ok := s.([]byte); ok { - if string(str) != "testing node" { - t.Error("Wrong value node", str) - } - } else { - t.Error("Invalid return type") - } -} - -func TestTrieUpdate(t *testing.T) { - db, err := NewDatabase() - defer db.Close() - - if err != nil { - t.Error("Error starting db") - } - - db.trie.Update("test", "test") -} - diff --git a/server.go b/server.go index 0c7488787..c8fb492d5 100644 --- a/server.go +++ b/server.go @@ -9,13 +9,13 @@ type Server struct { // Channel for shutting down the server shutdownChan chan bool // DB interface - db *Database + db *LDBDatabase // Peers (NYI) peers *list.List } func NewServer() (*Server, error) { - db, err := NewDatabase() + db, err := NewLDBDatabase() if err != nil { return nil, err } diff --git a/trie.go b/trie.go new file mode 100644 index 000000000..d9d5dba5a --- /dev/null +++ b/trie.go @@ -0,0 +1,50 @@ +package main + +// Database interface +type Database interface { + Put(key []byte, value []byte) + Get(key []byte) ([]byte, error) +} + +type Trie struct { + root string + db Database +} + +func NewTrie(db Database) *Trie { + return &Trie{db: db, root: ""} +} + +func (t *Trie) Update(key string, value string) { + k := CompactHexDecode(key) + + t.root = t.UpdateState(t.root, k, value) +} + +func (t *Trie) Get(key []byte) ([]byte, error) { + return nil, nil +} + +// Inserts a new sate or delete a state based on the value +func (t *Trie) UpdateState(node string, key []int, value string) string { + if value != "" { + return t.InsertState(node, ""/*key*/, value) + } else { + // delete it + } + + return "" +} + +func (t *Trie) InsertState(node, key, value string) string { + return "" +} + +func (t *Trie) Put(node []byte) []byte { + enc := Encode(node) + sha := Sha256Bin(enc) + + t.db.Put([]byte(sha), enc) + + return sha +} diff --git a/trie.test.go b/trie.test.go new file mode 100644 index 000000000..0a6054cf0 --- /dev/null +++ b/trie.test.go @@ -0,0 +1,61 @@ +package main + +import ( + "testing" +) + +type MemDatabase struct { + db map[string][]byte + trie *Trie +} + +func NewMemDatabase() (*MemDatabase, error) { + db := &MemDatabase{db: make(map[string][]byte)} + + db.trie = NewTrie(db) + + return db, nil +} + +func (db *MemDatabase) Put(key []byte, value []byte) { + db.db[string(key)] = value +} + +func (db *MemDatabase) Get(key []byte) ([]byte, error) { + return db.db[string(key)], nil +} + +func TestTriePut(t *testing.T) { + db, err := NewMemDatabase() + + if err != nil { + t.Error("Error starting db") + } + + key := db.trie.Put([]byte("testing node")) + + data, err := db.Get(key) + if err != nil { + t.Error("Nothing at node") + } + + s, _ := Decode(data, 0) + if str, ok := s.([]byte); ok { + if string(str) != "testing node" { + t.Error("Wrong value node", str) + } + } else { + t.Error("Invalid return type") + } +} + +func TestTrieUpdate(t *testing.T) { + db, err := NewMemDatabase() + + if err != nil { + t.Error("Error starting db") + } + + db.trie.Update("test", "test") +} +