Move caches to manager #1553

Merged
lunny merged 1 commits from lunny/move_caches into master 2020-02-27 03:12:27 +00:00
8 changed files with 81 additions and 50 deletions

56
caches/manager.go Normal file
View File

@ -0,0 +1,56 @@
// Copyright 2020 The Xorm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package caches
import "sync"
type Manager struct {
cacher Cacher
disableGlobalCache bool
cachers map[string]Cacher
cacherLock sync.RWMutex
}
func NewManager() *Manager {
return &Manager{
cachers: make(map[string]Cacher),
}
}
// SetDisableGlobalCache disable global cache or not
func (mgr *Manager) SetDisableGlobalCache(disable bool) {
if mgr.disableGlobalCache != disable {
mgr.disableGlobalCache = disable
}
}
func (mgr *Manager) SetCacher(tableName string, cacher Cacher) {
mgr.cacherLock.Lock()
mgr.cachers[tableName] = cacher
mgr.cacherLock.Unlock()
}
func (mgr *Manager) GetCacher(tableName string) Cacher {
var cacher Cacher
var ok bool
mgr.cacherLock.RLock()
cacher, ok = mgr.cachers[tableName]
mgr.cacherLock.RUnlock()
if !ok && !mgr.disableGlobalCache {
cacher = mgr.cacher
}
return cacher
}
// SetDefaultCacher set the default cacher. Xorm's default not enable cacher.
func (mgr *Manager) SetDefaultCacher(cacher Cacher) {
mgr.cacher = cacher
}
// GetDefaultCacher returns the default cacher
func (mgr *Manager) GetDefaultCacher() Cacher {
return mgr.cacher
}

View File

