emap

package module
v0.0.0-...-2ddaa85 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 25, 2016 License: Apache-2.0 Imports: 4 Imported by: 0

README

Enhanced Golang Map

Build Status codecov Go Report Card GoDoc License

EMap implements an enhanced map in Golang. The main enhancement of emap over original golang map is the support of searching index.

  • Values in the emap can have one or more indices which can be used to search or delete.
  • Key in the emap must be unique as same as the key in the golang map.
  • Index in the emap is an N to M relation which mean a value can have multi indices and multi values can have one same index.

##Several Choices #####Generic EMap

  • The generic emap has no restrict for the type of its key, value and index.
  • The generic emap has a read-write locker inside so it is concurrent safe.

#####Expirable EMap

  • The expirable emap has no restrict for the type of its key, value and index.
  • The expirable emap has a read-write locker inside so it is concurrent safe.
  • The expirable emap will check all the values in the emap with the period of input interval(milliseconds). If a value is expired, it will be deleted automatically.

#####Strict EMap

  • The types of key, value and index used in the strict emap are determined during initialization by the sample inputs.
  • All methods of the strict emap must use the same type of the sample inputs otherwise an error will be returned.
  • The strict emap has a read-write locker inside so it is concurrent safe.

#####Unlock EMap

  • The unlock emap has no restrict for the type of its key, value and index.
  • The unlock emap has no locker or mutex inside, so it is not concurrent safe.
  • It is only suitable for those models like Event Loop to achieve better performance.

##Requirements #####Download this package

go get github.com/starwander/emap

#####Implements ExpirableValue interface of this package for all values if ExpirableEmap is chosen

// ExpirableValue is the interface which must be implemented by all the value in the expirable EMap.
type ExpirableValue interface {
	// IsExpired returns if the value is expired.
	// If true, the value will be deleted automatically.
	IsExpired() bool
}

Basic Operations

  • Insert: pushes a new value into emap with input key and indices.
  • FetchByKey: gets the value in the emap by input key.
  • FetchByIndex: gets the all values in the emap by input index.
  • DeleteByKey: deletes the value in the emap by input key.
  • DeleteByIndex: deletes all the values in the emap by input index.
  • AddIndex: add the input index to the value in the emap of the input key.
  • RemoveIndex: remove the input index from the value in the emap of the input key.
  • KeyNum: returns the total key number in the emap.
  • KeyNumOfIndex: returns the total key number of the input index in the emap.
  • IndexNum: returns the total index number in the emap.
  • IndexNumOfKey: returns the total index number of the input key in the emap.
  • HasKey: returns if the input key exists in the emap.
  • HasIndex: returns if the input index exists in the emap.

Higher-order Operations

  • Transform:
  • Transform is a higher-order operation which apply the input callback function to each key-value pair in the emap.
  • Any error returned by the callback function will interrupt the transforming and the error will be returned.
  • If transform successfully, a new golang map is created with each key-value pair returned by the input callback function.
  • Foreach:
  • Foreach is a higher-order operation which apply the input callback function to each key-value pair in the emap.
  • Since the callback function has no return, the foreach procedure will never be interrupted.
  • A typical usage of Foreach is apply a closure.

Example

package main

import (
	"fmt"
	"github.com/starwander/emap"
	"time"
)

type employee struct {
	name       string
	gender     string
	department string
	retired    bool
	//hobby      []string
}

type emplyeeByDept struct {
	name       string
	department string
}

func (e *employee) IsExpired() bool {
	return e.retired
}

