欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

go實(shí)現(xiàn)一個(gè)內(nèi)存緩存系統(tǒng)的示例代碼

 更新時(shí)間:2024年10月18日 10:43:55   作者:Monkey@  
本文主要介紹了go實(shí)現(xiàn)一個(gè)內(nèi)存緩存系統(tǒng)的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

面試內(nèi)容:

  • 支持設(shè)定過(guò)期時(shí)間,精度到秒
  • 支持設(shè)定最大內(nèi)存,當(dāng)內(nèi)存超出時(shí)做出合適的處理
  • 支持并發(fā)安全
  • 要求按照以下接口實(shí)現(xiàn)
SetMemory(size string) bool
	Set(key string, val interface{}, expire time.Duration) bool
	Get(key string) (interface{}, bool)
	Del(key string) bool
	Exists(key string) bool
	Flush() bool
	Keys() int64

下面為具體實(shí)現(xiàn)代碼:

接口

package cache
import "time"
type Cache interface {
	SetMemory(size string) bool
	Set(key string, val interface{}, expire time.Duration) bool
	Get(key string) (interface{}, bool)
	Del(key string) bool
	Exists(key string) bool
	Flush() bool
	Keys() int64
}

實(shí)現(xiàn)類

package cache

import (
	"fmt"
	"sync"
	"time"
)

type MemCache struct {
	//最大內(nèi)存
	maxMemorySize int64
	// 當(dāng)前已使用的內(nèi)存
	currMemorySize int64
	// 最大內(nèi)存字符串表示
	maxMemorySizeStr string
	// 緩存鍵值對(duì)
	values map[string]*memCacheValue
	// 讀寫(xiě)鎖
	lock sync.RWMutex
	//設(shè)置清除過(guò)期緩存的時(shí)間間隔
	clearExpireTime time.Duration
}

type memCacheValue struct {
	//value 值
	val interface{}
	// 過(guò)期時(shí)間
	expireTime time.Time
	//有效時(shí)間
	expire time.Duration
	//value 大小
	size int64
}

func NewMemCache() Cache {
	mc := &MemCache{
		clearExpireTime: time.Second * 10,
		values:          make(map[string]*memCacheValue),
	}
	go mc.clearExpireItm()
	return mc
}

// SetMemory size 1KB 100KB 1M 2M 1GB
func (mc *MemCache) SetMemory(size string) bool {
	mc.maxMemorySize, mc.maxMemorySizeStr = ParseSize(size)
	return true
}

// Set 設(shè)置緩存
func (mc *MemCache) Set(key string, val interface{}, expire time.Duration) bool {
	mc.lock.Lock()
	defer mc.lock.Unlock()
	v := &memCacheValue{val: val, expireTime: time.Now().Add(expire),
		expire: expire,
		size:   GetValSize(val)}
	//mc.values[key] = v
	mc.del(key)
	mc.add(key, v)
	if mc.currMemorySize > mc.maxMemorySize {
		mc.del(key)
		panic(fmt.Sprintf("max memory size %d", mc.maxMemorySize))
	}
	return true
}

func (mc *MemCache) get(key string) (*memCacheValue, bool) {
	val, ok := mc.values[key]
	return val, ok
}

func (mc *MemCache) del(key string) {
	tmp, ok := mc.get(key)
	if ok && tmp != nil {
		mc.currMemorySize -= tmp.size
		delete(mc.values, key)
	}
}

func (mc *MemCache) add(key string, val *memCacheValue) {
	mc.values[key] = val
	mc.currMemorySize += val.size
}

// Get 獲取緩存值
func (mc *MemCache) Get(key string) (interface{}, bool) {
	mc.lock.RLock()
	defer mc.lock.RUnlock()
	mcv, ok := mc.get(key)
	if ok {
		if mcv.expire != 0 && mcv.expireTime.Before(time.Now()) {
			mc.del(key)
			return nil, false
		}
		return mcv.val, ok
	}
	return nil, false
}

// Del 刪除緩存值
func (mc *MemCache) Del(key string) bool {
	mc.lock.Lock()
	defer mc.lock.Unlock()
	mc.del(key)
	return true
}

