diff options
author | Hiroshi Yokoi <yokoi.hiroshi@po.ntts.co.jp> | 2014-12-05 11:27:47 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2014-12-05 11:27:47 +0900 |
commit | 39686e18dbbbcfb32d891b86c3b1a978525bf370 (patch) | |
tree | 017001d6c617b9b521cebb9a65f04e1618ce338a /utils | |
parent | 9dd3001830c17f08ce659af003fb21b18df4883c (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.go | 199 | ||||
-rw-r--r-- | utils/collection_test.go | 162 |
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("") +} |