From 849874a247eda64e859b5943c9480a8dba558e3e Mon Sep 17 00:00:00 2001 From: John Date: Fri, 9 Oct 2020 20:59:49 +0800 Subject: [PATCH] improve adapter definition for package gcache --- database/gdb/gdb.go | 6 +- database/gdb/gdb_driver_mssql.go | 11 +- database/gdb/gdb_driver_mysql.go | 10 +- database/gdb/gdb_driver_oracle.go | 38 ++- database/gdb/gdb_driver_pgsql.go | 11 +- database/gdb/gdb_driver_sqlite.go | 11 +- database/gdb/gdb_model_select.go | 2 +- debug/gdebug/gdebug_stack.go | 6 + net/ghttp/ghttp_server_router_serve.go | 16 +- os/gcache/gcache.go | 39 ++- os/gcache/gcache_adapter.go | 34 +- os/gcache/gcache_adapter_memory.go | 451 +++++++++++++------------ os/gcache/gcache_cache.go | 23 +- os/gcache/gcache_z_unit_1_test.go | 281 +++++++++------ os/gfile/gfile_cache.go | 4 +- os/gsession/gsession_session.go | 2 +- util/gconv/gconv_z_unit_basic_test.go | 2 +- 17 files changed, 535 insertions(+), 412 deletions(-) diff --git a/database/gdb/gdb.go b/database/gdb/gdb.go index d65f317e1..089a201f4 100644 --- a/database/gdb/gdb.go +++ b/database/gdb/gdb.go @@ -438,11 +438,11 @@ func (c *Core) getSqlDb(master bool, schema ...string) (sqlDb *sql.DB, err error node = &n } // Cache the underlying connection pool object by node. - v := gcache.GetOrSetFuncLock(node.String(), func() interface{} { + v, _ := gcache.GetOrSetFuncLock(node.String(), func() (interface{}, error) { sqlDb, err = c.DB.Open(node) if err != nil { intlog.Printf("DB open failed: %v, %+v", err, node) - return nil + return nil, err } if c.maxIdleConnCount > 0 { sqlDb.SetMaxIdleConns(c.maxIdleConnCount) @@ -461,7 +461,7 @@ func (c *Core) getSqlDb(master bool, schema ...string) (sqlDb *sql.DB, err error } else if node.MaxConnLifetime > 0 { sqlDb.SetConnMaxLifetime(node.MaxConnLifetime * time.Second) } - return sqlDb + return sqlDb, nil }, 0) if v != nil && sqlDb == nil { sqlDb = v.(*sql.DB) diff --git a/database/gdb/gdb_driver_mssql.go b/database/gdb/gdb_driver_mssql.go index 715a21157..a6cfa3d58 100644 --- a/database/gdb/gdb_driver_mssql.go +++ b/database/gdb/gdb_driver_mssql.go @@ -199,15 +199,16 @@ func (d *DriverMssql) TableFields(table string, schema ...string) (fields map[st if len(schema) > 0 && schema[0] != "" { checkSchema = schema[0] } - v := gcache.GetOrSetFunc( - fmt.Sprintf(`mssql_table_fields_%s_%s`, table, checkSchema), func() interface{} { + v, _ := gcache.GetOrSetFunc( + fmt.Sprintf(`mssql_table_fields_%s_%s`, table, checkSchema), + func() (interface{}, error) { var ( result Result link *sql.DB ) link, err = d.DB.GetSlave(checkSchema) if err != nil { - return nil + return nil, err } result, err = d.DB.DoGetAll(link, fmt.Sprintf(` SELECT a.name Field, @@ -234,7 +235,7 @@ func (d *DriverMssql) TableFields(table string, schema ...string) (fields map[st where d.name='%s' order by a.id,a.colorder`, strings.ToUpper(table))) if err != nil { - return nil + return nil, err } fields = make(map[string]*TableField) for i, m := range result { @@ -249,7 +250,7 @@ func (d *DriverMssql) TableFields(table string, schema ...string) (fields map[st Comment: m["Comment"].String(), } } - return fields + return fields, nil }, 0) if err == nil { fields = v.(map[string]*TableField) diff --git a/database/gdb/gdb_driver_mysql.go b/database/gdb/gdb_driver_mysql.go index cce6d4ec9..09050845f 100644 --- a/database/gdb/gdb_driver_mysql.go +++ b/database/gdb/gdb_driver_mysql.go @@ -103,23 +103,23 @@ func (d *DriverMysql) TableFields(table string, schema ...string) (fields map[st if len(schema) > 0 && schema[0] != "" { checkSchema = schema[0] } - v := gcache.GetOrSetFunc( + v, _ := gcache.GetOrSetFunc( fmt.Sprintf(`mysql_table_fields_%s_%s`, table, checkSchema), - func() interface{} { + func() (interface{}, error) { var ( result Result link *sql.DB ) link, err = d.DB.GetSlave(checkSchema) if err != nil { - return nil + return nil, err } result, err = d.DB.DoGetAll( link, fmt.Sprintf(`SHOW FULL COLUMNS FROM %s`, d.DB.QuoteWord(table)), ) if err != nil { - return nil + return nil, err } fields = make(map[string]*TableField) for i, m := range result { @@ -134,7 +134,7 @@ func (d *DriverMysql) TableFields(table string, schema ...string) (fields map[st Comment: m["Comment"].String(), } } - return fields + return fields, nil }, 0) if err == nil { fields = v.(map[string]*TableField) diff --git a/database/gdb/gdb_driver_oracle.go b/database/gdb/gdb_driver_oracle.go index a33c9c89e..ce4754bc7 100644 --- a/database/gdb/gdb_driver_oracle.go +++ b/database/gdb/gdb_driver_oracle.go @@ -159,9 +159,9 @@ func (d *DriverOracle) TableFields(table string, schema ...string) (fields map[s if len(schema) > 0 && schema[0] != "" { checkSchema = schema[0] } - v := gcache.GetOrSetFunc( + v, _ := gcache.GetOrSetFunc( fmt.Sprintf(`oracle_table_fields_%s_%s`, table, checkSchema), - func() interface{} { + func() (interface{}, error) { result := (Result)(nil) result, err = d.DB.GetAll(fmt.Sprintf(` SELECT COLUMN_NAME AS FIELD, CASE DATA_TYPE @@ -170,7 +170,7 @@ func (d *DriverOracle) TableFields(table string, schema ...string) (fields map[s ELSE DATA_TYPE||'('||DATA_LENGTH||')' END AS TYPE FROM USER_TAB_COLUMNS WHERE TABLE_NAME = '%s' ORDER BY COLUMN_ID`, strings.ToUpper(table))) if err != nil { - return nil + return nil, err } fields = make(map[string]*TableField) for i, m := range result { @@ -180,7 +180,7 @@ func (d *DriverOracle) TableFields(table string, schema ...string) (fields map[s Type: strings.ToLower(m["TYPE"].String()), } } - return fields + return fields, nil }, 0) if err == nil { fields = v.(map[string]*TableField) @@ -190,24 +190,26 @@ func (d *DriverOracle) TableFields(table string, schema ...string) (fields map[s func (d *DriverOracle) getTableUniqueIndex(table string) (fields map[string]map[string]string, err error) { table = strings.ToUpper(table) - v := gcache.GetOrSetFunc("table_unique_index_"+table, func() interface{} { - res := (Result)(nil) - res, err = d.DB.GetAll(fmt.Sprintf(` + v, _ := gcache.GetOrSetFunc( + "table_unique_index_"+table, + func() (interface{}, error) { + res := (Result)(nil) + res, err = d.DB.GetAll(fmt.Sprintf(` SELECT INDEX_NAME,COLUMN_NAME,CHAR_LENGTH FROM USER_IND_COLUMNS WHERE TABLE_NAME = '%s' AND INDEX_NAME IN(SELECT INDEX_NAME FROM USER_INDEXES WHERE TABLE_NAME='%s' AND UNIQUENESS='UNIQUE') ORDER BY INDEX_NAME,COLUMN_POSITION`, table, table)) - if err != nil { - return nil - } - fields := make(map[string]map[string]string) - for _, v := range res { - mm := make(map[string]string) - mm[v["COLUMN_NAME"].String()] = v["CHAR_LENGTH"].String() - fields[v["INDEX_NAME"].String()] = mm - } - return fields - }, 0) + if err != nil { + return nil, err + } + fields := make(map[string]map[string]string) + for _, v := range res { + mm := make(map[string]string) + mm[v["COLUMN_NAME"].String()] = v["CHAR_LENGTH"].String() + fields[v["INDEX_NAME"].String()] = mm + } + return fields, nil + }, 0) if err == nil { fields = v.(map[string]map[string]string) } diff --git a/database/gdb/gdb_driver_pgsql.go b/database/gdb/gdb_driver_pgsql.go index 785ea8350..749599239 100644 --- a/database/gdb/gdb_driver_pgsql.go +++ b/database/gdb/gdb_driver_pgsql.go @@ -108,15 +108,16 @@ func (d *DriverPgsql) TableFields(table string, schema ...string) (fields map[st if len(schema) > 0 && schema[0] != "" { checkSchema = schema[0] } - v := gcache.GetOrSetFunc( - fmt.Sprintf(`pgsql_table_fields_%s_%s`, table, checkSchema), func() interface{} { + v, _ := gcache.GetOrSetFunc( + fmt.Sprintf(`pgsql_table_fields_%s_%s`, table, checkSchema), + func() (interface{}, error) { var ( result Result link *sql.DB ) link, err = d.DB.GetSlave(checkSchema) if err != nil { - return nil + return nil, err } result, err = d.DB.DoGetAll(link, fmt.Sprintf(` SELECT a.attname AS field, t.typname AS type FROM pg_class c, pg_attribute a @@ -124,7 +125,7 @@ func (d *DriverPgsql) TableFields(table string, schema ...string) (fields map[st WHERE c.relname = '%s' and a.attnum > 0 and a.attrelid = c.oid and a.atttypid = t.oid ORDER BY a.attnum`, strings.ToLower(table))) if err != nil { - return nil + return nil, err } fields = make(map[string]*TableField) @@ -135,7 +136,7 @@ func (d *DriverPgsql) TableFields(table string, schema ...string) (fields map[st Type: m["type"].String(), } } - return fields + return fields, nil }, 0) if err == nil { fields = v.(map[string]*TableField) diff --git a/database/gdb/gdb_driver_sqlite.go b/database/gdb/gdb_driver_sqlite.go index ba61e0496..17b55fb2f 100644 --- a/database/gdb/gdb_driver_sqlite.go +++ b/database/gdb/gdb_driver_sqlite.go @@ -99,19 +99,20 @@ func (d *DriverSqlite) TableFields(table string, schema ...string) (fields map[s if len(schema) > 0 && schema[0] != "" { checkSchema = schema[0] } - v := gcache.GetOrSetFunc( - fmt.Sprintf(`sqlite_table_fields_%s_%s`, table, checkSchema), func() interface{} { + v, _ := gcache.GetOrSetFunc( + fmt.Sprintf(`sqlite_table_fields_%s_%s`, table, checkSchema), + func() (interface{}, error) { var ( result Result link *sql.DB ) link, err = d.DB.GetSlave(checkSchema) if err != nil { - return nil + return nil, err } result, err = d.DB.DoGetAll(link, fmt.Sprintf(`PRAGMA TABLE_INFO(%s)`, table)) if err != nil { - return nil + return nil, err } fields = make(map[string]*TableField) for i, m := range result { @@ -121,7 +122,7 @@ func (d *DriverSqlite) TableFields(table string, schema ...string) (fields map[s Type: strings.ToLower(m["type"].String()), } } - return fields + return fields, nil }, 0) if err == nil { fields = v.(map[string]*TableField) diff --git a/database/gdb/gdb_model_select.go b/database/gdb/gdb_model_select.go index 55b5e39c0..0e104f933 100644 --- a/database/gdb/gdb_model_select.go +++ b/database/gdb/gdb_model_select.go @@ -439,7 +439,7 @@ func (m *Model) doGetAllBySql(sql string, args ...interface{}) (result Result, e if len(cacheKey) == 0 { cacheKey = sql + ", @PARAMS:" + gconv.String(args) } - if v := cacheObj.GetVar(cacheKey); !v.IsNil() { + if v, _ := cacheObj.GetVar(cacheKey); !v.IsNil() { if result, ok := v.Val().(Result); ok { // In-memory cache. return result, nil diff --git a/debug/gdebug/gdebug_stack.go b/debug/gdebug/gdebug_stack.go index 06d059cd7..522960803 100644 --- a/debug/gdebug/gdebug_stack.go +++ b/debug/gdebug/gdebug_stack.go @@ -9,6 +9,7 @@ package gdebug import ( "bytes" "fmt" + "path/filepath" "runtime" "strings" ) @@ -68,8 +69,13 @@ func StackWithFilters(filters []string, skip ...int) string { file[0:len(goRootForFilter)] == goRootForFilter { continue } + // Custom filtering. filtered = false for _, filter := range filters { + // Ignore test files. + if strings.HasSuffix(filepath.Base(file), "_test.go") { + break + } if filter != "" && strings.Contains(file, filter) { filtered = true break diff --git a/net/ghttp/ghttp_server_router_serve.go b/net/ghttp/ghttp_server_router_serve.go index 135f55e43..6fb39c5ca 100644 --- a/net/ghttp/ghttp_server_router_serve.go +++ b/net/ghttp/ghttp_server_router_serve.go @@ -44,13 +44,15 @@ func (s *Server) getHandlersWithCache(r *Request) (parsedItems []*handlerParsedI } } // Search and cache the router handlers. - value := s.serveCache.GetOrSetFunc(s.serveHandlerKey(method, r.URL.Path, r.GetHost()), func() interface{} { - parsedItems, hasHook, hasServe = s.searchHandlers(method, r.URL.Path, r.GetHost()) - if parsedItems != nil { - return &handlerCacheItem{parsedItems, hasHook, hasServe} - } - return nil - }, gROUTE_CACHE_DURATION) + value, _ := s.serveCache.GetOrSetFunc( + s.serveHandlerKey(method, r.URL.Path, r.GetHost()), + func() (interface{}, error) { + parsedItems, hasHook, hasServe = s.searchHandlers(method, r.URL.Path, r.GetHost()) + if parsedItems != nil { + return &handlerCacheItem{parsedItems, hasHook, hasServe}, nil + } + return nil, nil + }, gROUTE_CACHE_DURATION) if value != nil { item := value.(*handlerCacheItem) return item.parsedItems, item.hasHook, item.hasServe diff --git a/os/gcache/gcache.go b/os/gcache/gcache.go index 1ac20f1a2..fd4dc0f5a 100644 --- a/os/gcache/gcache.go +++ b/os/gcache/gcache.go @@ -13,6 +13,9 @@ import ( "time" ) +// ValueFunc is the function for custom cache value producing. +type ValueFunc func() (value interface{}, err error) + // Default cache object. var defaultCache = New() @@ -24,25 +27,25 @@ func Set(key interface{}, value interface{}, duration time.Duration) { // SetIfNotExist sets cache with - pair if does not exist in the cache, // which is expired after . It does not expire if == 0. -func SetIfNotExist(key interface{}, value interface{}, duration time.Duration) bool { +func SetIfNotExist(key interface{}, value interface{}, duration time.Duration) (bool, error) { return defaultCache.SetIfNotExist(key, value, duration) } // Sets batch sets cache with key-value pairs by , which is expired after . // // It does not expire if == 0. -func Sets(data map[interface{}]interface{}, duration time.Duration) { - defaultCache.Sets(data, duration) +func Sets(data map[interface{}]interface{}, duration time.Duration) error { + return defaultCache.Sets(data, duration) } // Get returns the value of . // It returns nil if it does not exist or its value is nil. -func Get(key interface{}) interface{} { +func Get(key interface{}) (interface{}, error) { return defaultCache.Get(key) } // GetVar retrieves and returns the value of as gvar.Var. -func GetVar(key interface{}) *gvar.Var { +func GetVar(key interface{}) (*gvar.Var, error) { return defaultCache.GetVar(key) } @@ -51,14 +54,14 @@ func GetVar(key interface{}) *gvar.Var { // The key-value pair expires after . // // It does not expire if == 0. -func GetOrSet(key interface{}, value interface{}, duration time.Duration) interface{} { +func GetOrSet(key interface{}, value interface{}, duration time.Duration) (interface{}, error) { return defaultCache.GetOrSet(key, value, duration) } // GetOrSetFunc returns the value of , or sets with result of function // and returns its result if does not exist in the cache. The key-value pair expires // after . It does not expire if == 0. -func GetOrSetFunc(key interface{}, f func() interface{}, duration time.Duration) interface{} { +func GetOrSetFunc(key interface{}, f ValueFunc, duration time.Duration) (interface{}, error) { return defaultCache.GetOrSetFunc(key, f, duration) } @@ -67,18 +70,18 @@ func GetOrSetFunc(key interface{}, f func() interface{}, duration time.Duration) // after . It does not expire if == 0. // // Note that the function is executed within writing mutex lock. -func GetOrSetFuncLock(key interface{}, f func() interface{}, duration time.Duration) interface{} { +func GetOrSetFuncLock(key interface{}, f ValueFunc, duration time.Duration) (interface{}, error) { return defaultCache.GetOrSetFuncLock(key, f, duration) } // Contains returns true if exists in the cache, or else returns false. -func Contains(key interface{}) bool { +func Contains(key interface{}) (bool, error) { return defaultCache.Contains(key) } // Remove deletes the one or more keys from cache, and returns its value. // If multiple keys are given, it returns the value of the deleted last item. -func Remove(keys ...interface{}) (value interface{}) { +func Remove(keys ...interface{}) (value interface{}, err error) { return defaultCache.Remove(keys...) } @@ -89,44 +92,44 @@ func Removes(keys []interface{}) { } // Data returns a copy of all key-value pairs in the cache as map type. -func Data() map[interface{}]interface{} { +func Data() (map[interface{}]interface{}, error) { return defaultCache.Data() } // Keys returns all keys in the cache as slice. -func Keys() []interface{} { +func Keys() ([]interface{}, error) { return defaultCache.Keys() } // KeyStrings returns all keys in the cache as string slice. -func KeyStrings() []string { +func KeyStrings() ([]string, error) { return defaultCache.KeyStrings() } // Values returns all values in the cache as slice. -func Values() []interface{} { +func Values() ([]interface{}, error) { return defaultCache.Values() } // Size returns the size of the cache. -func Size() int { +func Size() (int, error) { return defaultCache.Size() } // GetExpire retrieves and returns the expiration of . // It returns -1 if the does not exist in the cache. -func GetExpire(key interface{}) time.Duration { +func GetExpire(key interface{}) (time.Duration, error) { return defaultCache.GetExpire(key) } // Update updates the value of without changing its expiration and returns the old value. // The returned value is false if the does not exist in the cache. -func Update(key interface{}, value interface{}) (oldValue interface{}, exist bool) { +func Update(key interface{}, value interface{}) (oldValue interface{}, exist bool, err error) { return defaultCache.Update(key, value) } // UpdateExpire updates the expiration of and returns the old expiration duration value. // It returns -1 if the does not exist in the cache. -func UpdateExpire(key interface{}, duration time.Duration) (oldDuration time.Duration) { +func UpdateExpire(key interface{}, duration time.Duration) (oldDuration time.Duration, err error) { return defaultCache.UpdateExpire(key, duration) } diff --git a/os/gcache/gcache_adapter.go b/os/gcache/gcache_adapter.go index 37f829026..28a022895 100644 --- a/os/gcache/gcache_adapter.go +++ b/os/gcache/gcache_adapter.go @@ -11,19 +11,18 @@ import ( ) // Adapter is the adapter for cache features implements. -// TODO Adding error returning for each function for preciseness. type Adapter interface { // Set sets cache with - pair, which is expired after . // // It does not expire if == 0. // It deletes the if < 0. - Set(key interface{}, value interface{}, duration time.Duration) + Set(key interface{}, value interface{}, duration time.Duration) error // Sets batch sets cache with key-value pairs by , which is expired after . // // It does not expire if == 0. // It deletes the keys of if < 0 or given is nil. - Sets(data map[interface{}]interface{}, duration time.Duration) + Sets(data map[interface{}]interface{}, duration time.Duration) error // SetIfNotExist sets cache with - pair which is expired after // if does not exist in the cache. It returns true the dose not exist in the @@ -34,11 +33,11 @@ type Adapter interface { // // It does not expire if == 0. // It deletes the if < 0 or given is nil. - SetIfNotExist(key interface{}, value interface{}, duration time.Duration) bool + SetIfNotExist(key interface{}, value interface{}, duration time.Duration) (bool, error) // Get retrieves and returns the associated value of given . // It returns nil if it does not exist or its value is nil. - Get(key interface{}) interface{} + Get(key interface{}) (interface{}, error) // GetOrSet retrieves and returns the value of , or sets - pair and // returns if does not exist in the cache. The key-value pair expires @@ -47,7 +46,7 @@ type Adapter interface { // It does not expire if == 0. // It deletes the if < 0 or given is nil, but it does nothing // if is a function and the function result is nil. - GetOrSet(key interface{}, value interface{}, duration time.Duration) interface{} + GetOrSet(key interface{}, value interface{}, duration time.Duration) (interface{}, error) // GetOrSetFunc retrieves and returns the value of , or sets with result of // function and returns its result if does not exist in the cache. The key-value @@ -56,7 +55,7 @@ type Adapter interface { // It does not expire if == 0. // It deletes the if < 0 or given is nil, but it does nothing // if is a function and the function result is nil. - GetOrSetFunc(key interface{}, f func() interface{}, duration time.Duration) interface{} + GetOrSetFunc(key interface{}, f ValueFunc, duration time.Duration) (interface{}, error) // GetOrSetFuncLock retrieves and returns the value of , or sets with result of // function and returns its result if does not exist in the cache. The key-value @@ -67,44 +66,47 @@ type Adapter interface { // // Note that the function should be executed within writing mutex lock for concurrent // safety purpose. - GetOrSetFuncLock(key interface{}, f func() interface{}, duration time.Duration) interface{} + GetOrSetFuncLock(key interface{}, f ValueFunc, duration time.Duration) (interface{}, error) + + // Contains returns true if exists in the cache, or else returns false. + Contains(key interface{}) (bool, error) // GetExpire retrieves and returns the expiration of in the cache. // // It returns 0 if the does not expire. // It returns -1 if the does not exist in the cache. - GetExpire(key interface{}) time.Duration + GetExpire(key interface{}) (time.Duration, error) // Remove deletes one or more keys from cache, and returns its value. // If multiple keys are given, it returns the value of the last deleted item. - Remove(keys ...interface{}) (value interface{}) + Remove(keys ...interface{}) (value interface{}, err error) // Update updates the value of without changing its expiration and returns the old value. // The returned value is false if the does not exist in the cache. // // It deletes the if given is nil. // It does nothing if does not exist in the cache. - Update(key interface{}, value interface{}) (oldValue interface{}, exist bool) + Update(key interface{}, value interface{}) (oldValue interface{}, exist bool, err error) // UpdateExpire updates the expiration of and returns the old expiration duration value. // // It returns -1 and does nothing if the does not exist in the cache. // It deletes the if < 0. - UpdateExpire(key interface{}, duration time.Duration) (oldDuration time.Duration) + UpdateExpire(key interface{}, duration time.Duration) (oldDuration time.Duration, err error) // Size returns the number of items in the cache. - Size() (size int) + Size() (size int, err error) // Data returns a copy of all key-value pairs in the cache as map type. // Note that this function may leads lots of memory usage, you can implement this function // if necessary. - Data() map[interface{}]interface{} + Data() (map[interface{}]interface{}, error) // Keys returns all keys in the cache as slice. - Keys() []interface{} + Keys() ([]interface{}, error) // Values returns all values in the cache as slice. - Values() []interface{} + Values() ([]interface{}, error) // Clear clears all data of the cache. // Note that this function is sensitive and should be carefully used. diff --git a/os/gcache/gcache_adapter_memory.go b/os/gcache/gcache_adapter_memory.go index f74165363..2eb7e9a5d 100644 --- a/os/gcache/gcache_adapter_memory.go +++ b/os/gcache/gcache_adapter_memory.go @@ -98,7 +98,7 @@ func newAdapterMemory(lruCap ...int) *adapterMemory { // // It does not expire if == 0. // It deletes the if < 0. -func (c *adapterMemory) Set(key interface{}, value interface{}, duration time.Duration) { +func (c *adapterMemory) Set(key interface{}, value interface{}, duration time.Duration) error { expireTime := c.getInternalExpire(duration) c.dataMu.Lock() c.data[key] = adapterMemoryItem{ @@ -110,6 +110,7 @@ func (c *adapterMemory) Set(key interface{}, value interface{}, duration time.Du k: key, e: expireTime, }) + return nil } // Update updates the value of without changing its expiration and returns the old value. @@ -117,7 +118,7 @@ func (c *adapterMemory) Set(key interface{}, value interface{}, duration time.Du // // It deletes the if given is nil. // It does nothing if does not exist in the cache. -func (c *adapterMemory) Update(key interface{}, value interface{}) (oldValue interface{}, exist bool) { +func (c *adapterMemory) Update(key interface{}, value interface{}) (oldValue interface{}, exist bool, err error) { c.dataMu.Lock() defer c.dataMu.Unlock() if item, ok := c.data[key]; ok { @@ -125,16 +126,16 @@ func (c *adapterMemory) Update(key interface{}, value interface{}) (oldValue int v: value, e: item.e, } - return item.v, true + return item.v, true, nil } - return nil, false + return nil, false, nil } // UpdateExpire updates the expiration of and returns the old expiration duration value. // // It returns -1 and does nothing if the does not exist in the cache. // It deletes the if < 0. -func (c *adapterMemory) UpdateExpire(key interface{}, duration time.Duration) (oldDuration time.Duration) { +func (c *adapterMemory) UpdateExpire(key interface{}, duration time.Duration) (oldDuration time.Duration, err error) { newExpireTime := c.getInternalExpire(duration) c.dataMu.Lock() defer c.dataMu.Unlock() @@ -147,22 +148,241 @@ func (c *adapterMemory) UpdateExpire(key interface{}, duration time.Duration) (o k: key, e: newExpireTime, }) - return time.Duration(item.e-gtime.TimestampMilli()) * time.Millisecond + return time.Duration(item.e-gtime.TimestampMilli()) * time.Millisecond, nil } - return -1 + return -1, nil } // GetExpire retrieves and returns the expiration of in the cache. // // It returns 0 if the does not expire. // It returns -1 if the does not exist in the cache. -func (c *adapterMemory) GetExpire(key interface{}) time.Duration { +func (c *adapterMemory) GetExpire(key interface{}) (time.Duration, error) { c.dataMu.RLock() defer c.dataMu.RUnlock() if item, ok := c.data[key]; ok { - return time.Duration(item.e-gtime.TimestampMilli()) * time.Millisecond + return time.Duration(item.e-gtime.TimestampMilli()) * time.Millisecond, nil } - return -1 + return -1, nil +} + +// SetIfNotExist sets cache with - pair which is expired after +// if does not exist in the cache. It returns true the dose not exist in the +// cache and it sets successfully to the cache, or else it returns false. +// The parameter can be type of , but it dose nothing if its +// result is nil. +// +// It does not expire if == 0. +// It deletes the if < 0 or given is nil. +func (c *adapterMemory) SetIfNotExist(key interface{}, value interface{}, duration time.Duration) (bool, error) { + isContained, err := c.Contains(key) + if err != nil { + return false, err + } + if !isContained { + _, err := c.doSetWithLockCheck(key, value, duration) + if err != nil { + return false, err + } + return true, nil + } + return false, nil +} + +// Sets batch sets cache with key-value pairs by , which is expired after . +// +// It does not expire if == 0. +// It deletes the keys of if < 0 or given is nil. +func (c *adapterMemory) Sets(data map[interface{}]interface{}, duration time.Duration) error { + expireTime := c.getInternalExpire(duration) + for k, v := range data { + c.dataMu.Lock() + c.data[k] = adapterMemoryItem{ + v: v, + e: expireTime, + } + c.dataMu.Unlock() + c.eventList.PushBack(&adapterMemoryEvent{ + k: k, + e: expireTime, + }) + } + return nil +} + +// Get retrieves and returns the associated value of given . +// It returns nil if it does not exist or its value is nil. +func (c *adapterMemory) Get(key interface{}) (interface{}, error) { + c.dataMu.RLock() + item, ok := c.data[key] + c.dataMu.RUnlock() + if ok && !item.IsExpired() { + // Adding to LRU history if LRU feature is enabled. + if c.cap > 0 { + c.lruGetList.PushBack(key) + } + return item.v, nil + } + return nil, nil +} + +// GetOrSet retrieves and returns the value of , or sets - pair and +// returns if does not exist in the cache. The key-value pair expires +// after . +// +// It does not expire if == 0. +// It deletes the if < 0 or given is nil, but it does nothing +// if is a function and the function result is nil. +func (c *adapterMemory) GetOrSet(key interface{}, value interface{}, duration time.Duration) (interface{}, error) { + v, err := c.Get(key) + if err != nil { + return nil, err + } + if v == nil { + return c.doSetWithLockCheck(key, value, duration) + } else { + return v, nil + } +} + +// GetOrSetFunc retrieves and returns the value of , or sets with result of +// function and returns its result if does not exist in the cache. The key-value +// pair expires after . +// +// It does not expire if == 0. +// It deletes the if < 0 or given is nil, but it does nothing +// if is a function and the function result is nil. +func (c *adapterMemory) GetOrSetFunc(key interface{}, f ValueFunc, duration time.Duration) (interface{}, error) { + v, err := c.Get(key) + if err != nil { + return nil, err + } + if v == nil { + value, err := f() + if err != nil { + return nil, err + } + if value == nil { + return nil, nil + } + return c.doSetWithLockCheck(key, value, duration) + } else { + return v, nil + } +} + +// GetOrSetFuncLock retrieves and returns the value of , or sets with result of +// function and returns its result if does not exist in the cache. The key-value +// pair expires after . +// +// It does not expire if == 0. +// It does nothing if function returns nil. +// +// Note that the function should be executed within writing mutex lock for concurrent +// safety purpose. +func (c *adapterMemory) GetOrSetFuncLock(key interface{}, f ValueFunc, duration time.Duration) (interface{}, error) { + v, err := c.Get(key) + if err != nil { + return nil, err + } + if v == nil { + return c.doSetWithLockCheck(key, f, duration) + } else { + return v, nil + } +} + +// Contains returns true if exists in the cache, or else returns false. +func (c *adapterMemory) Contains(key interface{}) (bool, error) { + v, err := c.Get(key) + if err != nil { + return false, err + } + return v != nil, nil +} + +// Remove deletes the one or more keys from cache, and returns its value. +// If multiple keys are given, it returns the value of the deleted last item. +func (c *adapterMemory) Remove(keys ...interface{}) (value interface{}, err error) { + c.dataMu.Lock() + defer c.dataMu.Unlock() + for _, key := range keys { + item, ok := c.data[key] + if ok { + value = item.v + delete(c.data, key) + c.eventList.PushBack(&adapterMemoryEvent{ + k: key, + e: gtime.TimestampMilli() - 1000, + }) + } + } + return value, nil +} + +// Data returns a copy of all key-value pairs in the cache as map type. +func (c *adapterMemory) Data() (map[interface{}]interface{}, error) { + m := make(map[interface{}]interface{}) + c.dataMu.RLock() + for k, v := range c.data { + if !v.IsExpired() { + m[k] = v.v + } + } + c.dataMu.RUnlock() + return m, nil +} + +// Keys returns all keys in the cache as slice. +func (c *adapterMemory) Keys() ([]interface{}, error) { + keys := make([]interface{}, 0) + c.dataMu.RLock() + for k, v := range c.data { + if !v.IsExpired() { + keys = append(keys, k) + } + } + c.dataMu.RUnlock() + return keys, nil +} + +// Values returns all values in the cache as slice. +func (c *adapterMemory) Values() ([]interface{}, error) { + values := make([]interface{}, 0) + c.dataMu.RLock() + for _, v := range c.data { + if !v.IsExpired() { + values = append(values, v.v) + } + } + c.dataMu.RUnlock() + return values, nil +} + +// Size returns the size of the cache. +func (c *adapterMemory) Size() (size int, err error) { + c.dataMu.RLock() + size = len(c.data) + c.dataMu.RUnlock() + return size, nil +} + +// Clear clears all data of the cache. +// Note that this function is sensitive and should be carefully used. +func (c *adapterMemory) Clear() error { + c.dataMu.Lock() + defer c.dataMu.Unlock() + c.data = make(map[interface{}]adapterMemoryItem) + return nil +} + +// Close closes the cache. +func (c *adapterMemory) Close() error { + if c.cap > 0 { + c.lru.Close() + } + c.closed.Set(true) + return nil } // doSetWithLockCheck sets cache with - pair if does not exist in the @@ -174,22 +394,27 @@ func (c *adapterMemory) GetExpire(key interface{}) time.Duration { // // It doubly checks the whether exists in the cache using mutex writing lock // before setting it to the cache. -func (c *adapterMemory) doSetWithLockCheck(key interface{}, value interface{}, duration time.Duration) interface{} { +func (c *adapterMemory) doSetWithLockCheck(key interface{}, value interface{}, duration time.Duration) (interface{}, error) { expireTimestamp := c.getInternalExpire(duration) c.dataMu.Lock() defer c.dataMu.Unlock() if v, ok := c.data[key]; ok && !v.IsExpired() { - return v.v + return v.v, nil } - if f, ok := value.(func() interface{}); ok { - value = f() - if value == nil { - return nil + if f, ok := value.(ValueFunc); ok { + v, err := f() + if err != nil { + return nil, err + } + if v == nil { + return nil, nil + } else { + value = v } } c.data[key] = adapterMemoryItem{v: value, e: expireTimestamp} c.eventList.PushBack(&adapterMemoryEvent{k: key, e: expireTimestamp}) - return value + return value, nil } // getInternalExpire converts and returns the expire time with given expired duration in milliseconds. @@ -230,198 +455,6 @@ func (c *adapterMemory) getOrNewExpireSet(expire int64) (expireSet *gset.Set) { return } -// SetIfNotExist sets cache with - pair which is expired after -// if does not exist in the cache. It returns true the dose not exist in the -// cache and it sets successfully to the cache, or else it returns false. -// The parameter can be type of , but it dose nothing if its -// result is nil. -// -// It does not expire if == 0. -// It deletes the if < 0 or given is nil. -func (c *adapterMemory) SetIfNotExist(key interface{}, value interface{}, duration time.Duration) bool { - if !c.Contains(key) { - c.doSetWithLockCheck(key, value, duration) - return true - } - return false -} - -// Sets batch sets cache with key-value pairs by , which is expired after . -// -// It does not expire if == 0. -// It deletes the keys of if < 0 or given is nil. -func (c *adapterMemory) Sets(data map[interface{}]interface{}, duration time.Duration) { - expireTime := c.getInternalExpire(duration) - for k, v := range data { - c.dataMu.Lock() - c.data[k] = adapterMemoryItem{ - v: v, - e: expireTime, - } - c.dataMu.Unlock() - c.eventList.PushBack(&adapterMemoryEvent{ - k: k, - e: expireTime, - }) - } -} - -// Get retrieves and returns the associated value of given . -// It returns nil if it does not exist or its value is nil. -func (c *adapterMemory) Get(key interface{}) interface{} { - c.dataMu.RLock() - item, ok := c.data[key] - c.dataMu.RUnlock() - if ok && !item.IsExpired() { - // Adding to LRU history if LRU feature is enabled. - if c.cap > 0 { - c.lruGetList.PushBack(key) - } - return item.v - } - return nil -} - -// GetOrSet retrieves and returns the value of , or sets - pair and -// returns if does not exist in the cache. The key-value pair expires -// after . -// -// It does not expire if == 0. -// It deletes the if < 0 or given is nil, but it does nothing -// if is a function and the function result is nil. -func (c *adapterMemory) GetOrSet(key interface{}, value interface{}, duration time.Duration) interface{} { - if v := c.Get(key); v == nil { - return c.doSetWithLockCheck(key, value, duration) - } else { - return v - } -} - -// GetOrSetFunc retrieves and returns the value of , or sets with result of -// function and returns its result if does not exist in the cache. The key-value -// pair expires after . -// -// It does not expire if == 0. -// It deletes the if < 0 or given is nil, but it does nothing -// if is a function and the function result is nil. -func (c *adapterMemory) GetOrSetFunc(key interface{}, f func() interface{}, duration time.Duration) interface{} { - if v := c.Get(key); v == nil { - value := f() - if value == nil { - return nil - } - return c.doSetWithLockCheck(key, value, duration) - } else { - return v - } -} - -// GetOrSetFuncLock retrieves and returns the value of , or sets with result of -// function and returns its result if does not exist in the cache. The key-value -// pair expires after . -// -// It does not expire if == 0. -// It does nothing if function returns nil. -// -// Note that the function should be executed within writing mutex lock for concurrent -// safety purpose. -func (c *adapterMemory) GetOrSetFuncLock(key interface{}, f func() interface{}, duration time.Duration) interface{} { - if v := c.Get(key); v == nil { - return c.doSetWithLockCheck(key, f, duration) - } else { - return v - } -} - -// Contains returns true if exists in the cache, or else returns false. -func (c *adapterMemory) Contains(key interface{}) bool { - return c.Get(key) != nil -} - -// Remove deletes the one or more keys from cache, and returns its value. -// If multiple keys are given, it returns the value of the deleted last item. -func (c *adapterMemory) Remove(keys ...interface{}) (value interface{}) { - c.dataMu.Lock() - defer c.dataMu.Unlock() - for _, key := range keys { - item, ok := c.data[key] - if ok { - value = item.v - delete(c.data, key) - c.eventList.PushBack(&adapterMemoryEvent{ - k: key, - e: gtime.TimestampMilli() - 1000, - }) - } - } - return -} - -// Data returns a copy of all key-value pairs in the cache as map type. -func (c *adapterMemory) Data() map[interface{}]interface{} { - m := make(map[interface{}]interface{}) - c.dataMu.RLock() - for k, v := range c.data { - if !v.IsExpired() { - m[k] = v.v - } - } - c.dataMu.RUnlock() - return m -} - -// Keys returns all keys in the cache as slice. -func (c *adapterMemory) Keys() []interface{} { - keys := make([]interface{}, 0) - c.dataMu.RLock() - for k, v := range c.data { - if !v.IsExpired() { - keys = append(keys, k) - } - } - c.dataMu.RUnlock() - return keys -} - -// Values returns all values in the cache as slice. -func (c *adapterMemory) Values() []interface{} { - values := make([]interface{}, 0) - c.dataMu.RLock() - for _, v := range c.data { - if !v.IsExpired() { - values = append(values, v.v) - } - } - c.dataMu.RUnlock() - return values -} - -// Size returns the size of the cache. -func (c *adapterMemory) Size() (size int) { - c.dataMu.RLock() - size = len(c.data) - c.dataMu.RUnlock() - return -} - -// Clear clears all data of the cache. -// Note that this function is sensitive and should be carefully used. -func (c *adapterMemory) Clear() error { - c.dataMu.Lock() - defer c.dataMu.Unlock() - c.data = make(map[interface{}]adapterMemoryItem) - return nil -} - -// Close closes the cache. -func (c *adapterMemory) Close() error { - if c.cap > 0 { - c.lru.Close() - } - c.closed.Set(true) - return nil -} - // syncEventAndClearExpired does the asynchronous task loop: // 1. Asynchronously process the data in the event list, // and synchronize the results to the and properties. diff --git a/os/gcache/gcache_cache.go b/os/gcache/gcache_cache.go index 7151fd9f4..5c80c9a2e 100644 --- a/os/gcache/gcache_cache.go +++ b/os/gcache/gcache_cache.go @@ -38,23 +38,24 @@ func (c *Cache) SetAdapter(adapter Adapter) { c.Adapter = adapter } -// Contains returns true if exists in the cache, or else returns false. -func (c *Cache) Contains(key interface{}) bool { - return c.Get(key) != nil -} - // GetVar retrieves and returns the value of as gvar.Var. -func (c *Cache) GetVar(key interface{}) *gvar.Var { - return gvar.New(c.Get(key)) +func (c *Cache) GetVar(key interface{}) (*gvar.Var, error) { + v, err := c.Get(key) + return gvar.New(v), err } // Removes deletes in the cache. // Deprecated, use Remove instead. -func (c *Cache) Removes(keys []interface{}) { - c.Remove(keys...) +func (c *Cache) Removes(keys []interface{}) error { + _, err := c.Remove(keys...) + return err } // KeyStrings returns all keys in the cache as string slice. -func (c *Cache) KeyStrings() []string { - return gconv.Strings(c.Keys()) +func (c *Cache) KeyStrings() ([]string, error) { + keys, err := c.Keys() + if err != nil { + return nil, err + } + return gconv.Strings(keys), nil } diff --git a/os/gcache/gcache_z_unit_1_test.go b/os/gcache/gcache_z_unit_1_test.go index 54620423c..459800a91 100644 --- a/os/gcache/gcache_z_unit_1_test.go +++ b/os/gcache/gcache_z_unit_1_test.go @@ -25,8 +25,10 @@ func TestCache_GCache_Set(t *testing.T) { gtest.C(t, func(t *gtest.T) { gcache.Set(1, 11, 0) defer gcache.Removes(g.Slice{1, 2, 3}) - t.Assert(gcache.Get(1), 11) - t.Assert(gcache.Contains(1), true) + v, _ := gcache.Get(1) + t.Assert(v, 11) + b, _ := gcache.Contains(1) + t.Assert(b, true) }) } @@ -34,44 +36,57 @@ func TestCache_Set(t *testing.T) { gtest.C(t, func(t *gtest.T) { c := gcache.New() defer c.Close() - c.Set(1, 11, 0) - t.Assert(c.Get(1), 11) - t.Assert(c.Contains(1), true) + t.Assert(c.Set(1, 11, 0), nil) + v, _ := c.Get(1) + t.Assert(v, 11) + b, _ := c.Contains(1) + t.Assert(b, true) }) } func TestCache_GetVar(t *testing.T) { + c := gcache.New() + defer c.Close() gtest.C(t, func(t *gtest.T) { - c := gcache.New() - defer c.Close() - c.Set(1, 11, 0) - t.Assert(c.Get(1), 11) - t.Assert(c.Contains(1), true) - t.Assert(c.GetVar(1).Int(), 11) - t.Assert(c.GetVar(2).Int(), 0) - t.Assert(c.GetVar(2).IsNil(), true) - t.Assert(c.GetVar(2).IsEmpty(), true) + t.Assert(c.Set(1, 11, 0), nil) + v, _ := c.Get(1) + t.Assert(v, 11) + b, _ := c.Contains(1) + t.Assert(b, true) + }) + gtest.C(t, func(t *gtest.T) { + v, _ := c.GetVar(1) + t.Assert(v.Int(), 11) + v, _ = c.GetVar(2) + t.Assert(v.Int(), 0) + t.Assert(v.IsNil(), true) + t.Assert(v.IsEmpty(), true) }) } func TestCache_Set_Expire(t *testing.T) { gtest.C(t, func(t *gtest.T) { cache := gcache.New() - cache.Set(2, 22, 100*time.Millisecond) - t.Assert(cache.Get(2), 22) + t.Assert(cache.Set(2, 22, 100*time.Millisecond), nil) + v, _ := cache.Get(2) + t.Assert(v, 22) time.Sleep(200 * time.Millisecond) - t.Assert(cache.Get(2), nil) + v, _ = cache.Get(2) + t.Assert(v, nil) time.Sleep(3 * time.Second) - t.Assert(cache.Size(), 0) - cache.Close() + n, _ := cache.Size() + t.Assert(n, 0) + t.Assert(cache.Close(), nil) }) gtest.C(t, func(t *gtest.T) { cache := gcache.New() - cache.Set(1, 11, 100*time.Millisecond) - t.Assert(cache.Get(1), 11) + t.Assert(cache.Set(1, 11, 100*time.Millisecond), nil) + v, _ := cache.Get(1) + t.Assert(v, 11) time.Sleep(200 * time.Millisecond) - t.Assert(cache.Get(1), nil) + v, _ = cache.Get(1) + t.Assert(v, nil) }) } @@ -80,20 +95,22 @@ func TestCache_Update_GetExpire(t *testing.T) { gtest.C(t, func(t *gtest.T) { key := guid.S() gcache.Set(key, 11, 3*time.Second) - expire1 := gcache.GetExpire(key) + expire1, _ := gcache.GetExpire(key) gcache.Update(key, 12) - expire2 := gcache.GetExpire(key) - t.Assert(gcache.GetVar(key), 12) + expire2, _ := gcache.GetExpire(key) + v, _ := gcache.GetVar(key) + t.Assert(v, 12) t.Assert(math.Ceil(expire1.Seconds()), math.Ceil(expire2.Seconds())) }) // gcache.Cache gtest.C(t, func(t *gtest.T) { cache := gcache.New() cache.Set(1, 11, 3*time.Second) - expire1 := cache.GetExpire(1) + expire1, _ := cache.GetExpire(1) cache.Update(1, 12) - expire2 := cache.GetExpire(1) - t.Assert(cache.GetVar(1), 12) + expire2, _ := cache.GetExpire(1) + v, _ := cache.GetVar(1) + t.Assert(v, 12) t.Assert(math.Ceil(expire1.Seconds()), math.Ceil(expire2.Seconds())) }) } @@ -104,34 +121,43 @@ func TestCache_UpdateExpire(t *testing.T) { key := guid.S() gcache.Set(key, 11, 3*time.Second) defer gcache.Remove(key) - oldExpire := gcache.GetExpire(key) + oldExpire, _ := gcache.GetExpire(key) newExpire := 10 * time.Second gcache.UpdateExpire(key, newExpire) - t.AssertNE(gcache.GetExpire(key), oldExpire) - t.Assert(math.Ceil(gcache.GetExpire(key).Seconds()), 10) + e, _ := gcache.GetExpire(key) + t.AssertNE(e, oldExpire) + e, _ = gcache.GetExpire(key) + t.Assert(math.Ceil(e.Seconds()), 10) }) // gcache.Cache gtest.C(t, func(t *gtest.T) { cache := gcache.New() cache.Set(1, 11, 3*time.Second) - oldExpire := cache.GetExpire(1) + oldExpire, _ := cache.GetExpire(1) newExpire := 10 * time.Second cache.UpdateExpire(1, newExpire) - t.AssertNE(cache.GetExpire(1), oldExpire) - t.Assert(math.Ceil(cache.GetExpire(1).Seconds()), 10) + e, _ := cache.GetExpire(1) + t.AssertNE(e, oldExpire) + + e, _ = cache.GetExpire(1) + t.Assert(math.Ceil(e.Seconds()), 10) }) } func TestCache_Keys_Values(t *testing.T) { gtest.C(t, func(t *gtest.T) { - cache := gcache.New() + c := gcache.New() for i := 0; i < 10; i++ { - cache.Set(i, i*10, 0) + t.Assert(c.Set(i, i*10, 0), nil) } - t.Assert(len(cache.Keys()), 10) - t.Assert(len(cache.Values()), 10) - t.AssertIN(0, cache.Keys()) - t.AssertIN(90, cache.Values()) + var ( + keys, _ = c.Keys() + values, _ = c.Values() + ) + t.Assert(len(keys), 10) + t.Assert(len(values), 10) + t.AssertIN(0, keys) + t.AssertIN(90, values) }) } @@ -141,22 +167,30 @@ func TestCache_LRU(t *testing.T) { for i := 0; i < 10; i++ { cache.Set(i, i, 0) } - t.Assert(cache.Size(), 10) - t.Assert(cache.Get(6), 6) + n, _ := cache.Size() + t.Assert(n, 10) + v, _ := cache.Get(6) + t.Assert(v, 6) time.Sleep(4 * time.Second) - t.Assert(cache.Size(), 2) - t.Assert(cache.Get(6), 6) - t.Assert(cache.Get(1), nil) - cache.Close() + n, _ = cache.Size() + t.Assert(n, 2) + v, _ = cache.Get(6) + t.Assert(v, 6) + v, _ = cache.Get(1) + t.Assert(v, nil) + t.Assert(cache.Close(), nil) }) } func TestCache_LRU_expire(t *testing.T) { gtest.C(t, func(t *gtest.T) { cache := gcache.New(2) - cache.Set(1, nil, 1000) - t.Assert(cache.Size(), 1) - t.Assert(cache.Get(1), nil) + t.Assert(cache.Set(1, nil, 1000), nil) + n, _ := cache.Size() + t.Assert(n, 1) + v, _ := cache.Get(1) + + t.Assert(v, nil) }) } @@ -164,17 +198,22 @@ func TestCache_SetIfNotExist(t *testing.T) { gtest.C(t, func(t *gtest.T) { cache := gcache.New() cache.SetIfNotExist(1, 11, 0) - t.Assert(cache.Get(1), 11) + v, _ := cache.Get(1) + t.Assert(v, 11) cache.SetIfNotExist(1, 22, 0) - t.Assert(cache.Get(1), 11) + v, _ = cache.Get(1) + t.Assert(v, 11) cache.SetIfNotExist(2, 22, 0) - t.Assert(cache.Get(2), 22) + v, _ = cache.Get(2) + t.Assert(v, 22) gcache.Removes(g.Slice{1, 2, 3}) gcache.SetIfNotExist(1, 11, 0) - t.Assert(gcache.Get(1), 11) + v, _ = gcache.Get(1) + t.Assert(v, 11) gcache.SetIfNotExist(1, 22, 0) - t.Assert(gcache.Get(1), 11) + v, _ = gcache.Get(1) + t.Assert(v, 11) }) } @@ -182,11 +221,13 @@ func TestCache_Sets(t *testing.T) { gtest.C(t, func(t *gtest.T) { cache := gcache.New() cache.Sets(g.MapAnyAny{1: 11, 2: 22}, 0) - t.Assert(cache.Get(1), 11) + v, _ := cache.Get(1) + t.Assert(v, 11) gcache.Removes(g.Slice{1, 2, 3}) gcache.Sets(g.MapAnyAny{1: 11, 2: 22}, 0) - t.Assert(gcache.Get(1), 11) + v, _ = cache.Get(1) + t.Assert(v, 11) }) } @@ -194,63 +235,82 @@ func TestCache_GetOrSet(t *testing.T) { gtest.C(t, func(t *gtest.T) { cache := gcache.New() cache.GetOrSet(1, 11, 0) - t.Assert(cache.Get(1), 11) + v, _ := cache.Get(1) + t.Assert(v, 11) cache.GetOrSet(1, 111, 0) - t.Assert(cache.Get(1), 11) + v, _ = cache.Get(1) + t.Assert(v, 11) gcache.Removes(g.Slice{1, 2, 3}) gcache.GetOrSet(1, 11, 0) - t.Assert(gcache.Get(1), 11) + + v, _ = cache.Get(1) + t.Assert(v, 11) + gcache.GetOrSet(1, 111, 0) - t.Assert(gcache.Get(1), 11) + v, _ = cache.Get(1) + t.Assert(v, 11) }) } func TestCache_GetOrSetFunc(t *testing.T) { gtest.C(t, func(t *gtest.T) { cache := gcache.New() - cache.GetOrSetFunc(1, func() interface{} { - return 11 + cache.GetOrSetFunc(1, func() (interface{}, error) { + return 11, nil }, 0) - t.Assert(cache.Get(1), 11) - cache.GetOrSetFunc(1, func() interface{} { - return 111 + v, _ := cache.Get(1) + t.Assert(v, 11) + + cache.GetOrSetFunc(1, func() (interface{}, error) { + return 111, nil }, 0) - t.Assert(cache.Get(1), 11) + v, _ = cache.Get(1) + t.Assert(v, 11) gcache.Removes(g.Slice{1, 2, 3}) - gcache.GetOrSetFunc(1, func() interface{} { - return 11 + + gcache.GetOrSetFunc(1, func() (interface{}, error) { + return 11, nil }, 0) - t.Assert(gcache.Get(1), 11) - gcache.GetOrSetFunc(1, func() interface{} { - return 111 + v, _ = cache.Get(1) + t.Assert(v, 11) + + gcache.GetOrSetFunc(1, func() (interface{}, error) { + return 111, nil }, 0) - t.Assert(gcache.Get(1), 11) + v, _ = cache.Get(1) + t.Assert(v, 11) }) } func TestCache_GetOrSetFuncLock(t *testing.T) { gtest.C(t, func(t *gtest.T) { cache := gcache.New() - cache.GetOrSetFuncLock(1, func() interface{} { - return 11 + cache.GetOrSetFuncLock(1, func() (interface{}, error) { + return 11, nil }, 0) - t.Assert(cache.Get(1), 11) - cache.GetOrSetFuncLock(1, func() interface{} { - return 111 + v, _ := cache.Get(1) + t.Assert(v, 11) + + cache.GetOrSetFuncLock(1, func() (interface{}, error) { + return 111, nil }, 0) - t.Assert(cache.Get(1), 11) + v, _ = cache.Get(1) + t.Assert(v, 11) gcache.Removes(g.Slice{1, 2, 3}) - gcache.GetOrSetFuncLock(1, func() interface{} { - return 11 + gcache.GetOrSetFuncLock(1, func() (interface{}, error) { + return 11, nil }, 0) - t.Assert(gcache.Get(1), 11) - gcache.GetOrSetFuncLock(1, func() interface{} { - return 111 + v, _ = cache.Get(1) + t.Assert(v, 11) + + gcache.GetOrSetFuncLock(1, func() (interface{}, error) { + return 111, nil }, 0) - t.Assert(gcache.Get(1), 11) + v, _ = cache.Get(1) + t.Assert(v, 11) }) } @@ -259,7 +319,8 @@ func TestCache_Clear(t *testing.T) { cache := gcache.New() cache.Sets(g.MapAnyAny{1: 11, 2: 22}, 0) cache.Clear() - t.Assert(cache.Size(), 0) + n, _ := cache.Size() + t.Assert(n, 0) }) } @@ -298,47 +359,57 @@ func TestCache_Basic(t *testing.T) { { cache := gcache.New() cache.Sets(g.MapAnyAny{1: 11, 2: 22}, 0) - t.Assert(cache.Contains(1), true) - t.Assert(cache.Get(1), 11) - data := cache.Data() + b, _ := cache.Contains(1) + t.Assert(b, true) + v, _ := cache.Get(1) + t.Assert(v, 11) + data, _ := cache.Data() t.Assert(data[1], 11) t.Assert(data[2], 22) t.Assert(data[3], nil) - t.Assert(cache.Size(), 2) - keys := cache.Keys() + n, _ := cache.Size() + t.Assert(n, 2) + keys, _ := cache.Keys() t.Assert(gset.NewFrom(g.Slice{1, 2}).Equal(gset.NewFrom(keys)), true) - keyStrs := cache.KeyStrings() + keyStrs, _ := cache.KeyStrings() t.Assert(gset.NewFrom(g.Slice{"1", "2"}).Equal(gset.NewFrom(keyStrs)), true) - values := cache.Values() + values, _ := cache.Values() t.Assert(gset.NewFrom(g.Slice{11, 22}).Equal(gset.NewFrom(values)), true) - removeData1 := cache.Remove(1) + removeData1, _ := cache.Remove(1) t.Assert(removeData1, 11) - t.Assert(cache.Size(), 1) + n, _ = cache.Size() + t.Assert(n, 1) cache.Removes(g.Slice{2}) - t.Assert(cache.Size(), 0) + n, _ = cache.Size() + t.Assert(n, 0) } gcache.Remove(g.Slice{1, 2, 3}...) { gcache.Sets(g.MapAnyAny{1: 11, 2: 22}, 0) - t.Assert(gcache.Contains(1), true) - t.Assert(gcache.Get(1), 11) - data := gcache.Data() + b, _ := gcache.Contains(1) + t.Assert(b, true) + v, _ := gcache.Get(1) + t.Assert(v, 11) + data, _ := gcache.Data() t.Assert(data[1], 11) t.Assert(data[2], 22) t.Assert(data[3], nil) - t.Assert(gcache.Size(), 2) - keys := gcache.Keys() + n, _ := gcache.Size() + t.Assert(n, 2) + keys, _ := gcache.Keys() t.Assert(gset.NewFrom(g.Slice{1, 2}).Equal(gset.NewFrom(keys)), true) - keyStrs := gcache.KeyStrings() + keyStrs, _ := gcache.KeyStrings() t.Assert(gset.NewFrom(g.Slice{"1", "2"}).Equal(gset.NewFrom(keyStrs)), true) - values := gcache.Values() + values, _ := gcache.Values() t.Assert(gset.NewFrom(g.Slice{11, 22}).Equal(gset.NewFrom(values)), true) - removeData1 := gcache.Remove(1) + removeData1, _ := gcache.Remove(1) t.Assert(removeData1, 11) - t.Assert(gcache.Size(), 1) + n, _ = gcache.Size() + t.Assert(n, 1) gcache.Removes(g.Slice{2}) - t.Assert(gcache.Size(), 0) + n, _ = gcache.Size() + t.Assert(n, 0) } }) } diff --git a/os/gfile/gfile_cache.go b/os/gfile/gfile_cache.go index eb663576d..1dba5a994 100644 --- a/os/gfile/gfile_cache.go +++ b/os/gfile/gfile_cache.go @@ -39,7 +39,7 @@ func GetBytesWithCache(path string, duration ...time.Duration) []byte { if len(duration) > 0 { expire = duration[0] } - r := gcache.GetOrSetFuncLock(key, func() interface{} { + r, _ := gcache.GetOrSetFuncLock(key, func() (interface{}, error) { b := GetBytes(path) if b != nil { // Adding this to gfsnotify, @@ -49,7 +49,7 @@ func GetBytesWithCache(path string, duration ...time.Duration) []byte { gfsnotify.Exit() }) } - return b + return b, nil }, expire) if r != nil { return r.([]byte) diff --git a/os/gsession/gsession_session.go b/os/gsession/gsession_session.go index 156033f36..2132942ef 100644 --- a/os/gsession/gsession_session.go +++ b/os/gsession/gsession_session.go @@ -40,7 +40,7 @@ func (s *Session) init() { if s.id != "" { var err error // Retrieve memory session data from manager. - if r := s.manager.sessionData.Get(s.id); r != nil { + if r, _ := s.manager.sessionData.Get(s.id); r != nil { s.data = r.(*gmap.StrAnyMap) intlog.Print("session init data:", s.data) } diff --git a/util/gconv/gconv_z_unit_basic_test.go b/util/gconv/gconv_z_unit_basic_test.go index 806c8b119..9f73bf6c3 100644 --- a/util/gconv/gconv_z_unit_basic_test.go +++ b/util/gconv/gconv_z_unit_basic_test.go @@ -15,7 +15,7 @@ import ( func Test_Basic(t *testing.T) { gtest.C(t, func(t *gtest.T) { - f32 := float32(123.456) + f32 := float32(123.451) i64 := int64(1552578474888) t.AssertEQ(gconv.Int(f32), int(123)) t.AssertEQ(gconv.Int8(f32), int8(123))