func (mc *MemCache) Exists(key string) bool {
	mc.lock.RLock()
	defer mc.lock.RUnlock()
	_, ok := mc.get(key)
	return ok
}

func (mc *MemCache) Flush() bool {
	mc.lock.Lock()
	defer mc.lock.Unlock()
	mc.values = make(map[string]*memCacheValue, 0)
	mc.currMemorySize = 0
	return true
}

func (mc *MemCache) Keys() int64 {
	mc.lock.RLock()
	defer mc.lock.RUnlock()
	return int64(len(mc.values))
}

func (mc *MemCache) clearExpireItm() {
	ticker := time.NewTicker(mc.clearExpireTime)
	defer ticker.Stop()
	for {
		select {
		case <-ticker.C:
			for key, v := range mc.values {
				if v.expire != 0 && time.Now().After(v.expireTime) {
					mc.lock.Lock()
					mc.del(key)
					mc.lock.Unlock()
				}
			}
		}
	}
}

//
//var Cache = NewMemCache()
//
//func Set(key string, val interface{}) bool {
//
//	return false
//}

工具類

package cache

import (
	"log"
	"regexp"
	"strconv"
	"strings"
)

const (
	B = 1 << (iota * 10)
	KB
	MB
	GB
	TB
	PB
)

func ParseSize(size string) (int64, string) {

	//默認(rèn)大小為 100M
	re, _ := regexp.Compile("[0-9]+")
	unit := string(re.ReplaceAll([]byte(size), []byte("")))
	num, _ := strconv.ParseInt(strings.Replace(size, unit, "", 1), 10, 64)
	unit = strings.ToUpper(unit)
	var byteNum int64 = 0
	switch unit {
	case "B":
		byteNum = num
		break
	case "KB":
		byteNum = num * KB
		break
	case "MB":
		byteNum = num * MB
		break
	case "GB":
		byteNum = num * GB
		break
	case "TB":
		byteNum = num * TB
		break
	case "PB":
		byteNum = num * PB
		break
	default:
		num = 0
		byteNum = 0

	}
	if num == 0 {
		log.Println("ParseSize 僅支持B,KB,MB,GB,TB,PB")
		num = 100 * MB
		byteNum = num
		unit = "MB"
	}
	sizeStr := strconv.FormatInt(num, 10) + unit
	return byteNum, sizeStr

}

func GetValSize(val interface{}) int64 {
	return 0
}

代理類

package server

import (
	"go_lang_pro/cache"
	"time"
)

type cacheServer struct {
	memCache cache.Cache
}

func NewMemoryCache() *cacheServer {
	return &cacheServer{
		memCache: cache.NewMemCache(),
	}
}

func (cs *cacheServer) SetMemory(size string) bool {
	return cs.memCache.SetMemory(size)
}

func (cs *cacheServer) Set(key string, val interface{}, expire ...time.Duration) bool {
	expirets := time.Second * 0
	if len(expire) > 0 {
		expirets = expire[0]
	}
	return cs.memCache.Set(key, val, expirets)
}

func (cs *cacheServer) Get(key string) (interface{}, bool) {
	return cs.memCache.Get(key)
}
func (cs *cacheServer) Del(key string) bool {
	return cs.memCache.Del(key)
}

func (cs *cacheServer) Exists(key string) bool {
	return cs.memCache.Exists(key)
}

func (cs *cacheServer) Flush() bool {
	return cs.memCache.Flush()
}

func (cs *cacheServer) Keys() int64 {
	return cs.memCache.Keys()
}

main 方法

package main

import (
	"go_lang_pro/cache"
	"time"
)

func main() {

	cache := cache.NewMemCache()
	cache.SetMemory("100MB")
	cache.Set("int", 1, time.Second)
	cache.Set("bool", false, time.Second)
	cache.Set("data", map[string]interface{}{"a": 1}, time.Second)
	cache.Get("int")
	cache.Del("int")
	cache.Flush()
	cache.Keys()

}

