From 7eadb02f45042e48774e0e4d7fd14dcfade0f103 Mon Sep 17 00:00:00 2001 From: Emir Pasic Date: Mon, 6 Mar 2017 04:18:23 +0100 Subject: [PATCH] - all trees (de)serialization --- trees/avltree/avltree_test.go | 31 ++++++++++++++++++++ trees/avltree/serialization.go | 39 +++++++++++++++++++++++++ trees/binaryheap/binaryheap_test.go | 32 ++++++++++++++++++++ trees/binaryheap/serialization.go | 22 ++++++++++++++ trees/btree/btree_test.go | 31 ++++++++++++++++++++ trees/btree/serialization.go | 39 +++++++++++++++++++++++++ trees/redblacktree/redblacktree_test.go | 31 ++++++++++++++++++++ trees/redblacktree/serialization.go | 39 +++++++++++++++++++++++++ 8 files changed, 264 insertions(+) create mode 100644 trees/avltree/serialization.go create mode 100644 trees/binaryheap/serialization.go create mode 100644 trees/btree/serialization.go create mode 100644 trees/redblacktree/serialization.go diff --git a/trees/avltree/avltree_test.go b/trees/avltree/avltree_test.go index 2e791d2..99c2adf 100644 --- a/trees/avltree/avltree_test.go +++ b/trees/avltree/avltree_test.go @@ -556,6 +556,37 @@ func TestAVLTreeIteratorLast(t *testing.T) { } } +func TestAVLTreeSerialization(t *testing.T) { + tree := NewWithStringComparator() + tree.Put("c", "3") + tree.Put("b", "2") + tree.Put("a", "1") + + var err error + assert := func() { + if actualValue, expectedValue := tree.Size(), 3; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) + } + if actualValue := tree.Keys(); actualValue[0].(string) != "a" || actualValue[1].(string) != "b" || actualValue[2].(string) != "c" { + t.Errorf("Got %v expected %v", actualValue, "[a,b,c]") + } + if actualValue := tree.Values(); actualValue[0].(string) != "1" || actualValue[1].(string) != "2" || actualValue[2].(string) != "3" { + t.Errorf("Got %v expected %v", actualValue, "[1,2,3]") + } + if err != nil { + t.Errorf("Got error %v", err) + } + } + + assert() + + json, err := tree.ToJSON() + assert() + + err = tree.FromJSON(json) + assert() +} + func benchmarkGet(b *testing.B, tree *Tree, size int) { for i := 0; i < b.N; i++ { for n := 0; n < size; n++ { diff --git a/trees/avltree/serialization.go b/trees/avltree/serialization.go new file mode 100644 index 0000000..0630d87 --- /dev/null +++ b/trees/avltree/serialization.go @@ -0,0 +1,39 @@ +// Copyright (c) 2015, Emir Pasic. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package avltree + +import ( + "encoding/json" + "github.com/emirpasic/gods/containers" + "github.com/emirpasic/gods/utils" +) + +func assertSerializationImplementation() { + var _ containers.JSONSerializer = (*Tree)(nil) + var _ containers.JSONDeserializer = (*Tree)(nil) +} + +// ToJSON outputs the JSON representation of list's elements. +func (tree *Tree) ToJSON() ([]byte, error) { + elements := make(map[string]interface{}) + it := tree.Iterator() + for it.Next() { + elements[utils.ToString(it.Key())] = it.Value() + } + return json.Marshal(&elements) +} + +// FromJSON populates list's elements from the input JSON representation. +func (tree *Tree) FromJSON(data []byte) error { + elements := make(map[string]interface{}) + err := json.Unmarshal(data, &elements) + if err == nil { + tree.Clear() + for key, value := range elements { + tree.Put(key, value) + } + } + return err +} diff --git a/trees/binaryheap/binaryheap_test.go b/trees/binaryheap/binaryheap_test.go index a20d647..cf97813 100644 --- a/trees/binaryheap/binaryheap_test.go +++ b/trees/binaryheap/binaryheap_test.go @@ -259,6 +259,38 @@ func TestBinaryHeapIteratorLast(t *testing.T) { } } +func TestBinaryHeapSerialization(t *testing.T) { + heap := NewWithStringComparator() + + heap.Push("c") // ["c"] + heap.Push("b") // ["b","c"] + heap.Push("a") // ["a","c","b"]("b" swapped with "a", hence last) + + var err error + assert := func() { + if actualValue := heap.Values(); actualValue[0].(string) != "a" || actualValue[1].(string) != "c" || actualValue[2].(string) != "b" { + t.Errorf("Got %v expected %v", actualValue, "[1,3,2]") + } + if actualValue := heap.Size(); actualValue != 3 { + t.Errorf("Got %v expected %v", actualValue, 3) + } + if actualValue, ok := heap.Peek(); actualValue != "a" || !ok { + t.Errorf("Got %v expected %v", actualValue, "a") + } + if err != nil { + t.Errorf("Got error %v", err) + } + } + + assert() + + json, err := heap.ToJSON() + assert() + + err = heap.FromJSON(json) + assert() +} + func benchmarkPush(b *testing.B, heap *Heap, size int) { for i := 0; i < b.N; i++ { for n := 0; n < size; n++ { diff --git a/trees/binaryheap/serialization.go b/trees/binaryheap/serialization.go new file mode 100644 index 0000000..299319b --- /dev/null +++ b/trees/binaryheap/serialization.go @@ -0,0 +1,22 @@ +// Copyright (c) 2015, Emir Pasic. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package binaryheap + +import "github.com/emirpasic/gods/containers" + +func assertSerializationImplementation() { + var _ containers.JSONSerializer = (*Heap)(nil) + var _ containers.JSONDeserializer = (*Heap)(nil) +} + +// ToJSON outputs the JSON representation of list's elements. +func (heap *Heap) ToJSON() ([]byte, error) { + return heap.list.ToJSON() +} + +// FromJSON populates list's elements from the input JSON representation. +func (heap *Heap) FromJSON(data []byte) error { + return heap.list.FromJSON(data) +} diff --git a/trees/btree/btree_test.go b/trees/btree/btree_test.go index 4705bc1..4d69665 100644 --- a/trees/btree/btree_test.go +++ b/trees/btree/btree_test.go @@ -1074,6 +1074,37 @@ func assertValidTreeNode(t *testing.T, node *Node, expectedEntries int, expected } } +func TestBTreeSerialization(t *testing.T) { + tree := NewWithStringComparator(3) + tree.Put("c", "3") + tree.Put("b", "2") + tree.Put("a", "1") + + var err error + assert := func() { + if actualValue, expectedValue := tree.Size(), 3; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) + } + if actualValue := tree.Keys(); actualValue[0].(string) != "a" || actualValue[1].(string) != "b" || actualValue[2].(string) != "c" { + t.Errorf("Got %v expected %v", actualValue, "[a,b,c]") + } + if actualValue := tree.Values(); actualValue[0].(string) != "1" || actualValue[1].(string) != "2" || actualValue[2].(string) != "3" { + t.Errorf("Got %v expected %v", actualValue, "[1,2,3]") + } + if err != nil { + t.Errorf("Got error %v", err) + } + } + + assert() + + json, err := tree.ToJSON() + assert() + + err = tree.FromJSON(json) + assert() +} + func benchmarkGet(b *testing.B, tree *Tree, size int) { for i := 0; i < b.N; i++ { for n := 0; n < size; n++ { diff --git a/trees/btree/serialization.go b/trees/btree/serialization.go new file mode 100644 index 0000000..95c817e --- /dev/null +++ b/trees/btree/serialization.go @@ -0,0 +1,39 @@ +// Copyright (c) 2015, Emir Pasic. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package btree + +import ( + "encoding/json" + "github.com/emirpasic/gods/containers" + "github.com/emirpasic/gods/utils" +) + +func assertSerializationImplementation() { + var _ containers.JSONSerializer = (*Tree)(nil) + var _ containers.JSONDeserializer = (*Tree)(nil) +} + +// ToJSON outputs the JSON representation of list's elements. +func (tree *Tree) ToJSON() ([]byte, error) { + elements := make(map[string]interface{}) + it := tree.Iterator() + for it.Next() { + elements[utils.ToString(it.Key())] = it.Value() + } + return json.Marshal(&elements) +} + +// FromJSON populates list's elements from the input JSON representation. +func (tree *Tree) FromJSON(data []byte) error { + elements := make(map[string]interface{}) + err := json.Unmarshal(data, &elements) + if err == nil { + tree.Clear() + for key, value := range elements { + tree.Put(key, value) + } + } + return err +} diff --git a/trees/redblacktree/redblacktree_test.go b/trees/redblacktree/redblacktree_test.go index 714defc..74c3d8a 100644 --- a/trees/redblacktree/redblacktree_test.go +++ b/trees/redblacktree/redblacktree_test.go @@ -557,6 +557,37 @@ func TestRedBlackTreeIteratorLast(t *testing.T) { } } +func TestRedBlackTreeSerialization(t *testing.T) { + tree := NewWithStringComparator() + tree.Put("c", "3") + tree.Put("b", "2") + tree.Put("a", "1") + + var err error + assert := func() { + if actualValue, expectedValue := tree.Size(), 3; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) + } + if actualValue := tree.Keys(); actualValue[0].(string) != "a" || actualValue[1].(string) != "b" || actualValue[2].(string) != "c" { + t.Errorf("Got %v expected %v", actualValue, "[a,b,c]") + } + if actualValue := tree.Values(); actualValue[0].(string) != "1" || actualValue[1].(string) != "2" || actualValue[2].(string) != "3" { + t.Errorf("Got %v expected %v", actualValue, "[1,2,3]") + } + if err != nil { + t.Errorf("Got error %v", err) + } + } + + assert() + + json, err := tree.ToJSON() + assert() + + err = tree.FromJSON(json) + assert() +} + func benchmarkGet(b *testing.B, tree *Tree, size int) { for i := 0; i < b.N; i++ { for n := 0; n < size; n++ { diff --git a/trees/redblacktree/serialization.go b/trees/redblacktree/serialization.go new file mode 100644 index 0000000..7969fc5 --- /dev/null +++ b/trees/redblacktree/serialization.go @@ -0,0 +1,39 @@ +// Copyright (c) 2015, Emir Pasic. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package redblacktree + +import ( + "encoding/json" + "github.com/emirpasic/gods/containers" + "github.com/emirpasic/gods/utils" +) + +func assertSerializationImplementation() { + var _ containers.JSONSerializer = (*Tree)(nil) + var _ containers.JSONDeserializer = (*Tree)(nil) +} + +// ToJSON outputs the JSON representation of list's elements. +func (tree *Tree) ToJSON() ([]byte, error) { + elements := make(map[string]interface{}) + it := tree.Iterator() + for it.Next() { + elements[utils.ToString(it.Key())] = it.Value() + } + return json.Marshal(&elements) +} + +// FromJSON populates list's elements from the input JSON representation. +func (tree *Tree) FromJSON(data []byte) error { + elements := make(map[string]interface{}) + err := json.Unmarshal(data, &elements) + if err == nil { + tree.Clear() + for key, value := range elements { + tree.Put(key, value) + } + } + return err +}