zoukankan      html  css  js  c++  java
  • urllib3中学到的LRU算法

    介绍

    urllib3._collections.py::RecentlyUserContainer类,是一个线程安全的Dict类容器,用来维护一定数量(maxsize)的Key-Value映射, 当数量超出,会删除最近最少使用的key。该类实际用在PoolManager中存储Session中一定连接数量的连接池,当连接数超出时,会自动删除最早保存的连接,并且查找连接的时间复杂度是O(1)。

    原理

    其原理是通过有序字典(OrderedDict)保存Key的插入顺序,但Key的数量超出阈值时,删除最早插入的Key

    from collections import OrderedDict
    from threading import RLock
    
    class RecentlyUserContainer:
        def __init__(self, maxsize):
            self._maxsize = maxsize
            self._container = OrderedDict()
            self.lock = RLock()
        
        def __getitem__(self, key):
            with self.lock:
                # 注意 这里先取出再插入的目的是更新该Key的顺序,即它最近被访问过
                item = self._container.pop(key)
                self._container[key] = item
                return item
        
        def __setitem__(self, key, value):
            with self.lock:
                self._container[key] = value
                if len(self._container) > self._maxsize:
                    # 驱逐出最早插入的Key
                    key, _ = self._container.popitem(last=False)
                    print(f"{key} is evicted")
    

    使用

    >>> pool = RecentlyUserContainer(3)
    >>> pool["https://www.1.com"] = "conn1" 
    >>> pool["https://www.2.com"] = "conn2"
    >>> pool["https://www.3.com"] = "conn3"
    >>> pool["https://www.4.com"] = "conn4"
    www.1.com is evicted
    >>> pool._container
    OrderedDict([('https://www.2.com', 'conn2'),
                 ('https://www.3.com', 'conn3'),
                 ('https://www.4.com', 'conn4')])
    
  • 相关阅读:
    Adding a prefix header to an iOS project
    DZ论坛常见基本设置问题
    DZ论坛如何去掉“今日”“昨日”发帖数显示?
    Discuz源码
    怎样使Firefox的新建标签页为空白页
    discuz论坛
    TK域名首次注册教程(咸干花生)
    氪星年货 #1:那些来自大牛的真知灼见
    慢性子
    life and penis
  • 原文地址:https://www.cnblogs.com/Zioyi/p/14456816.html
Copyright © 2011-2022 走看看