func main() {
	emap := emap.NewExpirableEMap(1000)

	emap.Insert("Tom", &employee{"Tom", "Male", "R&D", false}, "R&D", "swimming", "hiking")
	emap.Insert("Jerry", &employee{"Jerry", "Male", "Sales", false}, "Sales", "football", "hiking")
	emap.Insert("Carol", &employee{"Carol", "Female", "HR", false}, "HR", "movie")
	emap.Insert("Jessie", &employee{"Jessie", "Female", "Sales", false}, "Sales", "hiking", "cycling")

	fmt.Println(emap.KeyNum())                //4
	fmt.Println(emap.IndexNum())              //8
	fmt.Println(emap.IndexNumOfKey("Tom"))    //3
	fmt.Println(emap.KeyNumOfIndex("hiking")) //3

	fmt.Println(emap.FetchByKey("Carol")) // &{Carol Female HR false} <nil>
	allSales, _ := emap.FetchByIndex("Sales")
	for _, each := range allSales {
		//&{Jerry Male Sales false}
		//&{Jessie Female Sales false}
		fmt.Println(each.(*employee))
	}

	emap.RemoveIndex("Jerry", "hiking")
	allHiking, _ := emap.FetchByIndex("hiking")
	for _, each := range allHiking {
		//&{Tom Male R&D false}
		//&{Jessie Female Sales false}
		fmt.Println(each.(*employee))
	}
	emap.AddIndex("Jessie", "movie")
	allMovie, _ := emap.FetchByIndex("movie")
	for _, each := range allMovie {
		//&{Carol Female HR false}
		//&{Jessie Female Sales false}
		fmt.Println(each.(*employee))
	}

	emap.DeleteByKey("Jerry")
	fmt.Println(emap.KeyNum()) //3

	nameAndDept, _ := emap.Transform(func(n interface{}, e interface{}) (interface{}, error) {
		return &emplyeeByDept{n.(string), e.(*employee).department}, nil
	})
	for _, each := range nameAndDept {
		//&{Jessie Sales}
		//&{Tom R&D}
		//&{Carol HR}
		fmt.Println(each.(*emplyeeByDept))
	}

	var totalMaleNum, totalFemalNum int
	emap.Foreach(func(n interface{}, e interface{}) {
		if e.(*employee).gender == "Male" {
			totalMaleNum++
		} else {
			totalFemalNum++
		}
	})
	fmt.Println("Total male number:", totalMaleNum, "Total female number:", totalFemalNum) //Total male number: 1 Total female number: 2

	carol, _ := emap.FetchByKey("Carol")
	carol.(*employee).retired = true
	time.Sleep(1100 * time.Millisecond)
	fmt.Println(emap.FetchByKey("Carol")) //<nil> key not exist
}

Reference

GoDoc

LICENSE

EMap source code is licensed under the Apache Licence, Version 2.0.

Documentation

Overview

Package emap implements an enhanced map in golang. The main enhancement of emap over original golang map is the support of searching index. Values in the emap can have one or more indices which can be used to search or delete. Key in the emap must be unique as same as the key in the golang map. Index in the emap is an N to M relation which mean a value can have multi indices and multi values can have one same index.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ExpirableValue

type ExpirableValue interface {
	// IsExpired returns if the value is expired.
	// If true, the value will be deleted automatically.
	IsExpired() bool
}

ExpirableValue is the interface which must be implemented by all the value in the expirable EMap.

type GenericEMap

type GenericEMap struct {
	// contains filtered or unexported fields
}

GenericEMap has a read-write locker inside so it is concurrent safe. The value, key and index type is unlimited in the generic emap.

func NewExpirableEMap

func NewExpirableEMap(interval int) *GenericEMap

NewExpirableEMap creates a new generic emap with an expiration checker. The expiration checker will check all the values in the emap with the period of input interval(milliseconds). All value inserted into the expirable emap must implements ExpirableValue interface of this package. If a value is expired, it will be deleted automatically.

func NewGenericEMap

func NewGenericEMap() *GenericEMap

NewGenericEMap creates a new generic emap.

func (*GenericEMap) AddIndex

func (m *GenericEMap) AddIndex(key interface{}, index interface{}) error

AddIndex add the input index to the value in the emap of the input key. Try to add a duplicate index will cause an error return. Try to add an index to a non-existed value will cause an error return.

func (*GenericEMap) DeleteByIndex

func (m *GenericEMap) DeleteByIndex(index interface{}) error

DeleteByIndex deletes all the values in the emap by input index. Try to delete a non-existed index will cause an error return.

func (*GenericEMap) DeleteByKey

func (m *GenericEMap) DeleteByKey(key interface{}) error

DeleteByKey deletes the value in the emap by input key. Try to delete a non-existed key will cause an error return.

func (*GenericEMap) FetchByIndex

func (m *GenericEMap) FetchByIndex(index interface{}) ([]interface{}, error)

FetchByIndex gets the all values in the emap by input index. Try to fetch a non-existed index will cause an error return.

func (*GenericEMap) FetchByKey

func (m *GenericEMap) FetchByKey(key interface{}) (interface{}, error)

FetchByKey gets the value in the emap by input key. Try to fetch a non-existed key will cause an error return.

func (*GenericEMap) Foreach

func (m *GenericEMap) Foreach(callback func(interface{}, interface{}))

Foreach is a higher-order operation which apply the input callback function to each key-value pair in the emap. Since the callback function has no return, the foreach procedure will never be interrupted. A typical usage of Foreach is apply a closure.

func (*GenericEMap) HasIndex

func (m *GenericEMap) HasIndex(index interface{}) bool

HasIndex returns if the input index exists in the emap.

func (*GenericEMap) HasKey

func (m *GenericEMap) HasKey(key interface{}) bool

HasKey returns if the input key exists in the emap.

