找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 4819|回复: 0

一个Python写的支持LRU的类

[复制链接]
发表于 2011-2-16 14:23:46 | 显示全部楼层 |阅读模式
本帖最后由 freeeyes 于 2011-2-16 14:30 编辑

最近工作需要,写了一个Python下的池,需要LRU支持,感觉写起来比C++的简单。
脚本语言在逻辑处理上,还是提供了很多方便的接口。
在这里记录一下
  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-#
  3. '''
  4. Created on 2011-2-16
  5. @author: freeeyes
  6. '''
  7. import time
  8. from heapq import heappush, heappop, heapify
  9. class LRUCache(object):
  10.     class __Node(object):
  11.         def __init__(self, key, obj, timestamp, sort_key):
  12.             object.__init__(self)
  13.             self.key = key
  14.             self.obj = obj
  15.             self.atime = timestamp
  16.             self.mtime = self.atime
  17.             self._sort_key = sort_key
  18.    
  19.         def __cmp__(self, other):
  20.             return cmp(self._sort_key, other._sort_key)
  21.         
  22.         def __repr__(self):
  23.             return "<%s %s => %s (%s)>" % (self.__class__, self.key, self.obj, time.asctime(time.localtime(self.atime)))
  24.         
  25.     def __init__(self, nCacheCount):
  26.         self.m_nCacheCount = nCacheCount
  27.         self.m_heap     = []
  28.         self.m_dict     = {}
  29.         self.m_nCounter = 0
  30.     def GetSortKey(self):
  31.         self.m_nCounter += 1
  32.         return self.m_nCounter
  33.    
  34.     def __len__(self):
  35.         return len(self.m_heap)
  36.     def __setitem__(self, key, obj):
  37.         if self.m_dict.has_key(key):
  38.             node = self.m_dict[key]
  39.             node.atime = time.time()
  40.             node.mtime = node.atime
  41.             node._sort_key = self.GetSortKey()
  42.             heapify(self.m_heap)
  43.         else:
  44.             while len(self.m_heap) >= self.m_nCacheCount:
  45.                 lru = heappop(self.m_heap)
  46.                 self.SetData(lru.key, self.m_dict[lru.key].obj)
  47.                 del self.m_dict[lru.key]
  48.             
  49.             node = self.__Node(key, obj, time.time(), self.GetSortKey())
  50.             self.m_dict[key] = node
  51.             heappush(self.m_heap, node)
  52.     def __getitem__(self, key):
  53.         if not self.m_dict.has_key(key):
  54.             return self.GetData(key)
  55.         else:
  56.             node = self.m_dict[key]
  57.             node.atime = time.time()
  58.             node._sort_key = self.GetSortKey()
  59.             heapify(self.m_heap)
  60.             return node.obj
  61.     def __delitem__(self, key):
  62.         if not self.m_dict.has_key(key):
  63.             return None
  64.         else:
  65.             node = self.m_dict[key]
  66.             del self.m_dict[key]
  67.             self.m_heap.remove(node)
  68.             heapify(self.m_heap)
  69.             return node.obj
  70.         
  71.     def __iter__(self):
  72.         copy = self.m_heap[:]
  73.         while len(copy) > 0:
  74.             node = heappop(copy)
  75.             yield node.key
  76.         raise StopIteration
  77.    
  78.     def __setattr__(self, name, value):
  79.         object.__setattr__(self, name, value)
  80.         if name == 'size':
  81.             while len(self.m_heap) > value:
  82.                 lru = heappop(self.m_heap)
  83.                 del self.m_dict[lru.key]
  84.     def __repr__(self):
  85.         return "<%s (%d elements)>" % (str(self.__class__), len(self.m_heap))
  86.    
  87.     def GetData(self, key):
  88.         #重载实现函数,当找不到数据的时候,调用这个加载
  89.         pass
  90.    
  91.     def SetData(self, key, obj):
  92.         #当数据超过的池大小的时候,会调用这个。
  93.         pass
复制代码
这里因为我个人需要,我需要在GetItem()的时候,如果不在指定的字典里面,则提供外围一个接口,从别的介质获取数据(数据库中查找并加载进队列),如果队列达到上限,则剔除最不常用的那个对象,同时调用SetData()接口,让你把这个数据放在其他介质上(比如数据库)。
测试代码如下:(数据库部分省略,只是简单测试)
  1. class TaskLru(LRUCache):
  2.     def GetData(self, key):
  3.         print "[GetData]Key=" + str(key)
  4.         
  5.     def SetData(self, key, obj):
  6.         print "[SetData]Key=" + str(key) + ",obj=" + str(obj)
  7.         
  8.         
  9. objTaskLru = TaskLru(10)
  10. for i in range(0, 20):
  11.     objTaskLru[i] = i
复制代码


输出为
[SetData]Key=0,obj=0
[SetData]Key=1,obj=1
[SetData]Key=2,obj=2
[SetData]Key=3,obj=3
[SetData]Key=4,obj=4
[SetData]Key=5,obj=5
[SetData]Key=6,obj=6
[SetData]Key=7,obj=7
[SetData]Key=8,obj=8
[SetData]Key=9,obj=9


此代码在python2.6下编译通过。
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-5-7 17:06 , Processed in 0.019433 second(s), 6 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表