diff options
Diffstat (limited to 'utils/collection.go')
-rw-r--r-- | utils/collection.go | 199 |
1 files changed, 199 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() +} |