moved aliases to cache

This commit is contained in:
Radu Ioan Fericean
2015-08-10 18:02:53 +03:00
parent bfe866d57c
commit 241306a9ae
12 changed files with 186 additions and 120 deletions

View File

@@ -95,89 +95,48 @@ type AliasService interface {
SetAlias(Alias, *string) error
RemoveAlias(Alias, *string) error
GetAlias(Alias, *Alias) error
ReloadAliases(string, *string) error
}
type AliasMap struct {
table map[string]AliasValues
type AliasHandler struct {
accountingDb AccountingStorage
mu sync.RWMutex
}
func NewAliasMap(accountingDb AccountingStorage) (*AliasMap, error) {
um := newAliasMap(accountingDb)
var reply string
if err := um.ReloadAliases("", &reply); err != nil {
return nil, err
}
return um, nil
}
func newAliasMap(accountingDb AccountingStorage) *AliasMap {
return &AliasMap{
table: make(map[string]AliasValues),
func NewAliasHandler(accountingDb AccountingStorage) *AliasHandler {
return &AliasHandler{
accountingDb: accountingDb,
}
}
func (am *AliasMap) ReloadAliases(in string, reply *string) error {
am.mu.Lock()
defer am.mu.Unlock()
// backup old data
oldTable := am.table
am.table = make(map[string]AliasValues)
// load from db
if ups, err := am.accountingDb.GetAliases(); err == nil {
for _, up := range ups {
am.table[up.GetId()] = up.Values
}
} else {
// restore old data before return
am.table = oldTable
*reply = err.Error()
return err
}
*reply = utils.OK
return nil
}
func (am *AliasMap) SetAlias(al Alias, reply *string) error {
func (am *AliasHandler) SetAlias(al Alias, reply *string) error {
am.mu.Lock()
defer am.mu.Unlock()
if err := am.accountingDb.SetAlias(&al); err != nil {
*reply = err.Error()
return err
}
am.table[al.GetId()] = al.Values
*reply = utils.OK
return nil
}
func (am *AliasMap) RemoveAlias(al Alias, reply *string) error {
func (am *AliasHandler) RemoveAlias(al Alias, reply *string) error {
am.mu.Lock()
defer am.mu.Unlock()
if err := am.accountingDb.RemoveAlias(al.GetId()); err != nil {
*reply = err.Error()
return err
}
delete(am.table, al.GetId())
*reply = utils.OK
return nil
}
func (am *AliasMap) GetAlias(al Alias, result *Alias) error {
func (am *AliasHandler) GetAlias(al Alias, result *Alias) error {
am.mu.RLock()
defer am.mu.RUnlock()
variants := al.GenerateIds()
//log.Print("TABLE: ", am.table)
for _, variant := range variants {
//log.Printf("AL %+v", variant)
if r, ok := am.table[variant]; ok {
al.Values = r
*result = al
if r, err := am.accountingDb.GetAlias(variant, false); err == nil {
*result = *r
return nil
}
}
@@ -205,7 +164,7 @@ func (ps *ProxyAliasService) RemoveAlias(al Alias, reply *string) error {
}
func (ps *ProxyAliasService) GetAlias(al Alias, alias *Alias) error {
return ps.Client.Call("AliasV1.GetAliases", al, alias)
return ps.Client.Call("AliasV1.GetAlias", al, alias)
}
func (ps *ProxyAliasService) ReloadAliases(in string, reply *string) error {
@@ -233,8 +192,8 @@ func GetBestAlias(destination, direction, tenant, category, account, subject, gr
for _, p := range utils.SplitPrefix(destination, MIN_PREFIX_MATCH) {
if x, err := cache2go.GetCached(utils.DESTINATION_PREFIX + p); err == nil {
for _, aliasMap := range values {
for alias, aliasDestIds := range aliasMap {
for _, aliasHandler := range values {
for alias, aliasDestIds := range aliasHandler {
destIds := x.(map[interface{}]struct{})
for idId := range destIds {
dId := idId.(string)

View File

@@ -724,7 +724,8 @@ func (cd *CallDescriptor) RefundIncrements() (left float64, err error) {
func (cd *CallDescriptor) FlushCache() (err error) {
cache2go.Flush()
ratingStorage.CacheAll()
ratingStorage.CacheRatingAll()
accountingStorage.CacheAccountingAll()
return nil
}

View File

@@ -616,7 +616,7 @@ func TestGetCostWithMaxCostFree(t *testing.T) {
}
func TestMaxSessionTimeWithAccountAlias(t *testing.T) {
aliasService, _ = NewAliasMap(accountingStorage)
aliasService = NewAliasHandler(accountingStorage)
cd := &CallDescriptor{
TimeStart: time.Date(2013, 10, 21, 18, 34, 0, 0, time.UTC),
TimeEnd: time.Date(2013, 10, 21, 18, 35, 0, 0, time.UTC),

View File

@@ -47,7 +47,7 @@ func InitDataDb(cfg *config.CGRConfig) error {
return err
}
}
ratingDb.CacheAll()
ratingDb.CacheRatingAll()
return nil
}

View File

@@ -282,7 +282,8 @@ func init() {
log.Print("error in LoadAliases:", err)
}
csvr.WriteToDatabase(false, false)
ratingStorage.CacheAll()
ratingStorage.CacheRatingAll()
accountingStorage.CacheAccountingAll()
}
func TestLoadDestinations(t *testing.T) {

View File

@@ -44,7 +44,7 @@ func TestResponderGetDerivedChargers(t *testing.T) {
if err := ratingStorage.SetDerivedChargers(utils.DerivedChargersKey(utils.OUT, utils.ANY, utils.ANY, utils.ANY, utils.ANY), cfgedDC); err != nil {
t.Error(err)
}
if err := ratingStorage.CachePrefixes(utils.DERIVEDCHARGERS_PREFIX); err != nil {
if err := ratingStorage.CacheRatingPrefixes(utils.DERIVEDCHARGERS_PREFIX); err != nil {
t.Error(err)
}
var dcs utils.DerivedChargers
@@ -94,7 +94,7 @@ func TestGetDerivedMaxSessionTime(t *testing.T) {
if err := ratingStorage.SetDerivedChargers(keyCharger1, charger1); err != nil {
t.Error("Error on setting DerivedChargers", err.Error())
}
ratingStorage.CacheAll()
ratingStorage.CacheRatingAll()
if rifStoredAcnt, err := accountingStorage.GetAccount(utils.ConcatenatedKey(utils.OUT, testTenant, "rif")); err != nil {
t.Error(err)
//} else if rifStoredAcnt.BalanceMap[utils.VOICE+OUTBOUND].Equal(rifsAccount.BalanceMap[utils.VOICE+OUTBOUND]) {
@@ -148,7 +148,7 @@ func TestGetSessionRuns(t *testing.T) {
if err := ratingStorage.SetDerivedChargers(keyCharger1, charger1); err != nil {
t.Error("Error on setting DerivedChargers", err.Error())
}
ratingStorage.CacheAll()
ratingStorage.CacheRatingAll()
sesRuns := make([]*SessionRun, 0)
eSRuns := []*SessionRun{
&SessionRun{DerivedCharger: extra1DC,
@@ -368,7 +368,7 @@ func TestGetLCR(t *testing.T) {
t.Error(err)
}
}
if err := ratingStorage.CachePrefixValues(map[string][]string{
if err := ratingStorage.CacheRatingPrefixValues(map[string][]string{
utils.DESTINATION_PREFIX: []string{utils.DESTINATION_PREFIX + dstDe.Id},
utils.RATING_PLAN_PREFIX: []string{utils.RATING_PLAN_PREFIX + rp1.Id, utils.RATING_PLAN_PREFIX + rp2.Id},
utils.RATING_PROFILE_PREFIX: []string{utils.RATING_PROFILE_PREFIX + danRpfl.Id, utils.RATING_PROFILE_PREFIX + rifRpfl.Id},

View File

@@ -38,10 +38,9 @@ type Storage interface {
// Interface for storage providers.
type RatingStorage interface {
Storage
CacheAll() error
CachePrefixes(...string) error
CachePrefixValues(map[string][]string) error
Cache([]string, []string, []string, []string, []string, []string, []string) error
CacheRatingAll() error
CacheRatingPrefixes(...string) error
CacheRatingPrefixValues(map[string][]string) error
HasData(string, string) (bool, error)
GetRatingPlan(string, bool) (*RatingPlan, error)
SetRatingPlan(*RatingPlan) error
@@ -67,6 +66,9 @@ type RatingStorage interface {
type AccountingStorage interface {
Storage
CacheAccountingAll() error
CacheAccountingPrefixes(...string) error
CacheAccountingPrefixValues(map[string][]string) error
GetAccount(string) (*Account, error)
SetAccount(*Account) error
RemoveAccount(string) error
@@ -80,8 +82,7 @@ type AccountingStorage interface {
GetUsers() ([]*UserProfile, error)
RemoveUser(string) error
SetAlias(*Alias) error
GetAlias(string) (*Alias, error)
GetAliases() ([]*Alias, error)
GetAlias(string, bool) (*Alias, error)
RemoveAlias(string) error
}

View File

@@ -62,11 +62,11 @@ func (ms *MapStorage) GetKeysForPrefix(prefix string) ([]string, error) {
return keysForPrefix, nil
}
func (ms *MapStorage) CacheAll() error {
return ms.Cache(nil, nil, nil, nil, nil, nil, nil)
func (ms *MapStorage) CacheRatingAll() error {
return ms.cacheRating(nil, nil, nil, nil, nil, nil, nil)
}
func (ms *MapStorage) CachePrefixes(prefixes ...string) error {
func (ms *MapStorage) CacheRatingPrefixes(prefixes ...string) error {
pm := map[string][]string{
utils.DESTINATION_PREFIX: []string{},
utils.RATING_PLAN_PREFIX: []string{},
@@ -82,10 +82,10 @@ func (ms *MapStorage) CachePrefixes(prefixes ...string) error {
}
pm[prefix] = nil
}
return ms.Cache(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX])
return ms.cacheRating(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX])
}
func (ms *MapStorage) CachePrefixValues(prefixes map[string][]string) error {
func (ms *MapStorage) CacheRatingPrefixValues(prefixes map[string][]string) error {
pm := map[string][]string{
utils.DESTINATION_PREFIX: []string{},
utils.RATING_PLAN_PREFIX: []string{},
@@ -101,10 +101,10 @@ func (ms *MapStorage) CachePrefixValues(prefixes map[string][]string) error {
}
pm[prefix] = ids
}
return ms.Cache(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX])
return ms.cacheRating(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX])
}
func (ms *MapStorage) Cache(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, actKeys, shgKeys []string) error {
func (ms *MapStorage) cacheRating(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, actKeys, shgKeys []string) error {
cache2go.BeginTransaction()
if dKeys == nil || (float64(cache2go.CountEntries(utils.DESTINATION_PREFIX))*utils.DESTINATIONS_LOAD_THRESHOLD < float64(len(dKeys))) {
cache2go.RemPrefixKey(utils.DESTINATION_PREFIX)
@@ -164,8 +164,6 @@ func (ms *MapStorage) Cache(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, actKeys, s
return err
}
}
}
for k, _ := range ms.dict {
if strings.HasPrefix(k, utils.ACTION_PREFIX) {
cache2go.RemKey(k)
if _, err := ms.GetActions(k[len(utils.ACTION_PREFIX):], true); err != nil {
@@ -185,6 +183,54 @@ func (ms *MapStorage) Cache(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, actKeys, s
return nil
}
func (ms *MapStorage) CacheAccountingAll() error {
return ms.cacheAccounting(nil)
}
func (ms *MapStorage) CacheAccountingPrefixes(prefixes ...string) error {
pm := map[string][]string{
utils.ALIASES_PREFIX: []string{},
}
for _, prefix := range prefixes {
if _, found := pm[prefix]; !found {
return utils.ErrNotFound
}
pm[prefix] = nil
}
return ms.cacheAccounting(pm[utils.ALIASES_PREFIX])
}
func (ms *MapStorage) CacheAccountingPrefixValues(prefixes map[string][]string) error {
pm := map[string][]string{
utils.ALIASES_PREFIX: []string{},
}
for prefix, ids := range prefixes {
if _, found := pm[prefix]; !found {
return utils.ErrNotFound
}
pm[prefix] = ids
}
return ms.cacheAccounting(pm[utils.ALIASES_PREFIX])
}
func (ms *MapStorage) cacheAccounting(alsKeys []string) error {
cache2go.BeginTransaction()
if alsKeys == nil {
cache2go.RemPrefixKey(utils.ALIASES_PREFIX) // Forced until we can fine tune it
}
for k, _ := range ms.dict {
if strings.HasPrefix(k, utils.ALIASES_PREFIX) {
cache2go.RemKey(k)
if _, err := ms.GetAlias(k[len(utils.ALIASES_PREFIX):], true); err != nil {
cache2go.RollbackTransaction()
return err
}
}
}
cache2go.CommitTransaction()
return nil
}
// Used to check if specific subject is stored using prefix key attached to entity
func (ms *MapStorage) HasData(categ, subject string) (bool, error) {
switch categ {
@@ -369,7 +415,9 @@ func (ms *MapStorage) GetSharedGroup(key string, skipCache bool) (sg *SharedGrou
}
if values, ok := ms.dict[key]; ok {
err = ms.ms.Unmarshal(values, &sg)
cache2go.Cache(key, sg)
if err == nil {
cache2go.Cache(key, sg)
}
} else {
return nil, utils.ErrNotFound
}
@@ -498,29 +546,30 @@ func (ms *MapStorage) SetAlias(al *Alias) error {
return nil
}
func (ms *MapStorage) GetAlias(key string) (al *Alias, err error) {
if values, ok := ms.dict[utils.ALIASES_PREFIX+key]; ok {
func (ms *MapStorage) GetAlias(key string, skipCache bool) (al *Alias, err error) {
key = utils.ALIASES_PREFIX + key
if !skipCache {
if x, err := cache2go.GetCached(key); err == nil {
al = &Alias{Values: x.(AliasValues)}
al.SetId(key[len(utils.ALIASES_PREFIX):])
return al, nil
} else {
return nil, err
}
}
if values, ok := ms.dict[key]; ok {
al = &Alias{Values: make(AliasValues, 0)}
err = ms.ms.Unmarshal(values, &al.Values)
al.SetId(key[len(utils.ALIASES_PREFIX):])
err = ms.ms.Unmarshal(values, &al.Values)
if err == nil {
cache2go.Cache(key, al.Values)
}
} else {
return nil, utils.ErrNotFound
}
return al, nil
}
func (ms *MapStorage) GetAliases() (als []*Alias, err error) {
for key, value := range ms.dict {
if strings.HasPrefix(key, utils.ALIASES_PREFIX) {
al := &Alias{Values: make(AliasValues, 0)}
if err = ms.ms.Unmarshal(value, &al.Values); err == nil {
al.SetId(key[len(utils.ALIASES_PREFIX):])
als = append(als, al)
}
}
}
return
}
func (ms *MapStorage) RemoveAlias(key string) error {
delete(ms.dict, utils.ALIASES_PREFIX+key)
return nil

View File

@@ -66,11 +66,11 @@ func (rs *RedisStorage) GetKeysForPrefix(prefix string) ([]string, error) {
return rs.db.Keys(prefix + "*")
}
func (rs *RedisStorage) CacheAll() error {
return rs.Cache(nil, nil, nil, nil, nil, nil, nil)
func (rs *RedisStorage) CacheRatingAll() error {
return rs.cacheRating(nil, nil, nil, nil, nil, nil, nil)
}
func (rs *RedisStorage) CachePrefixes(prefixes ...string) error {
func (rs *RedisStorage) CacheRatingPrefixes(prefixes ...string) error {
pm := map[string][]string{
utils.DESTINATION_PREFIX: []string{},
utils.RATING_PLAN_PREFIX: []string{},
@@ -86,10 +86,10 @@ func (rs *RedisStorage) CachePrefixes(prefixes ...string) error {
}
pm[prefix] = nil
}
return rs.Cache(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX])
return rs.cacheRating(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX])
}
func (rs *RedisStorage) CachePrefixValues(prefixes map[string][]string) error {
func (rs *RedisStorage) CacheRatingPrefixValues(prefixes map[string][]string) error {
pm := map[string][]string{
utils.DESTINATION_PREFIX: []string{},
utils.RATING_PLAN_PREFIX: []string{},
@@ -105,10 +105,10 @@ func (rs *RedisStorage) CachePrefixValues(prefixes map[string][]string) error {
}
pm[prefix] = ids
}
return rs.Cache(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX])
return rs.cacheRating(pm[utils.DESTINATION_PREFIX], pm[utils.RATING_PLAN_PREFIX], pm[utils.RATING_PROFILE_PREFIX], pm[utils.LCR_PREFIX], pm[utils.DERIVEDCHARGERS_PREFIX], pm[utils.ACTION_PREFIX], pm[utils.SHARED_GROUP_PREFIX])
}
func (rs *RedisStorage) Cache(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, actKeys, shgKeys []string) (err error) {
func (rs *RedisStorage) cacheRating(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, actKeys, shgKeys []string) (err error) {
cache2go.BeginTransaction()
if dKeys == nil || (float64(cache2go.CountEntries(utils.DESTINATION_PREFIX))*utils.DESTINATIONS_LOAD_THRESHOLD < float64(len(dKeys))) {
// if need to load more than a half of exiting keys load them all
@@ -238,6 +238,7 @@ func (rs *RedisStorage) Cache(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, actKeys,
if len(actKeys) != 0 {
Logger.Info("Finished actions caching.")
}
if shgKeys == nil {
cache2go.RemPrefixKey(utils.SHARED_GROUP_PREFIX)
}
@@ -260,6 +261,65 @@ func (rs *RedisStorage) Cache(dKeys, rpKeys, rpfKeys, lcrKeys, dcsKeys, actKeys,
if len(shgKeys) != 0 {
Logger.Info("Finished shared groups caching.")
}
cache2go.CommitTransaction()
return nil
}
func (rs *RedisStorage) CacheAccountingAll() error {
return rs.cacheAccounting(nil)
}
func (rs *RedisStorage) CacheAccountingPrefixes(prefixes ...string) error {
pm := map[string][]string{
utils.ALIASES_PREFIX: []string{},
}
for _, prefix := range prefixes {
if _, found := pm[prefix]; !found {
return utils.ErrNotFound
}
pm[prefix] = nil
}
return rs.cacheAccounting(pm[utils.ALIASES_PREFIX])
}
func (rs *RedisStorage) CacheAccountingPrefixValues(prefixes map[string][]string) error {
pm := map[string][]string{
utils.ALIASES_PREFIX: []string{},
}
for prefix, ids := range prefixes {
if _, found := pm[prefix]; !found {
return utils.ErrNotFound
}
pm[prefix] = ids
}
return rs.cacheAccounting(pm[utils.ALIASES_PREFIX])
}
func (rs *RedisStorage) cacheAccounting(alsKeys []string) (err error) {
cache2go.BeginTransaction()
if alsKeys == nil {
cache2go.RemPrefixKey(utils.ALIASES_PREFIX)
}
if alsKeys == nil {
Logger.Info("Caching all aliases")
if alsKeys, err = rs.db.Keys(utils.ALIASES_PREFIX + "*"); err != nil {
cache2go.RollbackTransaction()
return err
}
} else if len(alsKeys) != 0 {
Logger.Info(fmt.Sprintf("Caching aliases: %v", alsKeys))
}
for _, key := range alsKeys {
cache2go.RemKey(key)
if _, err = rs.GetAlias(key[len(utils.ALIASES_PREFIX):], true); err != nil {
cache2go.RollbackTransaction()
return err
}
}
if len(alsKeys) != 0 {
Logger.Info("Finished aliases caching.")
}
cache2go.CommitTransaction()
return nil
}
@@ -578,29 +638,24 @@ func (rs *RedisStorage) SetAlias(al *Alias) (err error) {
return
}
func (rs *RedisStorage) GetAlias(key string) (al *Alias, err error) {
func (rs *RedisStorage) GetAlias(key string, skipCache bool) (al *Alias, err error) {
key = utils.ALIASES_PREFIX + key
if !skipCache {
if x, err := cache2go.GetCached(key); err == nil {
al = &Alias{Values: x.(AliasValues)}
al.SetId(key[len(utils.ALIASES_PREFIX):])
return al, nil
} else {
return nil, err
}
}
var values []byte
if values, err = rs.db.Get(utils.ALIASES_PREFIX + key); err == nil {
if values, err = rs.db.Get(key); err == nil {
al = &Alias{Values: make(AliasValues, 0)}
al.SetId(key[len(utils.ALIASES_PREFIX):])
err = rs.ms.Unmarshal(values, &al.Values)
}
return
}
func (rs *RedisStorage) GetAliases() (result []*Alias, err error) {
keys, err := rs.db.Keys(utils.ALIASES_PREFIX + "*")
if err != nil {
return nil, err
}
for _, key := range keys {
if values, err := rs.db.Get(key); err == nil {
al := &Alias{Values: make(AliasValues, 0)}
err = rs.ms.Unmarshal(values, &al.Values)
al.SetId(key[len(utils.ALIASES_PREFIX):])
result = append(result, al)
} else {
return nil, utils.ErrNotFound
if err == nil {
cache2go.Cache(key, al.Values)
}
}
return

View File

@@ -48,7 +48,7 @@ func TestFlush(t *testing.T) {
if err := rds.Flush(""); err != nil {
t.Error("Failed to Flush redis database", err.Error())
}
rds.CacheAll()
rds.CacheRatingAll()
}
func TestSetGetDerivedCharges(t *testing.T) {

View File

@@ -49,7 +49,7 @@ func (self *SQLStorage) Flush(placeholder string) (err error) {
}
func (self *SQLStorage) GetKeysForPrefix(prefix string) ([]string, error) {
return nil, nil
return nil, utils.ErrNotImplemented
}
func (self *SQLStorage) CreateTablesFromScript(scriptPath string) error {

View File

@@ -102,7 +102,7 @@ func TestCacheRefresh(t *testing.T) {
ratingStorage.GetDestination("T11")
ratingStorage.SetDestination(&Destination{"T11", []string{"1"}})
t.Log("Test cache refresh")
ratingStorage.CacheAll()
ratingStorage.CacheRatingAll()
d, err := ratingStorage.GetDestination("T11")
p := d.containsPrefix("1")
if err != nil || p == 0 {