func (*GenericEMap) IndexNum

func (m *GenericEMap) IndexNum() int

IndexNum returns the total index number in the emap.

func (*GenericEMap) IndexNumOfKey

func (m *GenericEMap) IndexNumOfKey(key interface{}) int

IndexNumOfKey returns the total index number of the input key in the emap.

func (*GenericEMap) Insert

func (m *GenericEMap) Insert(key interface{}, value interface{}, indices ...interface{}) error

Insert pushes a new value into emap with input key and indices. Input key must not be duplicated. Input indices are optional.

func (*GenericEMap) KeyNum

func (m *GenericEMap) KeyNum() int

KeyNum returns the total key number in the emap.

func (*GenericEMap) KeyNumOfIndex

func (m *GenericEMap) KeyNumOfIndex(index interface{}) int

KeyNumOfIndex returns the total key number of the input index in the emap.

func (*GenericEMap) RemoveIndex

func (m *GenericEMap) RemoveIndex(key interface{}, index interface{}) error

RemoveIndex remove the input index from the value in the emap of the input key. Try to delete a non-existed index will cause an error return. Try to delete an index from a non-existed value will cause an error return.

func (*GenericEMap) Transform

func (m *GenericEMap) Transform(callback func(interface{}, interface{}) (interface{}, error)) (map[interface{}]interface{}, error)

Transform is a higher-order operation which apply the input callback function to each key-value pair in the emap. Any error returned by the callback function will interrupt the transforming and the error will be returned. If transform successfully, a new golang map is created with each key-value pair returned by the input callback function.

type StrictEMap

type StrictEMap struct {
	// contains filtered or unexported fields
}

StrictEMap has a read-write locker inside so it is concurrent safe. The type of key, value and index is determined by the input keySample, valueSample and indexSample. Only the types of the sample inputs matter, the values of the sample inputs are irrelevant. All methods of the strict emap must use the same type of the sample inputs otherwise an error will be returned.

func NewStrictEMap

func NewStrictEMap(keySample interface{}, valueSample interface{}, indexSample interface{}) (*StrictEMap, error)

NewStrictEMap creates a new strict emap. The types of value, key and index are determined by the inputs. Try to appoint any unsupported key or index types, such as pointer, will cause an error return.

func (*StrictEMap) AddIndex

func (m *StrictEMap) AddIndex(key interface{}, index interface{}) error

AddIndex add the input index to the value in the emap of the input key. Try to add a duplicate index will cause an error return. Try to add an index to a non-existed value will cause an error return.

func (*StrictEMap) DeleteByIndex

func (m *StrictEMap) DeleteByIndex(index interface{}) error

DeleteByIndex deletes all the values in the emap by input index. Try to delete a non-existed index will cause an error return.

func (*StrictEMap) DeleteByKey

func (m *StrictEMap) DeleteByKey(key interface{}) error

DeleteByKey deletes the value in the emap by input key. Try to delete a non-existed key will cause an error return.

func (*StrictEMap) FetchByIndex

func (m *StrictEMap) FetchByIndex(index interface{}) ([]interface{}, error)

FetchByIndex gets the all values in the emap by input index. Try to fetch a non-existed index will cause an error return.

func (*StrictEMap) FetchByKey

func (m *StrictEMap) FetchByKey(key interface{}) (interface{}, error)

FetchByKey gets the value in the emap by input key. Try to fetch a non-existed key will cause an error return.

func (*StrictEMap) Foreach

func (m *StrictEMap) Foreach(callback func(interface{}, interface{}))

Foreach is a higher-order operation which apply the input callback function to each key-value pair in the emap. Since the callback function has no return, the foreach procedure will never be interrupted. A typical usage of Foreach is apply a closure.

func (*StrictEMap) HasIndex

func (m *StrictEMap) HasIndex(index interface{}) bool

HasIndex returns if the input index exists in the emap.

func (*StrictEMap) HasKey

func (m *StrictEMap) HasKey(key interface{}) bool

HasKey returns if the input key exists in the emap.

func (*StrictEMap) IndexNum

func (m *StrictEMap) IndexNum() int

IndexNum returns the total index number in the emap.

func (*StrictEMap) IndexNumOfKey

func (m *StrictEMap) IndexNumOfKey(key interface{}) int

IndexNumOfKey returns the total index number of the input key in the emap.

func (*StrictEMap) Insert

func (m *StrictEMap) Insert(key interface{}, value interface{}, indices ...interface{}) error

Insert pushes a new value into emap with input key and indices. Input key must not be duplicated. Input indices are optional.

func (*StrictEMap) KeyNum

func (m *StrictEMap) KeyNum() int

KeyNum returns the total key number in the emap.

