Coder Social home page Coder Social logo

emap's Introduction

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.

emap's People

Contributors

starwander avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.