热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

LRUw/o时间戳和HashMap-Java。-LRUw/oTimestampsandHashMap-Java

IamnewinprogrammingingeneralandinJavainparticular.IwanttoimplementanLRUcacheandw

I am new in programming in general and in Java in particular. I want to implement an LRU cache and would like to have O(1) complexity.

我在编程方面是新手,特别是在Java方面。我想实现一个LRU缓存,并希望有O(1)复杂度。

I have seen some implementations in the Internet using a manually implemented doubly linked list for the cache (two arrays, a Node class, previous, next etc.) and a HashMap where Key is the item to be cached and Value is the timestamp.

我已经在Internet上看到了一些实现,使用手动实现的缓存(两个数组,一个节点类,前面的,next等)和一个HashMap,其中键是要缓存的项,值是时间戳。

I really don't see the reason to use timestamps: the inserted item goes to the head of the manually-implemented LinkedList, the evicted item is the cached item located at the tail, and in every insertion the previously cached items are shifted one position towards the tail.

我真的没有看到使用时间戳的理由:插入的条目会进入手动实现的LinkedList的头部,被赶出的项是位于尾部的缓存项,在每次插入之前缓存的项都将一个位置移动到尾部。

The only problems that I see are the following:

我看到的唯一问题是:

  1. For the cache lookup (to find if we have a cache hit or miss for the requested item), we have to "scan" the cache list, which implies a for loop of some type (conventional, for-each etc., I don't really care much at this point). Obviously, we don't want that. I believe this issue can be solved easily by using an array of boolean variables to indicate whether an item is in the cache or not (1: in, 0: out) - let's call it lookupArray - as following: Let's say that the items are distinguished by some numeric ID, i.e. an integer between 1 and N. Then, this lookupArray of booleans will have size N+1 (because array indexing starts from zero) and it will be initialized at all zero values. When the item with numeric ID k, where 1<=k<=N, enters the cache, we set the boolean value at index k of lookupArray to 1. That way, cache lookup does not need any search in the cache: in order to check whether the item with numeric ID k is in the cache or not, we simply check whether the value of lookupArray at index k is 1 or 0, respectively. (We already have the index, i.e. we know where to look, thus there is no need to use a for loop.)

    对于缓存查找(如果我们对所请求的项有缓存命中或遗漏),我们必须“扫描”缓存列表,这意味着某个类型的循环(常规的,For -each等),在这一点上我并不十分关心。显然,我们不希望这样。我相信这个问题可以解决很容易通过使用一组布尔变量表明是否一个项目是否在缓存中(1:在0:)——我们称之为lookupArray如下:假设项目的一些数字ID,即一个整数1到N,这lookupArray的布尔值大小N + 1(因为数组索引从0开始),它会在所有零值初始化。当带有数字ID k的项(其中1<=k<=N)进入缓存时,我们在lookupArray的索引k中设置布尔值为1。这样,缓存查找不需要在缓存中进行任何搜索:为了检查带有数字ID k的项是否在缓存中,我们只需要检查索引k中lookupArray的值是否为1或0。(我们已经有了索引,也就是说,我们知道在哪里看,因此没有必要使用for循环。)

  2. The second problem, though, is not easilly solvable. Let's say that we have a cache hit for an item. Then, if this item is not located at the head (i.e. if it is not the most recently used item), we have to locate it in the cache list and then put it at the head. As far as I understand, this implies searching in the cache list, i.e. a for loop. Then, we can't achieve the O(1) objective.

    不过,第二个问题并不容易解决。假设我们有一个项目的缓存命中。然后,如果这个项目不是位于头部(也就是说,如果它不是最近使用的项目),我们必须在缓存列表中找到它,然后将它放在头部。据我所知,这意味着在缓存列表中搜索,即for循环。那么,我们就不能实现O(1)目标。

Am I right about (2)? Is any way to do this without using a HashMap and timestamps?

我说的对吗?没有使用HashMap和时间戳的方法可以做到这一点吗?

Due to the fact that I am relatively new in programming as I stated at the beginning of the post, I would really appreciate the use, if possible, of any code snippets demonstrating the implementation with a manually implemented doubly linked list.

由于我在文章开头就已经说过,我在编程方面相对较新的,所以如果可能的话,我会非常感谢使用手工实现的双向链表来演示实现的任何代码片段。

Sorry for the long message, I hope it is not only detailed but also clear.

不好意思,我希望它不仅详细而且清晰。

Thank you!

谢谢你!

1 个解决方案

#1


0  

Consider using a queue. It allows you to remove an object and insert it at the beginning. It also has a size and can be used for caching.

考虑使用一个队列。它允许您删除一个对象并在开始时插入它。它还有一个大小,可以用于缓存。

http://docs.oracle.com/javase/7/docs/api/java/util/Queue.html

http://docs.oracle.com/javase/7/docs/api/java/util/Queue.html

O, maybe you should not implement it yourself. There is an LRUMap available in the Apache Commons Collections library.

哦,也许你不应该自己去实现它。在Apache Commons集合库中有一个LRUMap。

https://commons.apache.org/proper/commons-collections/javadocs/api-3.2.1/org/apache/commons/collections/map/LRUMap.html

https://commons.apache.org/proper/commons-collections/javadocs/api-3.2.1/org/apache/commons/collections/map/LRUMap.html


推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • ASP.NET2.0数据教程之十四:使用FormView的模板
    本文介绍了在ASP.NET 2.0中使用FormView控件来实现自定义的显示外观,与GridView和DetailsView不同,FormView使用模板来呈现,可以实现不规则的外观呈现。同时还介绍了TemplateField的用法和FormView与DetailsView的区别。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • Java学习笔记之使用反射+泛型构建通用DAO
    本文介绍了使用反射和泛型构建通用DAO的方法,通过减少代码冗余度来提高开发效率。通过示例说明了如何使用反射和泛型来实现对不同表的相同操作,从而避免重复编写相似的代码。该方法可以在Java学习中起到较大的帮助作用。 ... [详细]
  • MySQL中的MVVC多版本并发控制机制的应用及实现
    本文介绍了MySQL中MVCC的应用及实现机制。MVCC是一种提高并发性能的技术,通过对事务内读取的内存进行处理,避免写操作堵塞读操作的并发问题。与其他数据库系统的MVCC实现机制不尽相同,MySQL的MVCC是在undolog中实现的。通过undolog可以找回数据的历史版本,提供给用户读取或在回滚时覆盖数据页上的数据。MySQL的大多数事务型存储引擎都实现了MVCC,但各自的实现机制有所不同。 ... [详细]
  • 本文介绍了在使用Laravel和sqlsrv连接到SQL Server 2016时,如何在插入查询中使用输出子句,并返回所需的值。同时讨论了使用CreatedOn字段返回最近创建的行的解决方法以及使用Eloquent模型创建后,值正确插入数据库但没有返回uniqueidentifier字段的问题。最后给出了一个示例代码。 ... [详细]
  • Todayatworksomeonetriedtoconvincemethat:今天在工作中有人试图说服我:{$obj->getTableInfo()}isfine ... [详细]
  • 解决Sharepoint 2013运行状况分析出现的“一个或多个服务器未响应”问题的方法
    本文介绍了解决Sharepoint 2013运行状况分析中出现的“一个或多个服务器未响应”问题的方法。对于有高要求的客户来说,系统检测问题的存在是不可接受的。文章详细描述了解决该问题的步骤,包括删除服务器、处理分布式缓存留下的记录以及使用代码等方法。同时还提供了相关关键词和错误提示信息,以帮助读者更好地理解和解决该问题。 ... [详细]
  • LVS实现负载均衡的原理LVS负载均衡负载均衡集群是LoadBalance集群。是一种将网络上的访问流量分布于各个节点,以降低服务器压力,更好的向客户端 ... [详细]
  • php缓存ri,浅析ThinkPHP缓存之快速缓存(F方法)和动态缓存(S方法)(日常整理)
    thinkPHP的F方法只能用于缓存简单数据类型,不支持有效期和缓存对象。S()缓存方法支持有效期,又称动态缓存方法。本文是小编日常整理有关thinkp ... [详细]
  • 本文整理了Java中com.evernote.android.job.JobRequest.getTransientExtras()方法的一些代码示例,展示了 ... [详细]
  • 本文介绍了在Ubuntu系统中清理残余配置文件和无用内容的方法,包括清理残余配置文件、清理下载缓存包、清理不再需要的包、清理无用的语言文件和清理无用的翻译内容。通过这些清理操作可以节省硬盘空间,提高系统的运行效率。 ... [详细]
author-avatar
shanfeng0828_589
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有