diff --git a/g/os/gcache/gcache_cache.go b/g/os/gcache/gcache_cache.go index ecf5570ac..13f2c491b 100644 --- a/g/os/gcache/gcache_cache.go +++ b/g/os/gcache/gcache_cache.go @@ -24,9 +24,6 @@ func New(lruCap...int) *Cache { } go c.autoSyncLoop() go c.autoClearLoop() - if c.cap > 0 { - go c.autoLruClearLoop() - } return c } diff --git a/g/os/gcache/gcache_mem_cache.go b/g/os/gcache/gcache_mem_cache.go index 87fc778e9..7b5ed299f 100644 --- a/g/os/gcache/gcache_mem_cache.go +++ b/g/os/gcache/gcache_mem_cache.go @@ -99,6 +99,10 @@ func (c *memCache) Set(key interface{}, value interface{}, expire int) { c.data[key] = memCacheItem{v : value, e : expireTimestamp} c.dmu.Unlock() c.eventQueue.PushBack(memCacheEvent{k : key, e : expireTimestamp}) + // LRU(Least Recently Used)操作记录 + if c.cap > 0 { + c.lru.Push(key) + } } // 设置kv缓存键值对,内部会对键名的存在性使用写锁进行二次检索确认,如果存在则不再写入;返回键名对应的键值。 @@ -113,6 +117,9 @@ func (c *memCache) doSetWithLockCheck(key interface{}, value interface{}, expire c.data[key] = memCacheItem{v : value, e : expireTimestamp} c.dmu.Unlock() c.eventQueue.PushBack(memCacheEvent{k : key, e : expireTimestamp}) + if c.cap > 0 { + c.lru.Push(key) + } return value } @@ -144,6 +151,9 @@ func (c *memCache) BatchSet(data map[interface{}]interface{}, expire int) { c.data[k] = memCacheItem{v: v, e: expireTimestamp} c.dmu.Unlock() c.eventQueue.PushBack(memCacheEvent{k: k, e: expireTimestamp}) + if c.cap > 0 { + c.lru.Push(k) + } } } @@ -305,30 +315,19 @@ func (c *memCache) autoClearLoop() { delete(c.eksets, v) c.smu.Unlock() } + // LRU缓存淘汰清理 + if c.cap > 0 { + for i := c.Size() - c.cap; i > 0; i-- { + if s := c.lru.Pop(); s != "" { + c.clearByKey(s, true) + } + } + } time.Sleep(10*time.Second) } } } -// LRU缓存淘汰清理 -func (c *memCache) autoLruClearLoop() { - for { - select { - case <-c.stopChan: - return - default: - if c.cap > 0 { - for i := c.Size() - c.cap; i > 0; i-- { - if s := c.lru.Pop(); s != "" { - c.clearByKey(s, true) - } - } - } - time.Sleep(time.Second) - } - } -} - // 删除对应键名的缓存数据 func (c *memCache) clearByKey(key interface{}, force...bool) bool { // 删除缓存数据 diff --git a/g/os/gfile/gfile.go b/g/os/gfile/gfile.go index c842706fa..b12528a8a 100644 --- a/g/os/gfile/gfile.go +++ b/g/os/gfile/gfile.go @@ -242,6 +242,20 @@ func Copy(src string, dst string) error { return nil } +// 返回目录下的文件名列表 +func DirNames(path string) ([]string, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + list, err := f.Readdirnames(-1) + f.Close() + if err != nil { + return nil, err + } + return list, nil +} + // 文件名正则匹配查找,第二个可选参数指定返回的列表是否仅为文件名(非绝对路径),默认返回绝对路径 func Glob(pattern string, onlyNames...bool) ([]string, error) { if list, err := filepath.Glob(pattern); err == nil { diff --git a/g/os/gfpool/gfpool.go b/g/os/gfpool/gfpool.go index 8cfc63f73..2c47161f7 100644 --- a/g/os/gfpool/gfpool.go +++ b/g/os/gfpool/gfpool.go @@ -106,6 +106,7 @@ func (p *Pool) File() (*File, error) { if err := f.Truncate(0); err != nil { return nil, err } + f.Seek(0, 0) } return f, nil } diff --git a/g/util/gconv/gconv.go b/g/util/gconv/gconv.go index 5b5e006ba..d061b3e59 100644 --- a/g/util/gconv/gconv.go +++ b/g/util/gconv/gconv.go @@ -12,6 +12,7 @@ import ( "strconv" "encoding/json" "gitee.com/johng/gf/g/encoding/gbinary" + "strings" ) // 将变量i转换为字符串指定的类型t @@ -120,7 +121,7 @@ func Int(i interface{}) int { } return 0 default: - v, _ := strconv.Atoi(String(value)) + v, _ := strconv.Atoi(strings.TrimSpace(String(value))) return v } } @@ -188,7 +189,7 @@ func Uint(i interface{}) uint { } return 0 default: - v, _ := strconv.ParseUint(String(value), 10, 64) + v, _ := strconv.ParseUint(strings.TrimSpace(String(value)), 10, 64) return uint(v) } } @@ -240,7 +241,7 @@ func Float32 (i interface{}) float32 { if v, ok := i.(float32); ok { return v } - v, _ := strconv.ParseFloat(String(i), 64) + v, _ := strconv.ParseFloat(strings.TrimSpace(String(i)), 64) return float32(v) } @@ -251,7 +252,7 @@ func Float64 (i interface{}) float64 { if v, ok := i.(float64); ok { return v } - v, _ := strconv.ParseFloat(String(i), 64) + v, _ := strconv.ParseFloat(strings.TrimSpace(String(i)), 64) return v } diff --git a/geg/database/kafka/gkafka_consumer.go b/geg/database/kafka/gkafka_consumer.go index ba670cf71..4b960b2f3 100644 --- a/geg/database/kafka/gkafka_consumer.go +++ b/geg/database/kafka/gkafka_consumer.go @@ -17,16 +17,18 @@ func newKafkaClientConsumer(topic, group string) *gkafka.Client { } func main () { - client := newKafkaClientConsumer("test", "test-group-1") + group := "test-group-11" + client := newKafkaClientConsumer("test", group) defer client.Close() for { - fmt.Println("reading...") - for i := 1; i < 10; i++ { + fmt.Println(group + " reading...") + for { if msg, err := client.Receive(); err != nil { fmt.Println(err) } else { - fmt.Println(string(msg.Value)) + fmt.Println(msg.Partition, msg.Offset, string(msg.Value)) + msg.MarkOffset() } } time.Sleep(3*time.Second) diff --git a/geg/database/kafka/gkafka_producer.go b/geg/database/kafka/gkafka_producer.go index 245bcc0f7..a1192ab1b 100644 --- a/geg/database/kafka/gkafka_producer.go +++ b/geg/database/kafka/gkafka_producer.go @@ -3,7 +3,7 @@ package main import ( "gitee.com/johng/gf/g/database/gkafka" "fmt" - "gitee.com/johng/gf/g/util/gconv" + "gitee.com/johng/gf/g/os/gtime" ) // 创建kafka生产客户端 @@ -19,11 +19,10 @@ func main () { client := newKafkaClientProducer("test") defer client.Close() - for i := 1; i < 10; i++ { - if err := client.SyncSend(&gkafka.Message{Value: []byte(gconv.String(i))}); err != nil { - fmt.Println(err) - } + if err := client.SyncSend(&gkafka.Message{Value: []byte(gtime.Now().String())}); err != nil { + fmt.Println(err) } + fmt.Println("done") } diff --git a/geg/os/gcache/usage_lru.go b/geg/os/gcache/usage_lru.go index 83dd3056a..2ef07ff38 100644 --- a/geg/os/gcache/usage_lru.go +++ b/geg/os/gcache/usage_lru.go @@ -8,17 +8,17 @@ import ( func main() { // 设置LRU淘汰数量 - gcache.SetCap(2) + c := gcache.New(2) - // 10个元素 + // 添加10个元素 for i := 0; i < 10; i++ { - gcache.Set(i, i, 0) + c.Set(i, i, 0) } - fmt.Println(gcache.Size()) - fmt.Println(gcache.Keys()) + fmt.Println(c.Size()) + fmt.Println(c.Keys()) - // 等待一定时间后(默认10秒检查一次),元素会被按照从旧到新的顺序进行淘汰 - time.Sleep(11*time.Second) - fmt.Println(gcache.Size()) - fmt.Println(gcache.Keys()) + // 等待一定时间后(默认1秒检查一次),元素会被按照从旧到新的顺序进行淘汰 + time.Sleep(2*time.Second) + fmt.Println(c.Size()) + fmt.Println(c.Keys()) } \ No newline at end of file diff --git a/geg/other/test.go b/geg/other/test.go index 85a218ea3..81a3fb2a7 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -1,16 +1,14 @@ package main import ( - "time" - "gitee.com/johng/gf/g/os/gcache" + "gitee.com/johng/gf/g/container/gmap" "fmt" ) func main() { - c := gcache.New(1000) - c.Set(1, 1, 0) - c.Set(2, 2, 0) - c.Clear() - fmt.Println(c.Size()) - time.Sleep(time.Second) + m1 := gmap.NewIntInterfaceMap() + m1.Set(1, gmap.NewIntIntMap()) + v1 := m1.Get(1).(*gmap.IntIntMap) + v1.Set(2, 2) + fmt.Println(m1.Get(1).(*gmap.IntIntMap).Size()) } \ No newline at end of file