Cache Eviction
Keshdan chiqarib tashlash
Oldingi darsdagi kesh oxirigacha ishlaydi, lekin bitta muammosi bor: yozuvni saqlaganingizda TTLni ushlab turasiz, lekin uni hech qachon ishlatmaysiz. Bir marta saqlangan yozuv keshda abadiy qoladi, hatto haqiqiy dunyoda uning muddati allaqachon o'tgan bo'lsa ham.
TTL foydali bo'lishi uchun, kesh yozuv qachon saqlanganini bilishi va uni qachon so'rashganda solishtirishi kerak. Haqiqiy tizimda bu joriy vaqtni bildiradi; mashqda joriy vaqtni chaqiruvchi o'zi now deb nomlangan oddiy son sifatida beradi — bu Unix vaqt tamg'asi (soniyalarda) kabi ishlaydi, lekin haqiqiy soatga bog'liq bo'lmagani uchun natijani har doim bashorat qilsa bo'ladi.
type CacheEntry struct {
Record DNSRecord
ExpiresAt int // "now" shu qiymatga yetsa yoki undan katta bo'lsa, yozuv muddati tugagan
}Set chaqirilganda, muddat tugash vaqti hisoblab chiqiladi va saqlanadi: now + r.TTL. Endi DNSCache DNSRecordning o'zini emas, CacheEntryni saqlaydi.
func (c DNSCache) Set(r DNSRecord, now int) {
c[r.Name+":"+r.Type] = CacheEntry{Record: r, ExpiresAt: now + r.TTL}
}Get endi ikkita ishni qiladi: yozuvni topadi, va uning muddati o'tganmi-yo'qmi tekshiradi. Agar now ExpiresAtga yetgan yoki undan katta bo'lsa, yozuv eskirgan — uni shunchaki e'tiborsiz qoldirish yetarli emas, uni keshdan chiqarib tashlash (evict) kerak, aks holda u xotirani egallab yotaveradi:
func (c DNSCache) Get(name, recordType string, now int) (DNSRecord, bool) {
key := name + ":" + recordType
entry, ok := c[key]
if !ok {
return DNSRecord{}, false
}
if now >= entry.ExpiresAt {
delete(c, key)
return DNSRecord{}, false
}
return entry.Record, true
}delete(c, key) — Exists or Not darsida ko'rgan o'rnatilgan funksiya. Uni chaqirish har doim xavfsiz, va bu yerda aynan kerakli ish: eskirgan yozuv keyingi so'rovda qaytadan tekshirilmasin uchun butunlay olib tashlanadi.
>_ Exercise
CacheEntryni Record DNSRecord va ExpiresAt int maydonlari bilan aniqlang. DNSCacheni endi CacheEntry qiymatlarini saqlaydigan qilib yangilang: map[string]CacheEntry.
Ikkita metodni yozing:
- •
(c DNSCache) Set(r DNSRecord, now int)— yozuvniExpiresAt: now + r.TTLbilan saqlaydi - •
(c DNSCache) Get(name, recordType string, now int) (DNSRecord, bool)— yozuvni qaytaradi; agar u mavjud bo'lmasa yoki muddati o'tgan bo'lsa (now >= ExpiresAt), uni keshdan olib tashlab(DNSRecord{}, false)qaytaradi
Misollar (TTL 60 bilan now=1000da saqlangan yozuv uchun, demak ExpiresAt=1060):
- •
cache.Get("example.com", "A", 1030)—(record, true)qaytaradi, chunki1030 < 1060 - •
cache.Get("example.com", "A", 1075)—(DNSRecord{}, false)qaytaradi va yozuvni keshdan chiqarib tashlaydi, chunki1075 >= 1060
Stuck? Reveal a hint to help you.
Key Takeaway
Key Takeaway:
TTL foydali bo'lishi uchun, kesh yozuv qachon saqlanganini eslab qolishi va har bir o'qishda muddatni tekshirishi kerak. Eskirgan yozuvni topganingizda uni shunchaki e'tiborsiz qoldirmang — delete bilan keshdan butunlay chiqarib tashlang.
NEXT UP
Record Validator
$ go run main.go
Kodingizni ishga tushiring