func (*StrictEMap) KeyNumOfIndex

func (m *StrictEMap) KeyNumOfIndex(index interface{}) int

KeyNumOfIndex returns the total key number of the input index in the emap.

func (*StrictEMap) RemoveIndex

func (m *StrictEMap) RemoveIndex(key interface{}, index interface{}) error

RemoveIndex remove the input index from the value in the emap of the input key. Try to delete a non-existed index will cause an error return. Try to delete an index from a non-existed value will cause an error return.

func (*StrictEMap) Transform

func (m *StrictEMap) Transform(callback func(interface{}, interface{}) (interface{}, error)) (map[interface{}]interface{}, error)

Transform is a higher-order operation which apply the input callback function to each key-value pair in the emap. Any error returned by the callback function will interrupt the transforming and the error will be returned. If transform successfully, a new golang map is created with each key-value pair returned by the input callback function.

type UnlockEMap

type UnlockEMap struct {
	// contains filtered or unexported fields
}

UnlockEMap basically is a generic emap without internal locker or mutex. So unlock emap is not concurrent safe, it is only suitable for those models like Event Loop to achieve better performance.

func NewUnlockEMap

func NewUnlockEMap() *UnlockEMap

NewUnlockEMap creates a new unlock emap.

func (*UnlockEMap) AddIndex

func (m *UnlockEMap) AddIndex(key interface{}, index interface{}) error

AddIndex add the input index to the value in the emap of the input key. Try to add a duplicate index will cause an error return. Try to add an index to a non-existed value will cause an error return.

func (*UnlockEMap) DeleteByIndex

func (m *UnlockEMap) DeleteByIndex(index interface{}) error

DeleteByIndex deletes all the values in the emap by input index. Try to delete a non-existed index will cause an error return.

func (*UnlockEMap) DeleteByKey

func (m *UnlockEMap) DeleteByKey(key interface{}) error

DeleteByKey deletes the value in the emap by input key. Try to delete a non-existed key will cause an error return.

func (*UnlockEMap) FetchByIndex

func (m *UnlockEMap) FetchByIndex(index interface{}) ([]interface{}, error)

FetchByIndex gets the all values in the emap by input index. Try to fetch a non-existed index will cause an error return.

func (*UnlockEMap) FetchByKey

func (m *UnlockEMap) FetchByKey(key interface{}) (interface{}, error)

FetchByKey gets the value in the emap by input key. Try to fetch a non-existed key will cause an error return.

func (*UnlockEMap) Foreach

func (m *UnlockEMap) Foreach(callback func(interface{}, interface{}))

Foreach is a higher-order operation which apply the input callback function to each key-value pair in the emap. Since the callback function has no return, the foreach procedure will never be interrupted. A typical usage of Foreach is apply a closure.

func (*UnlockEMap) HasIndex

func (m *UnlockEMap) HasIndex(index interface{}) bool

HasIndex returns if the input index exists in the emap.

func (*UnlockEMap) HasKey

func (m *UnlockEMap) HasKey(key interface{}) bool

HasKey returns if the input key exists in the emap.

func (*UnlockEMap) IndexNum

func (m *UnlockEMap) IndexNum() int

IndexNum returns the total index number in the emap.

func (*UnlockEMap) IndexNumOfKey

func (m *UnlockEMap) IndexNumOfKey(key interface{}) int

IndexNumOfKey returns the total index number of the input key in the emap.

func (*UnlockEMap) Insert

func (m *UnlockEMap) Insert(key interface{}, value interface{}, indices ...interface{}) error

Insert pushes a new value into emap with input key and indices. Input key must not be duplicated. Input indices are optional.

func (*UnlockEMap) KeyNum

func (m *UnlockEMap) KeyNum() int

KeyNum returns the total key number in the emap.

func (*UnlockEMap) KeyNumOfIndex

func (m *UnlockEMap) KeyNumOfIndex(index interface{}) int

KeyNumOfIndex returns the total key number of the input index in the emap.

func (*UnlockEMap) RemoveIndex

func (m *UnlockEMap) RemoveIndex(key interface{}, index interface{}) error

RemoveIndex remove the input index from the value in the emap of the input key. Try to delete a non-existed index will cause an error return. Try to delete an index from a non-existed value will cause an error return.

func (*UnlockEMap) Transform

func (m *UnlockEMap) Transform(callback func(interface{}, interface{}) (interface{}, error)) (map[interface{}]interface{}, error)

Transform is a higher-order operation which apply the input callback function to each key-value pair in the emap. Any error returned by the callback function will interrupt the transforming and the error will be returned. If transform successfully, a new golang map is created with each key-value pair returned by the input callback function.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL