summaryrefslogtreecommitdiffhomepage
path: root/utils
diff options
context:
space:
mode:
authorHiroshi Yokoi <yokoi.hiroshi@po.ntts.co.jp>2014-12-05 11:27:47 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2014-12-05 11:27:47 +0900
commit39686e18dbbbcfb32d891b86c3b1a978525bf370 (patch)
tree017001d6c617b9b521cebb9a65f04e1618ce338a /utils
parent9dd3001830c17f08ce659af003fb21b18df4883c (diff)
table: add initial code
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Diffstat (limited to 'utils')
-rw-r--r--utils/collection.go199
-rw-r--r--utils/collection_test.go162
2 files changed, 361 insertions, 0 deletions
diff --git a/utils/collection.go b/utils/collection.go
new file mode 100644
index 00000000..3f6e2ed1
--- /dev/null
+++ b/utils/collection.go
@@ -0,0 +1,199 @@
+// Copyright (C) 2014 Nippon Telegraph and Telephone Corporation.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+// implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package utils
+
+import (
+ "container/list"
+ "fmt"
+ "reflect"
+)
+
+// Elements of abstraction the key.
+type K struct {
+ Element interface{}
+}
+
+/*
+// Elements of abstraction the key.
+type V struct {
+ Element interface{}
+}
+*/
+/* This method may be required
+func (e *E) Elem() interface{} {
+ return e.Element
+}
+*/
+
+// Structure for extending the map collection.
+//
+// keyType : Key type of Map .
+// keyType : Value type of Map.
+// TMap : Map of the object to be extended.
+// TOrder : Insertion order list of map.
+type OrderedMap struct {
+ keyType interface{}
+ valType interface{}
+ TMap map[K]interface{}
+ TOrder *list.List
+}
+
+// Constructor of OrderedMap.
+func NewOrderedMap() *OrderedMap {
+ om := &OrderedMap{}
+ om.TMap = make(map[K]interface{})
+ om.TOrder = list.New()
+ return om
+}
+
+// Check whether the same of type of Map and List
+//
+// Returns: - error contents
+// and nil if no error occurred.
+func (om *OrderedMap) checkType(keyInfs interface{}, valInfs interface{}) (e error) {
+ if om.keyType == nil && om.valType == nil {
+ om.keyType = keyInfs
+ om.valType = valInfs
+ return nil
+ } else {
+ if reflect.TypeOf(om.keyType) != reflect.TypeOf(keyInfs) {
+ return fmt.Errorf("Map Key Type mismatch [ %s ] and [ %s ].", reflect.TypeOf(om.keyType), reflect.TypeOf(keyInfs))
+ }
+ }
+ return nil
+}
+
+// Check whether the same key exists in the map
+//
+// Returns: - error contents
+// and nil if no error occurred.
+func (om *OrderedMap) checkDuplicate(keyInfs interface{}) (e error) {
+ for elem := om.TOrder.Front(); elem != nil; elem = elem.Next() {
+ if elem.Value == keyInfs {
+ return fmt.Errorf("Map key Duplicated [%s].", elem.Value)
+ }
+ }
+ return
+}
+
+// Append Elements to Map
+//
+// Returns: - error contents
+// and nil if no error occurred.
+func (om *OrderedMap) Append(keyInfs interface{}, valInfs interface{}) (e error) {
+ e = om.checkType(keyInfs, valInfs)
+ if e != nil {
+ return e
+ }
+ // Append key Elements to Map
+ om.TMap[K{Element: keyInfs}] = valInfs
+ e = om.checkDuplicate(K{Element: keyInfs})
+ if e != nil {
+ /*
+ for elem := om.TOrder.Front(); elem != nil; elem = elem.Next() {
+ if elem.Value == (K{Element: keyInfs}) {
+ tmp := elem.Next()
+ om.TOrder.Remove(elem)
+ elem = tmp
+ }
+ }*/
+ return nil
+ }
+ // Append Elements to List
+ om.TOrder.PushBack(K{Element: keyInfs})
+ return nil
+}
+
+// Get Elements from receive parameter.
+//
+// Returns: - Value of Map
+// Return the interface that value has entered the Map.
+func (om *OrderedMap) Get(keyInfs interface{}) interface{} {
+ elem := om.TMap[K{Element: keyInfs}]
+ return elem
+}
+
+// Convert Map keys to List.
+//
+// Returns: - List of Map Keys
+func (om *OrderedMap) KeyLists() *list.List {
+ keys := list.New()
+ for key := om.TOrder.Front(); key != nil; key = key.Next() {
+ keyElem := key.Value.(K).Element
+ keys.PushBack(keyElem)
+ }
+ return keys
+}
+
+// Convert Map values to List.
+//
+// Returns: - List of Map Values
+func (om *OrderedMap) ValueLists() *list.List {
+ vals := list.New()
+ for key := om.TOrder.Front(); key != nil; key = key.Next() {
+ keyElem := key.Value.(K).Element
+ value := om.Get(keyElem)
+ vals.PushBack(value)
+ }
+ return vals
+}
+
+// Get Map length
+//
+// Returns: - Length of the map Element.
+func (om *OrderedMap) Len() int {
+ return om.TOrder.Len()
+}
+
+// Delete Map Element
+//
+// Returns: - error contents
+// and nil if no error occurred.
+func (om *OrderedMap) Delete(keyInfs interface{}) (e error) {
+ // Delete key Elements from Map
+ delete(om.TMap, K{Element: keyInfs})
+ // Delete key Elements from List
+ for elem := om.TOrder.Front(); elem != nil; elem = elem.Next() {
+ if elem.Value == (K{Element: keyInfs}) {
+ tmp := elem.Next()
+ if tmp == nil {
+ break
+ }
+ om.TOrder.Remove(elem)
+ elem = tmp
+ }
+ }
+ return
+}
+
+// Get Elements from Map and delete from List
+//
+// Returns: - Value of Map
+// Return the interface that value has entered the Map.
+func (om *OrderedMap) Pop(keyInfs interface{}) interface{} {
+ elem := om.TMap[K{Element: keyInfs}]
+ key := (K{Element: keyInfs}).Element
+ om.Delete(key)
+ return elem
+}
+
+// Clear Map and List
+func (om *OrderedMap) Clear() {
+ om.keyType = nil
+ om.valType = nil
+ om.TMap = make(map[K]interface{})
+ om.TOrder = list.New()
+}
diff --git a/utils/collection_test.go b/utils/collection_test.go
new file mode 100644
index 00000000..692c46f1
--- /dev/null
+++ b/utils/collection_test.go
@@ -0,0 +1,162 @@
+// collection_test.go
+package utils
+
+import (
+ "fmt"
+ "testing"
+)
+
+func insertData(t *testing.T, oMap *OrderedMap, num int) (*OrderedMap, string) {
+ var e error = nil
+ for i := 0; i < num; i++ {
+ arg := "test"
+ key := i
+ value := fmt.Sprintf("%s%d", arg, key)
+ e = oMap.Append(key, value)
+ if e != nil {
+ t.Error(e)
+ }
+ }
+ result := "FAIL"
+ if e == nil {
+ result = "OK"
+ }
+ return oMap, result
+}
+
+func getData(t *testing.T, oMap *OrderedMap, iNum int, deleteNum int) string {
+ var result string
+ for i := 0; i < iNum; i++ {
+ if deleteNum == i {
+ continue
+ }
+ arg := "test"
+ key := i
+ value := fmt.Sprintf("%s%d", arg, key)
+ ans := oMap.Get(i).Element
+ result = "OK"
+ //fmt.Println(ans)
+ if ans != value {
+ result = "FAIL"
+ break
+ }
+ }
+ return result
+}
+func deleteData(t *testing.T, oMap *OrderedMap, iNum int, deleteNum int) string {
+ e := oMap.Delete(deleteNum)
+ result := "OK"
+ if e != nil {
+ result = "FAIL"
+ t.Error(e)
+ return result
+ }
+ result = getData(t, oMap, iNum, deleteNum)
+ return result
+}
+func popData(t *testing.T, oMap *OrderedMap, iNum int, popNum int) string {
+ arg := "test"
+ value := fmt.Sprintf("%s%d", arg, popNum)
+ getValue := oMap.Pop(popNum).Element
+ result := "OK"
+ fmt.Println(getValue)
+ if value != getValue {
+ result = "FAIL"
+ t.Errorf("Different result < %s > < %s >", value, getValue)
+ return result
+ }
+ result = getData(t, oMap, iNum, popNum)
+ return result
+}
+func checkLen(t *testing.T, oMap *OrderedMap, iNum int) string {
+ mLen := oMap.Len()
+ result := "OK"
+ if mLen != iNum {
+ result = "FAIL"
+ t.Errorf("Different result < %d > < %d >", mLen, iNum)
+ return result
+ }
+ return result
+}
+func getkListData(t *testing.T, oMap *OrderedMap, iNum int) string {
+ kList := oMap.KeyLists()
+ mkLen := kList.Len()
+ result := "OK"
+ if mkLen != iNum {
+ result = "FAIL"
+ t.Errorf("Different result < %d > < %d >", mkLen, iNum)
+ return result
+ }
+ i := 0
+ for elem := kList.Front(); elem != nil; elem = elem.Next() {
+ if elem.Value != i {
+ result = "FAIL"
+ break
+ }
+ i++
+ }
+ return result
+}
+func getvListData(t *testing.T, oMap *OrderedMap, iNum int) string {
+ vList := oMap.ValueLists()
+ mvLen := vList.Len()
+ result := "OK"
+ if mvLen != iNum {
+ result = "FAIL"
+ t.Errorf("Different result < %d > < %d >", mvLen, iNum)
+ return result
+ }
+ arg := "test"
+ i := 0
+ for elem := vList.Front(); elem != nil; elem = elem.Next() {
+ value := fmt.Sprintf("%s%d", arg, i)
+ if elem.Value != value {
+ result = "FAIL"
+ break
+ }
+ i++
+ }
+ return result
+}
+func Test_Collection(t *testing.T) {
+ // init
+ var result string
+ iNum := 10
+ deleteNum := -1
+ oMap := NewOrderedMap()
+ // test
+ t.Log("# INSERT")
+ oMap, result = insertData(t, oMap, iNum)
+ t.Log("# INSERT END -> [ ", result, " ]")
+ t.Log("")
+ t.Log("# GET ELEMENT")
+ result = getData(t, oMap, iNum, deleteNum)
+ t.Log("# INSERT ELEMENT END -> [ ", result, " ]")
+ t.Log("")
+ t.Log("# DELETE ELEMENT")
+ deleteNum = 9
+ result = deleteData(t, oMap, iNum, deleteNum)
+ t.Log("# DELETE ELEMENT END -> [ ", result, " ]")
+ t.Log("")
+ t.Log("# POP ELEMENT")
+ popNum := 9
+ oMap = NewOrderedMap()
+ oMap, result = insertData(t, oMap, iNum)
+ result = popData(t, oMap, iNum, popNum)
+ t.Log("# POP ELEMENT END -> [ ", result, " ]")
+ t.Log("")
+ t.Log("# CHECK LEN")
+ oMap = NewOrderedMap()
+ oMap, result = insertData(t, oMap, iNum)
+ result = checkLen(t, oMap, iNum)
+ t.Log("# CHECK LEN END -> [ ", result, " ]")
+ t.Log("")
+ t.Log("# GET KEY LIST")
+ result = getkListData(t, oMap, iNum)
+ t.Log("# GET KEY LIST END -> [ ", result, " ]")
+ t.Log("")
+ t.Log("# GET VALUE LIST")
+ result = getvListData(t, oMap, iNum)
+ t.Log("# GET VALUE LIST END -> [ ", result, " ]")
+ t.Log("")
+}