Using map[interface{}]struct{} instead of []interface{} in cache

This commit is contained in:
Radu Ioan Fericean
2014-11-26 18:28:07 +02:00
parent 728354331b
commit 680985200f
8 changed files with 28 additions and 66 deletions

View File

@@ -89,7 +89,7 @@ func TestCachePush(t *testing.T) {
CachePush("ccc_t1", "1")
CachePush("ccc_t1", "2")
v, err := GetCached("ccc_t1")
if err != nil || len(v.([]interface{})) != 2 {
if err != nil || len(v.(map[interface{}]struct{})) != 2 {
t.Error("Error in cache push: ", v)
}
}

View File

@@ -37,21 +37,15 @@ func (cs cacheDoubleStore) Put(key string, value interface{}) {
}
func (cs cacheDoubleStore) Append(key string, value interface{}) {
var elements []interface{}
v, err := cs.Get(key)
if err == nil {
elements = v.([]interface{})
var elements map[interface{}]struct{}
if v, err := cs.Get(key); err == nil {
elements = v.(map[interface{}]struct{})
} else {
elements = make(map[interface{}]struct{})
}
// check if the val is already present
found := false
for _, v := range elements {
if value == v {
found = true
break
}
}
if !found {
elements = append(elements, value)
if _, found := elements[value]; !found {
elements[value] = struct{}{}
}
cache.Put(key, elements)
}

View File

@@ -160,8 +160,8 @@ func (ub *Account) getBalancesForPrefix(prefix, category string, balances Balanc
if b.DestinationId != "" && b.DestinationId != utils.ANY {
for _, p := range utils.SplitPrefix(prefix, MIN_PREFIX_MATCH) {
if x, err := cache2go.GetCached(DESTINATION_PREFIX + p); err == nil {
destIds := x.([]interface{})
for _, dId := range destIds {
destIds := x.(map[interface{}]struct{})
for dId, _ := range destIds {
if dId == b.DestinationId {
b.precision = len(p)
usefulBalances = append(usefulBalances, b)

View File

@@ -20,11 +20,9 @@ package engine
import (
"encoding/json"
"sort"
"strings"
"github.com/cgrates/cgrates/cache2go"
"github.com/cgrates/cgrates/utils"
"github.com/cgrates/cgrates/history"
)
@@ -76,11 +74,8 @@ func (d *Destination) GetHistoryRecord() history.Record {
// Reverse search in cache to see if prefix belongs to destination id
func CachedDestHasPrefix(destId, prefix string) bool {
if cached, err := cache2go.GetCached(DESTINATION_PREFIX + prefix); err == nil {
for _, cachedDstId := range cached.([]interface{}) {
if destId == cachedDstId {
return true
}
}
_, found := cached.(map[interface{}]struct{})[destId]
return found
}
return false
}
@@ -91,17 +86,16 @@ func CleanStalePrefixes(destIds []string) {
return
}
for prefix, idIDs := range prefixMap {
dIDs := idIDs.Value().([]interface{})
dIDs := idIDs.Value().(map[interface{}]struct{})
changed := false
sort.Sort(utils.InterfaceStrings(dIDs))
for _, searchedDID := range destIds {
if i, found := utils.GetSliceInterfaceIndex(dIDs, searchedDID); found {
if _, found := dIDs[searchedDID]; found {
if len(dIDs) == 1 {
// remove de prefix from cache
cache2go.RemKey(DESTINATION_PREFIX + prefix)
} else {
// delete the destination from list and put the new list in chache
dIDs[i], dIDs = dIDs[len(dIDs)-1], dIDs[:len(dIDs)-1]
delete(dIDs, searchedDID)
changed = true
}
}

View File

@@ -126,17 +126,18 @@ func TestNonCachedDestWrongPrefix(t *testing.T) {
}
func TestCleanStalePrefixes(t *testing.T) {
cache2go.Cache(DESTINATION_PREFIX+"1", []interface{}{"D1", "D2"})
cache2go.Cache(DESTINATION_PREFIX+"2", []interface{}{"D1"})
cache2go.Cache(DESTINATION_PREFIX+"3", []interface{}{"D2"})
x := struct{}{}
cache2go.Cache(DESTINATION_PREFIX+"1", map[interface{}]struct{}{"D1": x, "D2": x})
cache2go.Cache(DESTINATION_PREFIX+"2", map[interface{}]struct{}{"D1": x})
cache2go.Cache(DESTINATION_PREFIX+"3", map[interface{}]struct{}{"D2": x})
CleanStalePrefixes([]string{"D1"})
if r, err := cache2go.GetCached(DESTINATION_PREFIX + "1"); err != nil || len(r.([]interface{})) != 1 {
if r, err := cache2go.GetCached(DESTINATION_PREFIX + "1"); err != nil || len(r.(map[interface{}]struct{})) != 1 {
t.Error("Error cleaning stale destination ids", r)
}
if r, err := cache2go.GetCached(DESTINATION_PREFIX + "2"); err == nil {
t.Error("Error removing stale prefix: ", r)
}
if r, err := cache2go.GetCached(DESTINATION_PREFIX + "3"); err != nil || len(r.([]interface{})) != 1 {
if r, err := cache2go.GetCached(DESTINATION_PREFIX + "3"); err != nil || len(r.(map[interface{}]struct{})) != 1 {
t.Error("Error performing stale cleaning: ", r)
}
}

View File

@@ -127,8 +127,8 @@ func (rp *RatingProfile) GetRatingPlansForPrefix(cd *CallDescriptor) (err error)
} else {
for _, p := range utils.SplitPrefix(cd.Destination, MIN_PREFIX_MATCH) {
if x, err := cache2go.GetCached(DESTINATION_PREFIX + p); err == nil {
destIds := x.([]interface{})
for _, idId := range destIds {
destIds := x.(map[interface{}]struct{})
for idId, _ := range destIds {
dId := idId.(string)
if _, ok := rpl.DestinationRates[dId]; ok {
rps = rpl.RateIntervalList(dId)

View File

@@ -78,13 +78,11 @@ func (uc *UnitsCounter) addUnits(amount float64, prefix string) {
}
for _, p := range utils.SplitPrefix(prefix, MIN_PREFIX_MATCH) {
if x, err := cache2go.GetCached(DESTINATION_PREFIX + p); err == nil {
destIds := x.([]interface{})
for _, dId := range destIds {
if dId == mb.DestinationId {
mb.Value += amount
counted = true
break
}
destIds := x.(map[interface{}]struct{})
if _, found := destIds[mb.DestinationId]; found {
mb.Value += amount
counted = true
break
}
}
if counted {

View File

@@ -32,16 +32,6 @@ func IsSliceMember(ss []string, s string) bool {
return false
}
// Binary string search in slice
// returns true if found and the index
func GetSliceMemberIndex(ss []string, s string) (int, bool) {
sort.Strings(ss)
if i := sort.SearchStrings(ss, s); i < len(ss) && ss[i] == s {
return i, true
}
return len(ss), false
}
//Iterates over slice members and returns true if one starts with prefix
func SliceMemberHasPrefix(ss []string, prfx string) bool {
for _, mbr := range ss {
@@ -51,18 +41,3 @@ func SliceMemberHasPrefix(ss []string, prfx string) bool {
}
return false
}
type InterfaceStrings []interface{}
func (a InterfaceStrings) Len() int { return len(a) }
func (a InterfaceStrings) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a InterfaceStrings) Less(i, j int) bool { return a[i].(string) < a[j].(string) }
// Binary string search in slice
// returns true if found and the index
func GetSliceInterfaceIndex(ss []interface{}, s interface{}) (int, bool) {
if i := sort.Search(len(ss), func(i int) bool { return ss[i].(string) >= s.(string) }); i < len(ss) && ss[i] == s {
return i, true
}
return len(ss), false
}