到此這篇關(guān)于go實(shí)現(xiàn)一個(gè)內(nèi)存緩存系統(tǒng)的示例代碼的文章就介紹到這了,更多相關(guān)go 內(nèi)存緩存系統(tǒng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • 基于Golang編寫(xiě)貪吃蛇游戲

    基于Golang編寫(xiě)貪吃蛇游戲

    這篇文章主要為大家學(xué)習(xí)介紹了Golang如何基于終端庫(kù)termbox-go做個(gè)功能較簡(jiǎn)單的貪吃蛇游戲,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值
    2023-07-07
  • 聊聊go xorm生成mysql的結(jié)構(gòu)體問(wèn)題

    聊聊go xorm生成mysql的結(jié)構(gòu)體問(wèn)題

    這篇文章主要介紹了go xorm生成mysql的結(jié)構(gòu)體問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2022-03-03
  • Golang基于epoll實(shí)現(xiàn)最簡(jiǎn)單網(wǎng)絡(luò)通信框架

    Golang基于epoll實(shí)現(xiàn)最簡(jiǎn)單網(wǎng)絡(luò)通信框架

    這篇文章主要為大家詳細(xì)介紹了Golang如何基于epoll實(shí)現(xiàn)最簡(jiǎn)單網(wǎng)絡(luò)通信框架,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)學(xué)習(xí)
    2023-06-06
  • 簡(jiǎn)單高效!Go語(yǔ)言封裝二級(jí)認(rèn)證功能實(shí)現(xiàn)

    簡(jiǎn)單高效!Go語(yǔ)言封裝二級(jí)認(rèn)證功能實(shí)現(xiàn)

    本文將介紹如何使用Go語(yǔ)言封裝二級(jí)認(rèn)證功能,實(shí)現(xiàn)簡(jiǎn)單高效的用戶認(rèn)證流程,二級(jí)認(rèn)證是一種安全措施,要求用戶在登錄后進(jìn)行額外的身份驗(yàn)證,以提高賬戶安全性,
    2023-10-10
  • 重學(xué)Go語(yǔ)言之文件操作詳解

    重學(xué)Go語(yǔ)言之文件操作詳解

    有很多場(chǎng)景都需要對(duì)文件進(jìn)行讀取或者寫(xiě)入,比如讀取配置文件或者寫(xiě)入日志文件,在Go語(yǔ)言中,操作文件應(yīng)該算是一件比較簡(jiǎn)單的事情,我們?cè)谶@一篇文章中,一起來(lái)探究一下
    2023-08-08
  • 詳解go如何使用xorm在執(zhí)行前改寫(xiě)?SQL

    詳解go如何使用xorm在執(zhí)行前改寫(xiě)?SQL

    這篇文章主要為大家介紹了詳解go如何使用xorm在執(zhí)行前改寫(xiě)SQL的實(shí)現(xiàn)過(guò)程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • Golang 實(shí)現(xiàn)復(fù)制文件夾同時(shí)復(fù)制文件

    Golang 實(shí)現(xiàn)復(fù)制文件夾同時(shí)復(fù)制文件

    這篇文章主要介紹了Golang 實(shí)現(xiàn)復(fù)制文件夾同時(shí)復(fù)制文件,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • Go語(yǔ)言如何使用 Viper 來(lái)管理配置

    Go語(yǔ)言如何使用 Viper 來(lái)管理配置

    在現(xiàn)代軟件開(kāi)發(fā)中,良好的配置管理可以極大地提升應(yīng)用的靈活性和可維護(hù)性,下面我們就來(lái)看看GO語(yǔ)言中如何使用 Viper 來(lái)管理配置吧
    2024-11-11
  • Go語(yǔ)言入門(mén)之基礎(chǔ)語(yǔ)法和常用特性解析

    Go語(yǔ)言入門(mén)之基礎(chǔ)語(yǔ)法和常用特性解析

    這篇文章主要給大家講解了Go語(yǔ)言的基礎(chǔ)語(yǔ)法和常用特性解析,比較適合入門(mén)小白,文中通過(guò)代碼示例介紹的非常詳細(xì),對(duì)我們學(xué)習(xí)Go語(yǔ)言有一定的幫助,需要的朋友可以參考下
    2023-07-07
  • Golang中json和jsoniter的區(qū)別使用示例

    Golang中json和jsoniter的區(qū)別使用示例

    這篇文章主要介紹了Golang中json和jsoniter的區(qū)別使用示例,本文給大家分享兩種區(qū)別,結(jié)合示例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2023-12-12

最新評(píng)論