@ -41,7 +41,6 @@ type Engine struct {
Tables map[reflect.Type]*schemas.Table Tables map[reflect.Type]*schemas.Table
mutex *sync.RWMutex mutex *sync.RWMutex
Cacher caches.Cacher
showSQL bool showSQL bool
showExecTime bool showExecTime bool
@ -50,42 +49,20 @@ type Engine struct {
TZLocation *time.Location // The timezone of the application TZLocation *time.Location // The timezone of the application
DatabaseTZ *time.Location // The timezone of the database DatabaseTZ *time.Location // The timezone of the database
disableGlobalCache bool
tagHandlers map[string]tagHandler tagHandlers map[string]tagHandler
engineGroup *EngineGroup engineGroup *EngineGroup
cacherMgr *caches.Manager
cachers map[string]caches.Cacher
cacherLock sync.RWMutex
defaultContext context.Context defaultContext context.Context
} }
func (engine *Engine) setCacher(tableName string, cacher caches.Cacher) {
engine.cacherLock.Lock()
engine.cachers[tableName] = cacher
engine.cacherLock.Unlock()
}
func (engine *Engine) SetCacher(tableName string, cacher caches.Cacher) { func (engine *Engine) SetCacher(tableName string, cacher caches.Cacher) {
engine.setCacher(tableName, cacher) engine.cacherMgr.SetCacher(tableName, cacher)
}
func (engine *Engine) getCacher(tableName string) caches.Cacher {
var cacher caches.Cacher
var ok bool
engine.cacherLock.RLock()
cacher, ok = engine.cachers[tableName]
engine.cacherLock.RUnlock()
if !ok && !engine.disableGlobalCache {
cacher = engine.Cacher
}
return cacher
} }
func (engine *Engine) GetCacher(tableName string) caches.Cacher { func (engine *Engine) GetCacher(tableName string) caches.Cacher {
return engine.getCacher(tableName) return engine.cacherMgr.GetCacher(tableName)
} }
// BufferSize sets buffer size for iterate // BufferSize sets buffer size for iterate
@ -152,9 +129,7 @@ func (engine *Engine) SetLogLevel(level log.LogLevel) {
// SetDisableGlobalCache disable global cache or not // SetDisableGlobalCache disable global cache or not
func (engine *Engine) SetDisableGlobalCache(disable bool) { func (engine *Engine) SetDisableGlobalCache(disable bool) {
if engine.disableGlobalCache != disable { engine.cacherMgr.SetDisableGlobalCache(disable)
engine.disableGlobalCache = disable
}
} }
// DriverName return the current sql driver's name // DriverName return the current sql driver's name
@ -244,12 +219,12 @@ func (engine *Engine) SetMaxIdleConns(conns int) {
// SetDefaultCacher set the default cacher. Xorm's default not enable cacher. // SetDefaultCacher set the default cacher. Xorm's default not enable cacher.
func (engine *Engine) SetDefaultCacher(cacher caches.Cacher) { func (engine *Engine) SetDefaultCacher(cacher caches.Cacher) {
engine.Cacher = cacher engine.cacherMgr.SetDefaultCacher(cacher)
} }
// GetDefaultCacher returns the default cacher // GetDefaultCacher returns the default cacher
func (engine *Engine) GetDefaultCacher() caches.Cacher { func (engine *Engine) GetDefaultCacher() caches.Cacher {
return engine.Cacher return engine.cacherMgr.GetDefaultCacher()
} }
// NoCache If you has set default cacher, and you want temporilly stop use cache, // NoCache If you has set default cacher, and you want temporilly stop use cache,
@ -269,7 +244,7 @@ func (engine *Engine) NoCascade() *Session {
// MapCacher Set a table use a special cacher // MapCacher Set a table use a special cacher
func (engine *Engine) MapCacher(bean interface{}, cacher caches.Cacher) error { func (engine *Engine) MapCacher(bean interface{}, cacher caches.Cacher) error {
engine.setCacher(engine.TableName(bean, true), cacher) engine.SetCacher(engine.TableName(bean, true), cacher)
return nil return nil
} }
@ -799,7 +774,7 @@ func (engine *Engine) autoMapType(v reflect.Value) (*schemas.Table, error) {
} }
engine.Tables[t] = table engine.Tables[t] = table
if engine.Cacher != nil { if engine.GetDefaultCacher() != nil {
if v.CanAddr() { if v.CanAddr() {
engine.GobRegister(v.Addr().Interface()) engine.GobRegister(v.Addr().Interface())
} else { } else {
@ -1030,17 +1005,17 @@ func (engine *Engine) mapType(v reflect.Value) (*schemas.Table, error) {
} }
if hasCacheTag { if hasCacheTag {
if engine.Cacher != nil { // !nash! use engine's cacher if provided if engine.GetDefaultCacher() != nil { // !nash! use engine's cacher if provided
engine.logger.Info("enable cache on table:", table.Name) engine.logger.Info("enable cache on table:", table.Name)
engine.setCacher(table.Name, engine.Cacher) engine.SetCacher(table.Name, engine.GetDefaultCacher())
} else { } else {
engine.logger.Info("enable LRU cache on table:", table.Name) engine.logger.Info("enable LRU cache on table:", table.Name)
engine.setCacher(table.Name, caches.NewLRUCacher2(caches.NewMemoryStore(), time.Hour, 10000)) engine.SetCacher(table.Name, caches.NewLRUCacher2(caches.NewMemoryStore(), time.Hour, 10000))
} }
} }
if hasNoCacheTag { if hasNoCacheTag {
engine.logger.Info("disable cache on table:", table.Name) engine.logger.Info("disable cache on table:", table.Name)
engine.setCacher(table.Name, nil) engine.SetCacher(table.Name, nil)
} }
return table, nil return table, nil
@ -1152,7 +1127,7 @@ func (engine *Engine) CreateUniques(bean interface{}) error {
// ClearCacheBean if enabled cache, clear the cache bean // ClearCacheBean if enabled cache, clear the cache bean
func (engine *Engine) ClearCacheBean(bean interface{}, id string) error { func (engine *Engine) ClearCacheBean(bean interface{}, id string) error {
tableName := engine.TableName(bean) tableName := engine.TableName(bean)
cacher := engine.getCacher(tableName) cacher := engine.GetCacher(tableName)
if cacher != nil { if cacher != nil {
cacher.ClearIds(tableName) cacher.ClearIds(tableName)
cacher.DelBean(tableName, id) cacher.DelBean(tableName, id)
@ -1164,7 +1139,7 @@ func (engine *Engine) ClearCacheBean(bean interface{}, id string) error {
func (engine *Engine) ClearCache(beans ...interface{}) error { func (engine *Engine) ClearCache(beans ...interface{}) error {
for _, bean := range beans { for _, bean := range beans {
tableName := engine.TableName(bean) tableName := engine.TableName(bean)
cacher := engine.getCacher(tableName) cacher := engine.GetCacher(tableName)
if cacher != nil { if cacher != nil {
cacher.ClearIds(tableName) cacher.ClearIds(tableName)
cacher.ClearBeans(tableName) cacher.ClearBeans(tableName)

View File

@ -28,7 +28,7 @@ func (session *Session) cacheDelete(table *schemas.Table, tableName, sqlStr stri
return ErrCacheFailed return ErrCacheFailed
} }
cacher := session.engine.getCacher(tableName) cacher := session.engine.GetCacher(tableName)
pkColumns := table.PKColumns() pkColumns := table.PKColumns()
ids, err := caches.GetCacheSql(cacher, tableName, newsql, args) ids, err := caches.GetCacheSql(cacher, tableName, newsql, args)
if err != nil { if err != nil {
@ -206,7 +206,7 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
}) })
} }
if cacher := session.engine.getCacher(tableNameNoQuote); cacher != nil && session.statement.UseCache { if cacher := session.engine.GetCacher(tableNameNoQuote); cacher != nil && session.statement.UseCache {
session.cacheDelete(table, tableNameNoQuote, deleteSQL, argsForCache...) session.cacheDelete(table, tableNameNoQuote, deleteSQL, argsForCache...)
} }

View File

@ -183,7 +183,7 @@ func (session *Session) find(rowsSlicePtr interface{}, condiBean ...interface{})
} }
if session.canCache() { if session.canCache() {
if cacher := session.engine.getCacher(session.statement.TableName()); cacher != nil && if cacher := session.engine.GetCacher(session.statement.TableName()); cacher != nil &&
!session.statement.IsDistinct && !session.statement.IsDistinct &&
!session.statement.unscoped { !session.statement.unscoped {
err = session.cacheFind(sliceElementType, sqlStr, rowsSlicePtr, args...) err = session.cacheFind(sliceElementType, sqlStr, rowsSlicePtr, args...)
@ -329,7 +329,7 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
} }
tableName := session.statement.TableName() tableName := session.statement.TableName()
cacher := session.engine.getCacher(tableName) cacher := session.engine.GetCacher(tableName)
if cacher == nil { if cacher == nil {
return nil return nil
} }

View File

@ -65,7 +65,7 @@ func (session *Session) get(bean interface{}) (bool, error) {
table := session.statement.RefTable table := session.statement.RefTable
if session.canCache() && beanValue.Elem().Kind() == reflect.Struct { if session.canCache() && beanValue.Elem().Kind() == reflect.Struct {
if cacher := session.engine.getCacher(session.statement.TableName()); cacher != nil && if cacher := session.engine.GetCacher(session.statement.TableName()); cacher != nil &&
!session.statement.unscoped { !session.statement.unscoped {
has, err := session.cacheGet(bean, sqlStr, args...) has, err := session.cacheGet(bean, sqlStr, args...)
if err != ErrCacheFailed { if err != ErrCacheFailed {
@ -280,7 +280,7 @@ func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interf
} }
tableName := session.statement.TableName() tableName := session.statement.TableName()
cacher := session.engine.getCacher(tableName) cacher := session.engine.GetCacher(tableName)
session.engine.logger.Debug("[cache] Get SQL:", newsql, args) session.engine.logger.Debug("[cache] Get SQL:", newsql, args)
table := session.statement.RefTable table := session.statement.RefTable

View File

@ -613,7 +613,7 @@ func (session *Session) cacheInsert(table string) error {
if !session.statement.UseCache { if !session.statement.UseCache {
return nil return nil
} }
cacher := session.engine.getCacher(table) cacher := session.engine.GetCacher(table)
if cacher == nil { if cacher == nil {
return nil return nil
} }

View File

@ -42,7 +42,7 @@ func (session *Session) cacheUpdate(table *schemas.Table, tableName, sqlStr stri
} }
} }
cacher := session.engine.getCacher(tableName) cacher := session.engine.GetCacher(tableName)
session.engine.logger.Debug("[cacheUpdate] get cache sql", newsql, args[nStart:]) session.engine.logger.Debug("[cacheUpdate] get cache sql", newsql, args[nStart:])
ids, err := caches.GetCacheSql(cacher, tableName, newsql, args[nStart:]) ids, err := caches.GetCacheSql(cacher, tableName, newsql, args[nStart:])
if err != nil { if err != nil {
@ -412,7 +412,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
} }
} }
if cacher := session.engine.getCacher(tableName); cacher != nil && session.statement.UseCache { if cacher := session.engine.GetCacher(tableName); cacher != nil && session.statement.UseCache {
// session.cacheUpdate(table, tableName, sqlStr, args...) // session.cacheUpdate(table, tableName, sqlStr, args...)
session.engine.logger.Debug("[cacheUpdate] clear table ", tableName) session.engine.logger.Debug("[cacheUpdate] clear table ", tableName)
cacher.ClearIds(tableName) cacher.ClearIds(tableName)

View File

@ -68,8 +68,8 @@ func NewEngine(driverName string, dataSourceName string) (*Engine, error) {
TagIdentifier: "xorm", TagIdentifier: "xorm",
TZLocation: time.Local, TZLocation: time.Local,
tagHandlers: defaultTagHandlers, tagHandlers: defaultTagHandlers,
cachers: make(map[string]caches.Cacher),
defaultContext: context.Background(), defaultContext: context.Background(),
cacherMgr: caches.NewManager(),
} }
if uri.DBType == schemas.SQLITE { if uri.DBType == schemas.SQLITE {