使用JS完成一个LRU缓存

6 篇文章 0 订阅
1 篇文章 0 订阅

1. 什么是LRU缓存 

LRU 英文全称是 Least Recently Used,英译过来就是”最近最少使用“的意思。 它是页面置换算法中的一种。 

百度百科 

LRU 是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间 t,当须淘汰一个页面时,选择现有页面中其 t 值最大的,即最近最少使用的页面予以淘汰。 

通俗解释就是说

假如我们有一块内存,专门用来缓存我们最近发访问的网页,访问一个新网页,我们就会往内存中添加一个网页地址,随着网页的不断增加,内存存满了,这个时候我们就需要考虑删除一些网页了。这个时候我们找到内存中最早访问的那个网页地址,然后把它删掉。
这一整个过程就可以称之为 LRU 算法。 

两点需要注意: 

①当我们访问内存中已经存在了的网址,那么该网址需要更新在内存中的存储顺序。 

②当我们内存中还没有数据的时候,不需要执行删除操作。

2.实现LRU思路梳理 

  • 我们需要一块有限的存储空间,因为无限的化就没必要使用 LRU 算发删除数据了。
  • 我们这块存储空间里面存储的数据需要是有序的,因为我们必须要顺序来删除数据,所以可以考虑使用 ArrayMap 数据结构来存储,不能使用 Object,因为它是无序的。
  • 我们能够删除或者添加以及获取到这块存储空间中的指定数据。
  • 存储空间存满之后,在添加数据时,会自动删除时间最久远的那条数据。

实现就是我们实现一个LRUCache的类,用作存储空间,采用es6中的Map数据结构存储数据,因为它的时间复杂度为 O(1) 且有序,实现get,set方法用来获取和添加数据,存储空间有长度限制,不需要提供删除方法,当我们的内存长度满了之后,自动删除最近最久未被使用的数据,当使用get获取数据时,更新顺序到到最前面

3. 代码 

js 

class LRUCache {
  constructor(length) {
    this.length = length  // 存储长度
    this.map = new Map()  // 存储数据
  }

  // 存储数据,通过键值对的方式
  set(key, value) {
    if(this.map.has(key)) {
      this.map.delete(key)
    }
    this.map.set(key, value)

    // 如果超出了容量,则删除最久的数据(map中即第一个)
    if(this.map.size > this.length) {
      this.map.delete(this.map.keys().next().value)
    }
  }

  // 获取数据
  get(key) {
    if(!this.map.has(key)) {
      return null
    }

    const val = this.map.get(key)  // 获取元素
    this.map.delete(key)  // 删除元素
    this.map.set(key, val) // 重新插入元素,更新存储顺序
  }
}

const lruCache = new LRUCache(3)

lruCache.set('name', 'wft')
lruCache.set('age', 18)
lruCache.set('sex', '男')
lruCache.set('len', '超出长度')

console.log(lruCache, '----->>>')

ts 

interface ILRUCache {
  length: number
  map: Map<unknown, unknown>
  set(key: unknown, value: unknown): void
  get(key: unknown): void
}


class LRUCache implements ILRUCache {
  length: number
  map: Map<unknown, unknown>

  constructor(length: number) {
    this.length = length
    this.map = new Map()
  }

  set(key: unknown, value: unknown) {
    if(this.map.has(key)) {
      this.map.delete(key)
    }
    this.map.set(key, value)

    if(this.map.size > this.length) {
      this.map.delete(this.map.keys().next().value)
    }
  }

  get(key: unknown) {
    if(!this.map.has(key)) {
      return null
    }

    const val = this.map.get(key)
    this.map.delete(key)
    this.map.set(key, val)
  }
}

const lruCache = new LRUCache(3)

lruCache.set('name', 'wft')
lruCache.set('age', 18)
lruCache.set('sex', '男')
lruCache.set('len', '超出长度')

console.log(lruCache, '----->>>')

学习于:https://juejin.cn/post/7105654083347808263 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会说法语的猪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值