在地图中存储多个值

时间:2014-07-20 09:53:13

标签: go maps

问题:将IP地址和时间都存储到计数器中。像这样的东西

ip,time,count

然后我希望能够增加每个ip的计数:

IP ++

在我的地图中,然后在给定的时间间隔内,我想迭代所有键并找到时间戳超过N分钟的键。

我需要这个以确保我不会“忘记”内存中的密钥如果由于某种原因,客户端断开连接并且我没有正确删除密钥。

http://play.golang.org/p/RiWWOCARq7

问题:如何为我在地图中存储的每个IP地址添加时间戳。此外,我需要在多个go例程中使用它

我对编程和Golang都很陌生,所以如果这不是正确的方法,如果有人能指出我正确的方向,我会很感激。

3 个答案:

答案 0 :(得分:7)

例如,

package main

import (
    "sync"
    "time"
)

type IPCounter struct {
    IPAddr string
    Time   time.Time
    Count  int
}

type ipCounterMap struct {
    counters map[string]IPCounter
    mutex    sync.RWMutex
}

var ipCounters = ipCounterMap{counters: make(map[string]IPCounter)}

// Get IP address counter
func Counter(ipAddr string) IPCounter {
    ipCounters.mutex.RLock()
    defer ipCounters.mutex.RUnlock()
    counter, found := ipCounters.counters[ipAddr]
    if !found {
        counter.IPAddr = ipAddr
    }
    return counter
}

// Increment IP address counter
func Incr(ipAddr string) {
    now := time.Now().UTC()
    ipCounters.mutex.Lock()
    defer ipCounters.mutex.Unlock()
    counter, found := ipCounters.counters[ipAddr]
    if !found {
        counter.IPAddr = ipAddr
    }
    counter.Time = now
    counter.Count++
    ipCounters.counters[ipAddr] = counter
}

// Delete IP address counter
func Delete(ipAddr string) {
    ipCounters.mutex.Lock()
    defer ipCounters.mutex.Unlock()
    delete(ipCounters.counters, ipAddr)
}

// Get old IP address counters old durations ago
func OldIPCounters(old time.Duration) []IPCounter {
    var counters []IPCounter
    oldTime := time.Now().UTC().Add(-old)
    ipCounters.mutex.RLock()
    defer ipCounters.mutex.RUnlock()
    for _, counter := range ipCounters.counters {
        if counter.Time.Before(oldTime) {
            counters = append(counters, counter)
        }
    }
    return counters
}

func main() {}

答案 1 :(得分:4)

你可能想要一张ip的地图 - > struct {ip,counter,lastTime} 这样,你可以通过ip查找计数器,然后更新它

var Counters = map[string]*Counter{}

type Counter struct {
    ip       string
    count    int
    lastTime time.Time
}

以下是Play http://play.golang.org/p/TlCTc_4iq5

的工作示例

添加较旧的查找范围只是比现在的地图值的范围,并且当它足够老时执行某些操作。

答案 2 :(得分:2)

听起来你需要structmap用于存储集合,其中所有键都是一种类型,所有元素都是另一种(或相同类型)。

要对相关的不同数据类型的变量集合进行分组,请使用struct

e.g。

type IPCounter struct {
    ip    string
    time  time.Time
    count int
}

这里有一些示例代码可以创建其中一个对象并递增计数:

package main

import (
    "fmt"
    "time"
)

type IPAddressCounter struct {
    ip    string
    time  time.Time
    count int
}

func (i *IPAddressCounter) IncrementCount() {
    i.count++
}

func makeCounter(ip string) IPAddressCounter {
    return IPAddressCounter{
        ip:   ip,
        time: time.Now(),
    }
}

func main() {
    mapOfIPCounters := make(map[string]IPAddressCounter)

    mapOfIPCounters["192.168.1.1"] = makeCounter("192.168.1.1")
    mapOfIPCounters["192.168.1.2"] = makeCounter("192.168.1.2")
    mapOfIPCounters["192.168.1.3"] = makeCounter("192.168.1.3")

    for key, value := range mapOfIPCounters {
        value.IncrementCount()
        mapOfIPCounters[key] = value

        fmt.Println("The counter for "+key+" is", mapOfIPCounters[key].count)
    }

}