Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

MSDOS is not dead, it just smells that way. -- Henry Spencer


devel / comp.lang.python / LRU cache

SubjectAuthor
* LRU cacheDino
+- Re: LRU cacheChris Angelico
+- RE: LRU cache<avi.e.gross
+- RE: LRU cache<avi.e.gross
`* Re: LRU cacheMats Wichmann
 `* Re: LRU cacheDino
  `* Re: LRU cacheWeatherby,Gerard
   `- Re: LRU cacheDino

1
LRU cache

<9CTGL.3255637$miq3.78888@fx02.ams4>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=21688&group=comp.lang.python#21688

  copy link   Newsgroups: comp.lang.python
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!newsreader4.netcologne.de!news.netcologne.de!peer01.ams1!peer.ams1.xlned.com!news.xlned.com!peer03.ams4!peer.am4.highwinds-media.com!news.highwinds-media.com!fx02.ams4.POSTED!not-for-mail
MIME-Version: 1.0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101
Thunderbird/102.7.2
Newsgroups: comp.lang.python
Content-Language: en-US
From: din...@no.spam.ar (Dino)
Subject: LRU cache
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Lines: 17
Message-ID: <9CTGL.3255637$miq3.78888@fx02.ams4>
X-Complaints-To: abuse@eweka.nl
NNTP-Posting-Date: Tue, 14 Feb 2023 22:07:01 UTC
Organization: Eweka Internet Services
Date: Tue, 14 Feb 2023 17:07:00 -0500
X-Received-Bytes: 1268
 by: Dino - Tue, 14 Feb 2023 22:07 UTC

Here's my problem today. I am using a dict() to implement a quick and
dirty in-memory cache.

I am stopping adding elements when I am reaching 1000 elements (totally
arbitrary number), but I would like to have something slightly more
sophisticated to free up space for newer and potentially more relevant
entries.

I am thinking of the Least Recently Used principle, but how to implement
that is not immediate. Before I embark on reinventing the wheel, is
there a tool, library or smart trick that will allow me to remove
elements with LRU logic?

thanks

Dino

Re: LRU cache

<mailman.1821.1676414763.20444.python-list@python.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=21691&group=comp.lang.python#21691

  copy link   Newsgroups: comp.lang.python
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!not-for-mail
From: ros...@gmail.com (Chris Angelico)
Newsgroups: comp.lang.python
Subject: Re: LRU cache
Date: Wed, 15 Feb 2023 09:45:50 +1100
Lines: 20
Message-ID: <mailman.1821.1676414763.20444.python-list@python.org>
References: <9CTGL.3255637$miq3.78888@fx02.ams4>
<CAPTjJmpZ+12xzGhZUsG4boKOArPpK7kRCz+EfYiBP5KBUCJahQ@mail.gmail.com>
Mime-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
X-Trace: news.uni-berlin.de tK7PA2/7khrWi+774w8e1QwZN5aAF/mdQARiIwIgrDLA==
Return-Path: <rosuav@gmail.com>
X-Original-To: python-list@python.org
Delivered-To: python-list@mail.python.org
Authentication-Results: mail.python.org; dkim=pass
reason="2048-bit key; unprotected key"
header.d=gmail.com header.i=@gmail.com header.b=C6mx+f6Q;
dkim-adsp=pass; dkim-atps=neutral
X-Spam-Status: OK 0.090
X-Spam-Evidence: '*H*': 0.82; '*S*': 0.00; '2023': 0.07; 'arbitrary':
0.16; 'chrisa': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris
angelico': 0.16; 'logic?': 0.16; 'received:209.85.218': 0.16;
'wrote:': 0.16; 'problem': 0.16; 'feb': 0.17; 'implement': 0.19;
'to:addr:python-list': 0.20; 'space': 0.26; 'library': 0.26;
'thinking': 0.28; 'recently': 0.29; 'elements': 0.32; 'message-
id:@mail.gmail.com': 0.32; 'but': 0.32; 'there': 0.33; 'header:In-
Reply-To:1': 0.34; 'received:google.com': 0.34;
'from:addr:gmail.com': 0.35; 'using': 0.37; 'received:209.85':
0.37; 'received:209': 0.39; 'adding': 0.39; 'least': 0.39; 'wed,':
0.39; 'something': 0.40; 'smart': 0.67; '1000': 0.70; 'reaching':
0.71; 'free': 0.72; 'relevant': 0.73; 'potentially': 0.76;
'quick': 0.77; 'stopping': 0.91; 'trick': 0.91
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;
h=to:subject:message-id:date:from:in-reply-to:references:mime-version
:from:to:cc:subject:date:message-id:reply-to;
bh=+u1zZoYX2n/QeHRa7NIdEsBz17A4c+O1W+jPYMFf300=;
b=C6mx+f6QPGLJmSv+oyFnqo7OpE3deyVue5l3de9nXCyCBK2rj4Sn0yFm/FwMheZ9Tp
SoW0dZkWRoyw9DUYb1mD4cu22W3KWJl6OLCOGIlLxXZB50aS+/28ylhsqEXIjv9P+x8W
gpQ2lJwrseflWbD94giJUxB5FFuv4juuFs7VdgBOJWFOkDLkwB7Z1Fd0gl8cFvBtwsSL
n0gfpOtuMGFC9n+6xAzwNpQX60tVOKTzH05D4TKpXoWIxjUM6RnC3AeBPBv16W2qPgGn
Af0j1at1VyYmacXWuVmVZUETYYWEH8do2hESZXQCNhzkmOmBhe/0gGNVPJkkX17wcmjv
GiZw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=1e100.net; s=20210112;
h=to:subject:message-id:date:from:in-reply-to:references:mime-version
:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;
bh=+u1zZoYX2n/QeHRa7NIdEsBz17A4c+O1W+jPYMFf300=;
b=MYrg331uNvzo8bMvYRKOJFgYdwlrzWpjJCcLk9751HTiUMpi0jWyy7KhkGcGrzyWma
yqF0q+E4fTY2WchqTDHHOvjb2s9SI+4BMzgRYrIwCjXE77zQhdfbwIxIIRsyfKb2qjag
8BFIxys17j7YtIcjMdT7E3QxdeZjYfmdDbfsat24yUcVqBC1W5hKgQxudcSftcFM6ux2
yZ4crKQRbJr7ZgRTA14bnyDgUj6SliuxnaWt8M5wc9RODrzC2b2IjbILHuij2YUFiyFb
EHvxtE/IQDcxTcypI4inwJiqidHOr42t554U8RQ3UBCq6iwT6XsB3qE6szsU5socdyoG
L6NQ==
X-Gm-Message-State: AO0yUKU2aaellO18sQERh3yvnzEp+PGMa6/M3hEROcW/1rr8FLGUakwT
vL6cUt52GHDaEMt4tWfgQkznmB6sohQrH4K67VwR0h7s
X-Google-Smtp-Source: AK7set+YuxOW6bSKgnj5az32ql8IKoO0bnYKl8PhDnW+rjIIp2+Mk5sIbaY2e6jmrWYqGpxn18RtaZNKhufBvLyhY4U=
X-Received: by 2002:a17:907:7ba3:b0:88d:ba79:4317 with SMTP id
ne35-20020a1709077ba300b0088dba794317mr765010ejc.7.1676414761225; Tue, 14 Feb
2023 14:46:01 -0800 (PST)
In-Reply-To: <9CTGL.3255637$miq3.78888@fx02.ams4>
X-BeenThere: python-list@python.org
X-Mailman-Version: 2.1.39
Precedence: list
List-Id: General discussion list for the Python programming language
<python-list.python.org>
List-Unsubscribe: <https://mail.python.org/mailman/options/python-list>,
<mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive: <https://mail.python.org/pipermail/python-list/>
List-Post: <mailto:python-list@python.org>
List-Help: <mailto:python-list-request@python.org?subject=help>
List-Subscribe: <https://mail.python.org/mailman/listinfo/python-list>,
<mailto:python-list-request@python.org?subject=subscribe>
X-Mailman-Original-Message-ID: <CAPTjJmpZ+12xzGhZUsG4boKOArPpK7kRCz+EfYiBP5KBUCJahQ@mail.gmail.com>
X-Mailman-Original-References: <9CTGL.3255637$miq3.78888@fx02.ams4>
 by: Chris Angelico - Tue, 14 Feb 2023 22:45 UTC

On Wed, 15 Feb 2023 at 09:37, Dino <dino@no.spam.ar> wrote:
>
>
> Here's my problem today. I am using a dict() to implement a quick and
> dirty in-memory cache.
>
> I am stopping adding elements when I am reaching 1000 elements (totally
> arbitrary number), but I would like to have something slightly more
> sophisticated to free up space for newer and potentially more relevant
> entries.
>
> I am thinking of the Least Recently Used principle, but how to implement
> that is not immediate. Before I embark on reinventing the wheel, is
> there a tool, library or smart trick that will allow me to remove
> elements with LRU logic?
>

Check out functools.lru_cache :)

ChrisA

RE: LRU cache

<mailman.1823.1676416910.20444.python-list@python.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=21693&group=comp.lang.python#21693

  copy link   Newsgroups: comp.lang.python
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!not-for-mail
From:
Newsgroups: comp.lang.python
Subject: RE: LRU cache
Date: Tue, 14 Feb 2023 18:21:46 -0500
Lines: 78
Message-ID: <mailman.1823.1676416910.20444.python-list@python.org>
References: <9CTGL.3255637$miq3.78888@fx02.ams4>
<000d01d940cb$1c170630$54451290$@gmail.com>
Mime-Version: 1.0
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: 7bit
X-Trace: news.uni-berlin.de psIRmzr9l/zuXBkYvqZ7YABIY1Y4VXHrQUlPD3Kztzaw==
Return-Path: <avi.e.gross@gmail.com>
X-Original-To: python-list@python.org
Delivered-To: python-list@mail.python.org
Authentication-Results: mail.python.org; dkim=pass
reason="2048-bit key; unprotected key"
header.d=gmail.com header.i=@gmail.com header.b=M01G54+t;
dkim-adsp=pass; dkim-atps=neutral
X-Spam-Status: OK 0.116
X-Spam-Level: *
X-Spam-Evidence: '*H*': 0.77; '*S*': 0.00; '2023': 0.07;
'architecture': 0.07; 'queue': 0.07; 'avoided': 0.09; 'moved':
0.09; 'received:108': 0.09; 'url:mailman': 0.15; 'that.': 0.15;
'accessed': 0.16; 'algorithms': 0.16; 'arbitrary': 0.16; 'brute':
0.16; 'dict': 0.16; 'dictionary,': 0.16; 'dictionary.': 0.16;
'easily.': 0.16; 'implements': 0.16; 'logic?': 0.16;
'received:209.85.160.173': 0.16; 'received:mail-
qt1-f173.google.com': 0.16; 'solved': 0.16; 'sorted': 0.16;
'structure.': 0.16; 'tuple': 0.16; 'variant': 0.16; 'wish.': 0.16;
'problem': 0.16; 'values': 0.17; 'message-id:@gmail.com': 0.18;
'implement': 0.19; 'to:addr:python-list': 0.20; 'goal': 0.23;
'skip:- 10': 0.25; 'url-ip:188.166.95.178/32': 0.25; 'url-
ip:188.166.95/24': 0.25; 'url:listinfo': 0.25; 'url-
ip:188.166/16': 0.25; 'seems': 0.26; 'space': 0.26; 'library':
0.26; 'bit': 0.27; 'thinking': 0.28; 'keeping': 0.28; 'recently':
0.29; 'received:209.85.160': 0.31; 'url-ip:188/8': 0.31;
'question': 0.32; 'elements': 0.32; 'end.': 0.32; 'python-list':
0.32; 'structure': 0.32; 'but': 0.32; 'there': 0.33; 'mean': 0.34;
'header:In-Reply-To:1': 0.34; 'received:google.com': 0.34; 'item':
0.35; 'one.': 0.35; 'track': 0.35; 'from:addr:gmail.com': 0.35;
'count': 0.36; 'room': 0.36; 'change': 0.36; 'main': 0.37;
'using': 0.37; 'received:209.85': 0.37; 'hard': 0.37; 'could':
0.38; 'thanks': 0.38; 'received:209': 0.39; 'added': 0.39;
'adding': 0.39; 'least': 0.39; 'use': 0.39; 'date.': 0.40;
'something': 0.40; 'want': 0.40; 'should': 0.40; 'included': 0.61;
'search': 0.61; 'method': 0.61; 'from:': 0.62; 'to:': 0.62;
'simply': 0.63; 'once': 0.63; 'updates': 0.64; 'key': 0.64; 'in:':
0.64; 'thus': 0.64; 'your': 0.64; 'maximum': 0.67; 'smart': 0.67;
'items': 0.68; 'order': 0.69; 'adds': 0.69; 'and,': 0.69; 'end,':
0.69; 'times': 0.69; '1000': 0.70; 'depending': 0.70; 'speed':
0.71; 'reaching': 0.71; 'free': 0.72; 'deal': 0.73; 'relevant':
0.73; 'url-ip:104.110.240/24': 0.75; 'url-ip:104.110/16': 0.75;
'finds': 0.76; 'handles': 0.76; 'potentially': 0.76; 'treat':
0.76; 'quick': 0.77; 'sent:': 0.78; 'thousand': 0.84; 'newest':
0.84; 'ordered': 0.84; 'oldest': 0.91; 'stopping': 0.91; 'trick':
0.91; 'storage': 0.95
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;
h=thread-index:content-language:content-transfer-encoding
:mime-version:message-id:date:subject:in-reply-to:references:to:from
:from:to:cc:subject:date:message-id:reply-to;
bh=91Vm7101i25RMN4QQl2SwGQ3+rQCLvF3aHJMnWInWss=;
b=M01G54+tW+2wvHiL3s2qTJI6rKFSRhuKBZJ8nV2vNUYm/ZSZOotqeYf9B+HbkLRF6U
7k9cV5KBsgsUR6Q+kyizcMJ4o2Fj1mLySxZqtFSQ0U6qjz2JYwbUxHAEupZ8NFjq2O+B
GQao1HAE9Ni2aWag5dtLHUKsg8mVQdKFCbw3UUMcZUlc4+LVSUTcEc8FaiZmjDIZBg+d
UKoRPmRN1AOUWi3b5nJeYB+aYSfOOceI42mLCnECY1Xz8vmN3tLQMvFOa6UFdKePhgH4
WTOWJfjmmPTTzgWQ21iwgqRJIH/IWGQbsMXe2yRp+v+x4NVbWBYGXnAMFhjnxG5kMDnK
RquA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=1e100.net; s=20210112;
h=thread-index:content-language:content-transfer-encoding
:mime-version:message-id:date:subject:in-reply-to:references:to:from
:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;
bh=91Vm7101i25RMN4QQl2SwGQ3+rQCLvF3aHJMnWInWss=;
b=v2JCohVwe8WkvfFo4BQBHals1lFAdxuxpctFYtsLYa8qYD/ryktQs48E7HD2UXgsDO
Yk8Jrvw6ZwrWJpkimy/ciUzv0Rt8E9Ysp4yqd4/qsKQoBuQnPtWv3gNuygNFKMQK4pNI
VzXZzJRdZQlVpsxc5eUxwhn3Em7KSNqXH2nBZiSMGvyW603YyT9A6M0791aagK+jSJgS
E/c0vGG7rrj1Qnscs0cO4Wh02OuVbRvoq77j/XJx2tyWWenpTT4ayZe0BHVLuPTtJK3U
U8Y6fGiWWvEMXn7kPcuEMbCjcEGaKqGLZrtIZwQIvDxOrSLH5F2UeHKkz+JJBdyRLW2R
/+nw==
X-Gm-Message-State: AO0yUKUvzjmovSQVGwwVmleSsfnX/CK2oD0bGa4I6MnZ4hn71nR6ZR2H
/vXFN3haUHkobFV9uJRj3pj2ERJBj/E=
X-Google-Smtp-Source: AK7set+YI42fK3NEfj1+Hfr1nClGc2eCg0uTuxd7bZFIORKyRTCnODxa92NW02CzSkIfn3DvIjYe9A==
X-Received: by 2002:a05:622a:1106:b0:3b8:6c4d:488a with SMTP id
e6-20020a05622a110600b003b86c4d488amr73234qty.37.1676416907493;
Tue, 14 Feb 2023 15:21:47 -0800 (PST)
In-Reply-To: <9CTGL.3255637$miq3.78888@fx02.ams4>
X-Mailer: Microsoft Outlook 16.0
Content-Language: en-us
Thread-Index: AQJGlzwDgCGW5VBSn3MQkjhhvMLJxa30YasA
X-BeenThere: python-list@python.org
X-Mailman-Version: 2.1.39
Precedence: list
List-Id: General discussion list for the Python programming language
<python-list.python.org>
List-Unsubscribe: <https://mail.python.org/mailman/options/python-list>,
<mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive: <https://mail.python.org/pipermail/python-list/>
List-Post: <mailto:python-list@python.org>
List-Help: <mailto:python-list-request@python.org?subject=help>
List-Subscribe: <https://mail.python.org/mailman/listinfo/python-list>,
<mailto:python-list-request@python.org?subject=subscribe>
X-Mailman-Original-Message-ID: <000d01d940cb$1c170630$54451290$@gmail.com>
X-Mailman-Original-References: <9CTGL.3255637$miq3.78888@fx02.ams4>
 by: - Tue, 14 Feb 2023 23:21 UTC

Dino,

If your question is understood, you want to treat a dictionary as a sort of
queue with a maximum number of entries. And, you want to remove some kind of
least useful item to make room for any new one.

Most dictionaries now have entries in the order they were entered. There may
already be some variant out there that implements this but it should not be
hard to create.

So you could simply change the method that adds an item to the dictionary.
If the new next item is not already in the dictionary, simply remove the
first item using whatever method you wish.

Getting all the keys may be avoided by using an iterator once as in:
next(iter( my_dict.keys() )) or something like that.

You can then remove that item using the key and insert your new item at the
end.

Of course, that is not least recently used but least recently entered.

To deal with keeping track of what was accessed last or never, is a problem
not trivially solved with just a dictionary. I mean you could store a tuple
for each item that included a date and a payload as the value, and you could
then search all the values and find the one with the oldest date. That seems
a bit much so another architecture could be to maintain another data
structure holding keys and dates that perhaps you keep sorted by date and
every time the cache accesses a value, it finds the item in the second
storage and updates the date and moves the item to the end of the
structure.

But note that some may want to keep an access count so you always know how
many times an item has been re-used and thus not remove them as easily.

The main goal of a dictionary is to speed up access and make it almost
linear. Your algorithm can add so much overhead, depending on how it is
done, that it can defeat the purpose.

What some might do is skip the dictionary and use some kind of queue like a
dequeue that handles your thousand entries and new items are added at the
end, items accessed moved to the front, and a brute force search is used to
find an entry. But note some algorithms like that may end up removing the
newest item immediately as it is least recently used if placed at the end.

It may be an Ordered Dict is one solution as shown here:

https://www.geeksforgeeks.org/lru-cache-in-python-using-ordereddict/

-----Original Message-----
From: Python-list <python-list-bounces+avi.e.gross=gmail.com@python.org> On
Behalf Of Dino
Sent: Tuesday, February 14, 2023 5:07 PM
To: python-list@python.org
Subject: LRU cache

Here's my problem today. I am using a dict() to implement a quick and dirty
in-memory cache.

I am stopping adding elements when I am reaching 1000 elements (totally
arbitrary number), but I would like to have something slightly more
sophisticated to free up space for newer and potentially more relevant
entries.

I am thinking of the Least Recently Used principle, but how to implement
that is not immediate. Before I embark on reinventing the wheel, is there a
tool, library or smart trick that will allow me to remove elements with LRU
logic?

thanks

Dino
--
https://mail.python.org/mailman/listinfo/python-list

RE: LRU cache

<mailman.1824.1676425216.20444.python-list@python.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=21694&group=comp.lang.python#21694

  copy link   Newsgroups: comp.lang.python
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!lilly.ping.de!fu-berlin.de!uni-berlin.de!not-for-mail
From:
Newsgroups: comp.lang.python
Subject: RE: LRU cache
Date: Tue, 14 Feb 2023 20:40:13 -0500
Lines: 40
Message-ID: <mailman.1824.1676425216.20444.python-list@python.org>
References: <9CTGL.3255637$miq3.78888@fx02.ams4>
<CAPTjJmpZ+12xzGhZUsG4boKOArPpK7kRCz+EfYiBP5KBUCJahQ@mail.gmail.com>
<002601d940de$72f115a0$58d340e0$@gmail.com>
Mime-Version: 1.0
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: 7bit
X-Trace: news.uni-berlin.de EC6xeq05E0AC+1lxC2BPDQvvm9eY++fmo/YQUcs6xvug==
Return-Path: <avi.e.gross@gmail.com>
X-Original-To: python-list@python.org
Delivered-To: python-list@mail.python.org
Authentication-Results: mail.python.org; dkim=pass
reason="2048-bit key; unprotected key"
header.d=gmail.com header.i=@gmail.com header.b=fvoo8Ho/;
dkim-adsp=pass; dkim-atps=neutral
X-Spam-Status: OK 0.074
X-Spam-Evidence: '*H*': 0.85; '*S*': 0.00; '2023': 0.07; 'angelico':
0.09; 'received:108': 0.09; 'url:mailman': 0.15; 'accessed': 0.16;
'arbitrary': 0.16; 'chrisa': 0.16; 'functions.': 0.16; 'logic?':
0.16; 'wrote:': 0.16; 'problem': 0.16; 'feb': 0.17; 'message-
id:@gmail.com': 0.18; 'implement': 0.19; 'to:addr:python-list':
0.20; 'skip:- 10': 0.25; 'url-ip:188.166.95.178/32': 0.25; 'url-
ip:188.166.95/24': 0.25; 'url:listinfo': 0.25; 'url-
ip:188.166/16': 0.25; 'space': 0.26; 'library': 0.26; 'chris':
0.28; 'purpose': 0.28; 'thinking': 0.28; 'recently': 0.29;
'received:209.85.160': 0.31; 'url-ip:188/8': 0.31; 'elements':
0.32; 'python-list': 0.32; 'but': 0.32; 'there': 0.33; 'header:In-
Reply-To:1': 0.34; 'received:google.com': 0.34;
'from:addr:gmail.com': 0.35; 'using': 0.37; 'received:209.85':
0.37; 'could': 0.38; 'received:209': 0.39; 'adding': 0.39;
'least': 0.39; 'shared': 0.39; 'wed,': 0.39; 'something': 0.40;
'from:': 0.62; 'to:': 0.62; 're:': 0.64; 'smart': 0.67; '1000':
0.70; 'reaching': 0.71; 'free': 0.72; 'relevant': 0.73;
'features.': 0.76; 'potentially': 0.76; 'quick': 0.77; 'sent:':
0.78; 'extra': 0.84; 'stopping': 0.91; 'trick': 0.91
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;
h=thread-index:content-language:content-transfer-encoding
:mime-version:message-id:date:subject:in-reply-to:references:to:from
:from:to:cc:subject:date:message-id:reply-to;
bh=NVTCSZy+nqeOGVKiNxfgbroFNHZ+GssGMDKgpDyi1rY=;
b=fvoo8Ho/mkRHMnh6puDvLjydxaXoy/+LxUuidaD3BvTJpZWwmPbpRRrLrhp5dLswMZ
uAfQeNIsJGg6QH5+mCNIRBuu50bZdddMkmknE4V88qgSKX+jQ/ti62rapMCmO2CKHHql
WKD1ZwOvUmjW8J/yYqVMVD2dhGjxjRfoDePApofm/stsKnM76yFVMi1ceZ460LCcM/oK
5JOVlkPtABiaU9Gm4KrOOFwF8pBLk76rxRoLwfEnORPfDe95T978YU+0IdAMbFkV32iJ
/ccfIF7K608oCi+XoJvMROvx1HzmC//5fRQNxZbJ2ZIx1PO4RzywpMX4JrJlkgr5gqZk
yRFg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=1e100.net; s=20210112;
h=thread-index:content-language:content-transfer-encoding
:mime-version:message-id:date:subject:in-reply-to:references:to:from
:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;
bh=NVTCSZy+nqeOGVKiNxfgbroFNHZ+GssGMDKgpDyi1rY=;
b=RN7v5bhffCevcH6HXdtERecUQzs6/bgjsmZEQVjpUYtSjbiuLUVWOMPsyCVF6yLRXG
WK/1BIjWI4v2wHLa1sEZVnuUrVdLfZg/A5+OHb6SvevaGAghQg2Y5hgu6yz1t4edlu9D
GHKgjKfJZJC/e6qrDAbeYWEoOP4qgO4edcgub4PzD3tls2VxXEF1CcogHg+96bgYt/QE
x8zxjDA66/GMkAsMVSPrEonVPZoWQDETq0Q4KtPf37ZCac4g/Wz4zxD1/UorB/YDxHI8
Hnnq6bSLaq74FS504221+cY9Gmbvw7zFwZ/eWgA+Ue8f36nNv/wuEC3vNwDtlGSliF65
EYaw==
X-Gm-Message-State: AO0yUKWEoiwUAEiT+1lreQmjhMZTUZSs1l+ph4a56OTiuRfhZGBSx5oY
1jRiVJ+7of1Oet5ENL1FA7wJuXi/K+w=
X-Google-Smtp-Source: AK7set8fyBl9JsC2FFabRbctr2W41iz2o3l2omRrdSTLChIMBgIXPPZ6pw1JVdkrx7+jZ0O2TIwyng==
X-Received: by 2002:a05:622a:170e:b0:3b8:6bef:61de with SMTP id
h14-20020a05622a170e00b003b86bef61demr799441qtk.34.1676425213707;
Tue, 14 Feb 2023 17:40:13 -0800 (PST)
In-Reply-To: <CAPTjJmpZ+12xzGhZUsG4boKOArPpK7kRCz+EfYiBP5KBUCJahQ@mail.gmail.com>
X-Mailer: Microsoft Outlook 16.0
Content-Language: en-us
Thread-Index: AQJGlzwDgCGW5VBSn3MQkjhhvMLJxQHKT6pnreY7k9A=
X-BeenThere: python-list@python.org
X-Mailman-Version: 2.1.39
Precedence: list
List-Id: General discussion list for the Python programming language
<python-list.python.org>
List-Unsubscribe: <https://mail.python.org/mailman/options/python-list>,
<mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive: <https://mail.python.org/pipermail/python-list/>
List-Post: <mailto:python-list@python.org>
List-Help: <mailto:python-list-request@python.org?subject=help>
List-Subscribe: <https://mail.python.org/mailman/listinfo/python-list>,
<mailto:python-list-request@python.org?subject=subscribe>
X-Mailman-Original-Message-ID: <002601d940de$72f115a0$58d340e0$@gmail.com>
X-Mailman-Original-References: <9CTGL.3255637$miq3.78888@fx02.ams4>
<CAPTjJmpZ+12xzGhZUsG4boKOArPpK7kRCz+EfYiBP5KBUCJahQ@mail.gmail.com>
 by: - Wed, 15 Feb 2023 01:40 UTC

Chris,

That is a nice decorator solution with some extra features.

We don't know if the OP needed a cache that was more general purpose and
could be accessed from multiple points, and shared across multiple
functions.

-----Original Message-----
From: Python-list <python-list-bounces+avi.e.gross=gmail.com@python.org> On
Behalf Of Chris Angelico
Sent: Tuesday, February 14, 2023 5:46 PM
To: python-list@python.org
Subject: Re: LRU cache

On Wed, 15 Feb 2023 at 09:37, Dino <dino@no.spam.ar> wrote:
>
>
> Here's my problem today. I am using a dict() to implement a quick and
> dirty in-memory cache.
>
> I am stopping adding elements when I am reaching 1000 elements
> (totally arbitrary number), but I would like to have something
> slightly more sophisticated to free up space for newer and potentially
> more relevant entries.
>
> I am thinking of the Least Recently Used principle, but how to
> implement that is not immediate. Before I embark on reinventing the
> wheel, is there a tool, library or smart trick that will allow me to
> remove elements with LRU logic?
>

Check out functools.lru_cache :)

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list

Re: LRU cache

<mailman.1831.1676481401.20444.python-list@python.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=21703&group=comp.lang.python#21703

  copy link   Newsgroups: comp.lang.python
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!not-for-mail
From: mat...@wichmann.us (Mats Wichmann)
Newsgroups: comp.lang.python
Subject: Re: LRU cache
Date: Tue, 14 Feb 2023 17:36:49 -0700
Lines: 31
Message-ID: <mailman.1831.1676481401.20444.python-list@python.org>
References: <9CTGL.3255637$miq3.78888@fx02.ams4>
<a00f333f-b3cf-1122-4efa-62fd07ce6748@wichmann.us>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
X-Trace: news.uni-berlin.de L+jqS/moA6VfbvGKcXdE4QuTwFMf5FoxQw7oi5jkvhMg==
Return-Path: <mats@wichmann.us>
X-Original-To: python-list@python.org
Delivered-To: python-list@mail.python.org
Authentication-Results: mail.python.org; dkim=pass
reason="1024-bit key; unprotected key"
header.d=pobox.com header.i=@pobox.com header.b=wzDXhWXJ;
dkim-adsp=none (unprotected policy); dkim-atps=neutral
X-Spam-Status: UNSURE 0.308
X-Spam-Level: ***
X-Spam-Evidence: '*H*': 0.42; '*S*': 0.03; 'e.g.': 0.07; 'tutorial':
0.12; 'memory': 0.15; 'arbitrary': 0.16; 'logic?': 0.16; 'ones.':
0.16; 'received:64.147': 0.16; 'stats': 0.16; 'wrote:': 0.16;
'problem': 0.16; 'probably': 0.17; 'implement': 0.19; 'to:addr
:python-list': 0.20; 'maybe': 0.22; 'depends': 0.25; 'space':
0.26; 'behavior': 0.26; 'library': 0.26; 'expect': 0.28;
'thinking': 0.28; 'recently': 0.29; 'header:User-Agent:1': 0.30;
'module': 0.31; '(as': 0.32; 'elements': 0.32; 'but': 0.32;
'there': 0.33; 'header:In-Reply-To:1': 0.34; 'really': 0.37;
'using': 0.37; 'received:192.168': 0.37; 'adding': 0.39; 'least':
0.39; 'list': 0.39; 'something': 0.40; 'want': 0.40; 'here': 0.62;
'needs.': 0.64; 'your': 0.64; 'look': 0.65; 'smart': 0.67;
'received:64': 0.67; 'ones,': 0.69; '1000': 0.70; 'reaching':
0.71; 'free': 0.72; 'relevant': 0.73; "you'll": 0.73;
'combination': 0.76; 'need,': 0.76; 'potentially': 0.76; 'quick':
0.77; 'quickly': 0.80; 'position': 0.81; 'crew': 0.84;
'motivated': 0.84; 'ordering': 0.84; 'skip:m 50': 0.84;
'stopping': 0.91; 'trick': 0.91
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed; d=pobox.com; h=message-id
:date:mime-version:subject:to:references:from:in-reply-to
:content-type:content-transfer-encoding; s=sasl; bh=86Hk93r6O9cn
3WSD1Ha0SGcKR499WYdG5NYCK53bNiY=; b=wzDXhWXJTSdLXvY5t1YxBDAwWYE4
a28ThVSYZ2BlfBeTzeH7kTCIeCzOjWmjBd8BFMuXxlz9Eso+058CKktyfWq0CrbZ
B8PGzrJJgMNRd70NbWJgu7BA8qJYqqDj+VAz0I7mnKVE2GcnrdA7AIDzLfr+EVhQ
OuicnWyilebrweU=
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed; d=wichmann.us;
h=message-id:date:mime-version:subject:to:references:from:in-reply-to:content-type:content-transfer-encoding;
s=2018-07.pbsmtp; bh=86Hk93r6O9cn3WSD1Ha0SGcKR499WYdG5NYCK53bNiY=;
b=T1JpC+PkUxxyasw8Hl3pg+BJKYvDPaKSdf0OK51hO6GBqHnIjx64fJTc6hT7n1Gnx3icG92e2kp8S0USopEDHfKWmKrY4pIoIy+X3RSyPCpobNY0JwzHMyHKcjAVUOrsm1ghKrUqY3N/Y6yFtdSLHRvq1l+0Jg11E9oW0tPqvKI=
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101
Thunderbird/102.7.1
Content-Language: en-US
In-Reply-To: <9CTGL.3255637$miq3.78888@fx02.ams4>
X-Pobox-Relay-ID: D61E818E-ACC8-11ED-A404-307A8E0A682E-81526775!pb-smtp2.pobox.com
X-Mailman-Approved-At: Wed, 15 Feb 2023 12:16:40 -0500
X-BeenThere: python-list@python.org
X-Mailman-Version: 2.1.39
Precedence: list
List-Id: General discussion list for the Python programming language
<python-list.python.org>
List-Unsubscribe: <https://mail.python.org/mailman/options/python-list>,
<mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive: <https://mail.python.org/pipermail/python-list/>
List-Post: <mailto:python-list@python.org>
List-Help: <mailto:python-list-request@python.org?subject=help>
List-Subscribe: <https://mail.python.org/mailman/listinfo/python-list>,
<mailto:python-list-request@python.org?subject=subscribe>
X-Mailman-Original-Message-ID: <a00f333f-b3cf-1122-4efa-62fd07ce6748@wichmann.us>
X-Mailman-Original-References: <9CTGL.3255637$miq3.78888@fx02.ams4>
 by: Mats Wichmann - Wed, 15 Feb 2023 00:36 UTC

On 2/14/23 15:07, Dino wrote:
>
> Here's my problem today. I am using a dict() to implement a quick and
> dirty in-memory cache.
>
> I am stopping adding elements when I am reaching 1000 elements (totally
> arbitrary number), but I would like to have something slightly more
> sophisticated to free up space for newer and potentially more relevant
> entries.
>
> I am thinking of the Least Recently Used principle, but how to implement
> that is not immediate. Before I embark on reinventing the wheel, is
> there a tool, library or smart trick that will allow me to remove
> elements with LRU logic?

It depends here how fancy you want to get. If you really need the
behavior of a size-limited cache and you expect there to be a lot of
churn, then you'll probably want a combination of data structures...
e.g. a dict-like thing for quick hashed lookups (means your "keys" need
to be hashable) and a doubly-linked list for ordering so you can quickly
move a hit to the most-recent position - and maybe you want to keep
cache stats as well.

Do look at functools if that well-tested standard library module fits
your needs. If you need, or are motivated (as a learning experience?) to
roll your own, my memory tells me the RealPython crew did a tutorial on
implementing an LRU cache, might be worth a look (not sure if this is
one of the all-free ones, or one of the
must-be-a-paid-subscriber-to-get-the-advanced-stuff ones.

Re: LRU cache

<NPaHL.2601707$14z3.887943@fx11.ams4>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=21708&group=comp.lang.python#21708

  copy link   Newsgroups: comp.lang.python
Path: i2pn2.org!i2pn.org!weretis.net!feeder8.news.weretis.net!newsreader4.netcologne.de!news.netcologne.de!peer01.ams1!peer.ams1.xlned.com!news.xlned.com!peer02.ams4!peer.am4.highwinds-media.com!news.highwinds-media.com!fx11.ams4.POSTED!not-for-mail
MIME-Version: 1.0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101
Thunderbird/102.7.2
Subject: Re: LRU cache
Newsgroups: comp.lang.python
References: <9CTGL.3255637$miq3.78888@fx02.ams4>
<a00f333f-b3cf-1122-4efa-62fd07ce6748@wichmann.us>
<mailman.1831.1676481401.20444.python-list@python.org>
Content-Language: en-US
From: din...@no.spam.ar (Dino)
In-Reply-To: <mailman.1831.1676481401.20444.python-list@python.org>
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Lines: 10
Message-ID: <NPaHL.2601707$14z3.887943@fx11.ams4>
X-Complaints-To: abuse@eweka.nl
NNTP-Posting-Date: Wed, 15 Feb 2023 19:58:37 UTC
Organization: Eweka Internet Services
Date: Wed, 15 Feb 2023 14:58:37 -0500
X-Received-Bytes: 1157
 by: Dino - Wed, 15 Feb 2023 19:58 UTC

Thank you Mats, Avi and Chris

btw, functools.lru_cache seems rather different from what I need, but
maybe I am missing something. I'll look closer.

On 2/14/2023 7:36 PM, Mats Wichmann wrote:
> On 2/14/23 15:07, Dino wrote:
>>

Re: LRU cache

<mailman.1840.1676601634.20444.python-list@python.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=21713&group=comp.lang.python#21713

  copy link   Newsgroups: comp.lang.python
Path: i2pn2.org!i2pn.org!news.neodome.net!fu-berlin.de!uni-berlin.de!not-for-mail
From: gweathe...@uchc.edu (Weatherby,Gerard)
Newsgroups: comp.lang.python
Subject: Re: LRU cache
Date: Fri, 17 Feb 2023 02:40:21 +0000
Lines: 112
Message-ID: <mailman.1840.1676601634.20444.python-list@python.org>
References: <9CTGL.3255637$miq3.78888@fx02.ams4>
<a00f333f-b3cf-1122-4efa-62fd07ce6748@wichmann.us>
<mailman.1831.1676481401.20444.python-list@python.org>
<NPaHL.2601707$14z3.887943@fx11.ams4>
<SJ0PR14MB5864935B923047D8EFF0FD54B9A19@SJ0PR14MB5864.namprd14.prod.outlook.com>
Mime-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
X-Trace: news.uni-berlin.de vKmVZ89nicIIP+GrTDY+Ww4azXKkkpDb9mWmqrx6TTMQ==
Return-Path: <prvs=0412dfa57b=gweatherby@uchc.edu>
X-Original-To: python-list@python.org
Delivered-To: python-list@mail.python.org
Authentication-Results: mail.python.org; dkim=pass
reason="2048-bit key; unprotected key"
header.d=uchc.edu header.i=@uchc.edu header.b=g3X8lnL0;
dkim-adsp=pass; dkim-atps=neutral
X-Spam-Status: OK 0.006
X-Spam-Evidence: '*H*': 0.99; '*S*': 0.00; 'url-ip:140.82/16': 0.03;
'def': 0.04; 'random': 0.05; '2023': 0.07; 'loop': 0.07; 'else:':
0.09; 'int': 0.09; 'received:namprd14.prod.outlook.com': 0.09;
'&gt;': 0.14; 'url:github': 0.14; 'import': 0.15; 'url:mailman':
0.15; 'url-ip:140/8': 0.15; '&lt;': 0.16; '***': 0.16; '-&gt;':
0.16; 'all:': 0.16; 'any)': 0.16; 'assert': 0.16; 'avi': 0.16;
'int)': 0.16; 'key:': 0.16; 'mats': 0.16; 'mats,': 0.16; 'none)':
0.16; 'none:': 0.16; 'present,': 0.16; 'python3': 0.16;
'something.': 0.16; 'tuple': 0.16; 'typing': 0.16;
'url:urldefense': 0.16; 'url:v3': 0.16; 'wichmann': 0.16;
'wrote:': 0.16; 'values': 0.17; 'pm,': 0.19; 'to:addr:python-
list': 0.20; 'maybe': 0.22; 'skip:_ 10': 0.22; 'to:name:python-
list@python.org': 0.24; 'url:listinfo': 0.25; 'seems': 0.26;
'opening': 0.26; 'received:edu': 0.26; 'wednesday,': 0.26; 'old':
0.27; 'chris': 0.28; 'email addr:python.org&gt;': 0.28;
'recently': 0.29; 'raise': 0.31; 'think': 0.32; 'python-list':
0.32; 'but': 0.32; "i'll": 0.33; 'header:In-Reply-To:1': 0.34;
'count': 0.36; 'header:Received:8': 0.36; 'missing': 0.37;
'received:filterd': 0.37; 'received:pps.filterd': 0.37; 'class':
0.37; 'url-ip:13.107/16': 0.38; 'date:': 0.39; 'use': 0.39;
'email.': 0.61; 'skip:o 10': 0.61; 'from:': 0.62; 'to:': 0.62;
'range': 0.64; 'key': 0.64; 're:': 0.64; 'look': 0.65; 'url-
ip:104.18/16': 0.67; 'skip:e 20': 0.67; 'skip:# 10': 0.68;
'counter': 0.69;
'received:nam12-bn8-obe.outbound.protection.outlook.com': 0.69;
'url-ip:52.6/16': 0.69; '1000': 0.70; 'average': 0.70; 'del':
0.70; 'clicking': 0.76; 'need,': 0.76; 'links.': 0.81; 'largest':
0.84; 'size:': 0.84; 'attention:': 0.84; 'avg': 0.84; 'backwards':
0.84; 'email name:&lt;python-list': 0.84; 'skip:& 50': 0.84;
'skip:d 30': 0.86; 'exists': 0.91; 'oldest': 0.91; 'storage': 0.95
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=uchc.edu;
h=from : to : subject :
date : message-id : references : in-reply-to : content-type :
mime-version; s=UCHC03162020;
bh=eDgD71wizOxQdjr+OBoUVcNJGBJ18C0SJkVtBus3i8k=;
b=g3X8lnL0YIha0kQhTE5XmY4zCSx+TaCHMiOkIswZM6meR3AaOMQitiFd1coXmuNqJxA1
bDB5uzqATIn0COBmfO5I/pQag0SYfTzV2uiGd3xgx6rxad70xeEcPn5etDKR19esJ8KJ
MQwK7iuj6OAoMFmFwPN88QHRMdwKTXlPLkvastN9EluT0IbVCNZJX1WyRhJmaY2nKvJK
Ual/jY7esRXTi+SMOEKPCjB+hDIj0tvO+28j3li1cLJ/xrwlkonKyiTAV8Nfs/Dx2WFV
hiFpNi1EXmQ3gAMFk/aZhNDFlJCtHmzEZF1FDS+w+DXPiClbQA1GsR8/52Dmogd2+xZ2 tw==
ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;
b=mypAr8VPBHHzkVJz/tI+/4Tj7FyOB8rH9uMei5Kp2MKriX8sz8TgKyXc2qI5W3qI/OdBajqigjFl2807hab2gNWymmu+ptYvuSjwNhU13oc7tpeNLhJjYqKAE8uCz7vPNPjck75doaf54a91ysuP2o3CD5EQ/Tv47Mf1rbVmEcyWcmYq0WLk39MgWcWPb0gmaBJNsejW23dNUJ0oUVR5ptl6YOB0ZvHAxwBivzk7Zt6lgI5xm8ktE0bmE/T9zeZiMzbHcNUaHgG7cFRvJCTyEOgIHQf0xO+JSebDclHlDfoW5I9Uy20Q1YFhogVgvGeHzfJYchqD++A0rG7y/VJpdQ==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;
s=arcselector9901;
h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;
bh=eDgD71wizOxQdjr+OBoUVcNJGBJ18C0SJkVtBus3i8k=;
b=IgPZJ0Ctjvbjzo+/xUDWW1K3z2ume1Flk2fd+2AjhvR6vqOFzsXDXDzGiu6c0bNLD0cu2tt4iYS/7MXdCv5ObSxymfQa6E4/qM1CAUHsm/gg248K/JLEkt+Gi4eSt5hFXS6nmf1Esmlbi8jCnh3PUDPNvEAJrEBxC0YWnNVIyBwpadmUhyOW0erc0XsLoIorRqmcVkAbyXUYTOTfCMoRg79CTZ1modly4X4XimN+I/JiCybauenMYT1WmgpRlAb6buuRFAzh8UjKdOojFtFpB4ggx7zeDuaaEBcGVSZGMa9AOtQ56JsFpFPd8pQ079JqUU0e1qFRaBXdEYinHkUeUg==
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass
smtp.mailfrom=uchc.edu; dmarc=pass action=none header.from=uchc.edu;
dkim=pass header.d=uchc.edu; arc=none
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=uchc.onmicrosoft.com;
s=selector2-uchc-onmicrosoft-com;
h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
bh=eDgD71wizOxQdjr+OBoUVcNJGBJ18C0SJkVtBus3i8k=;
b=nMK4AI0tQToKVo2PVwuhikCCY4m0RgEsGZ5pRZ/ae6TvRnmf17wi+ayf7TxOPlpVWNkSmk0B13kiUEBzie92MNvJpBooPaMuMptlhAIrCgD5Qu9vrUUxWggr/TDjtI213h9PD7izpkyrTPTAkFlzhyyXPzKoY+nzT2n4t2wmiEU=
Thread-Topic: LRU cache
Thread-Index: AQHZQMTy4xbAip4d/kSMMBcVRAT8qq7PKaSAgAFG/C6AAf8HxQ==
In-Reply-To: <NPaHL.2601707$14z3.887943@fx11.ams4>
Accept-Language: en-US
Content-Language: en-US
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
x-ms-publictraffictype: Email
x-ms-traffictypediagnostic: SJ0PR14MB5864:EE_|DS0PR14MB7181:EE_
x-ms-office365-filtering-correlation-id: 55946f95-c7f1-49c2-8e9c-08db109050bb
x-ms-exchange-senderadcheck: 1
x-ms-exchange-antispam-relay: 0
x-microsoft-antispam: BCL:0;
x-microsoft-antispam-message-info: yuYGC8QYMUF6RYz81dANH8IQb9ZYZi1sRkIGNymgv2RBZBSo9WwEN3kska2ZaDgtrLJ/m3xG/tz10K4NJllFmIahWdl7vNt5nFkjFgb4vXJT74Z0uG8lCTXasqHHA9cg0x/MW4lLZ+Rqg01TGKQ0kEfZq534qMzI61NrGW0xR9NcApooF4j3x9Fgb/xqpiEDvwDfNfIEkAa8DConDEzytEGT51ORbw89N81l2ozR2Gtra+5w/Lfidusuu7GYhdAtq0MgaoxnMA4BcA83NkOBz0DS3WKasRfBzg9LBl0IpZLinfu8lrWThnHsH3d+TWrDDInAMfoC6Gf6zmfMTqTTxDsvkymMqD5QPoobVS0MuwgCYW3fIdU1H6To6mY9pfXvtIhQrJVQRTgctwcIwmv9hY7f2Qq0zqcxmMEYikEaA8Yfi/ZbhHXhKUYfhCMrIEXtkNkIsXbEMdVRbK1WuY1IgKWv3huKt2FHHgiFN9no83/8zW026VMn8Bnz8xaupHV0iUNidsNk0gDudrQkEd6T2lqqv3VsCPUTvOiLP2zC34nZqcirH7w7v8zgY040Atp+SHA4TedW8w9ds16D68uXnzPicQcSqu7Z49j3teCHLtk+fBKi3Vl+Em0c0EhGvS8I2u/2SnrsrF75GzvK4FRIe8UhmM6ZyGhADtrcPQ8fd/y+6FUBtOKUzeWP+89+Jjb2
x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;
IPV:NLI; SFV:NSPM; H:SJ0PR14MB5864.namprd14.prod.outlook.com; PTR:; CAT:NONE;
SFS:(13230025)(4636009)(376002)(396003)(136003)(346002)(366004)(39860400002)(451199018)(83380400001)(8936002)(5660300002)(75432002)(33656002)(41300700001)(91956017)(38070700005)(8676002)(66556008)(6916009)(166002)(66446008)(66476007)(64756008)(7116003)(76116006)(66946007)(86362001)(52536014)(41320700001)(55016003)(38100700002)(3480700007)(786003)(122000001)(316002)(2906002)(53546011)(7696005)(6506007)(478600001)(966005)(9686003)(71200400001)(186003)(26005);
DIR:OUT; SFP:1101;
x-ms-exchange-antispam-messagedata-chunkcount: 1
x-ms-exchange-antispam-messagedata-0: wRg03ziqtISXeuumSNHX4ZwpOE7LV9Kvbq8hpWZqI1P1YppRoLKxyx4Wqqcp
PJWowrgb/n34zDEPOs1wtxFjM5G9uQQKDcEKjoTb3Aia8RHw5M5b5xutqmQ/
ahGEpatkrdmbb7dpCY9cHLW1Wa2VrrEEIewj37Ns5FPMsg72VKj+1R+iJt9M
KYBqx/X32NlfaJ30h9sZ2Zwpk4Lsz7t3FO3B1bSqqa4QTvBz2jMVw2KJVAfX
64BHqeNzXAlTvasxxqv28XiHn/RwR5imla2klsJ0nPWzpiMpZoVT77jaQXei
xqssr2kWWc0fM673tKtbUoc1vNheC5+7PVZV6hkOcQfLZrWfjBkdSyIaJf6e
W26E9HOAoazMkE3yrb2oTnWf7g2FElJ4IdsJiumCsddFSufk8Bv1A+mX4y7r
xWG58fP1JeZxvyR90K0+znmXQ4lK8VslqS/Ie5HDmh+W9u3CToTJe6V7t8Vn
JUDck/MqchAKi9FtGCgA0WJWcvuNg7+c6/5mkjwuBOZYXR6D+uXB3XcyTc0e
m6vYeKEalQnNKwce9qDdchO7IAFTesaJpcxSA06z3J70ARjeJlQdL1M57Vpo
qRZ83xiW+XQQOw/37pykNJtn3gXj6sWUTuAekSWLu9gE8MekDmzBlqW+F4iq
kdavyaMqdYK5V5uXRK8kIuPe+YtEkmbh38hXt7/93LHGHb9mgeKhdsk7qZ8Z
rO9F51AV7RYeQwxo6Xx9tgzacDxPpmxs+eopOtsdVyuj3ONlK4U0N1G5X44p
Lc1lKsDbDW/fteY+MlesaS7oZUIPqyTHFQhugavXppohpczj2b8VJJOPXa0W
crIaLRO6TfbnnScEuReSA6BDP3w1FwGj8qOQ6BqVpl82WI8S8WzXUdrUlUms
fHvgWjeG6HqNUqBAyVcJhbGkqSanb+cIgbmgdvrlboKAaDTx4yn8tu314EFh
v9LpNW7zYOSh3YAkczppqerOeJwm0HPY9AHfFJ2Caj7UFEH+5DINlPjJIdon
go3rVj8uaRRoNu6YsHxLlqeEi8i+rgyHT0a6cLAoZ6kj7Z1pSVQCO3KwFfIo
HIvG1l/AHcIWwvIMinNngz64X9GgV7uLciwg/svQWjSxqGEU+lqaY3vItTQR
H/xmG++6p2pGWjBpbmPI8BX5SAAVOA5uCiq6cIM6hpO1CoYj/eF1MWuAQkUK
8h2IMi2v3RX2l+xMMT38ork4XDCcGlwBWRmI3UaSUZB6X5jSkm/LFWGrbcfc
Hpuotj3/89aBNoZVDSdURUy8wqq/pLtMWO4vsnvPREiSMBI+vrAQf3bc2jvv
gAVqfLIF2CjVzlt+n+IHspNBJs924GARbGa8zZuCCFjuGdtSikV7YuP0GY8v
u1/qpEGWvl2G763yL+8aZg0RZOaLzYEsrKm2pnRCbmaBR41YZQvnZbNmzohs
D7czU2vBJ8TeLygBCe410SZpl6Eim6AMe/81yogKKn2tiK8QNL7M8WhRy1F+
Axb4xk5hqxoYJ6mf/Krio/3ci4bApHCuvI8YNIn1axezDRpSltzHNXQLIHwP
r2hBw9HnFs3JmCd48C+JCAr8/OQOZswKS/9//FyvwJIST9J82l5Cdh0ZDaPI
RA==
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-AuthSource: SJ0PR14MB5864.namprd14.prod.outlook.com
X-MS-Exchange-CrossTenant-Network-Message-Id: 55946f95-c7f1-49c2-8e9c-08db109050bb
X-MS-Exchange-CrossTenant-originalarrivaltime: 17 Feb 2023 02:40:21.8391 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: 5c82d83a-818a-4c16-b540-ded2344a7ad3
X-MS-Exchange-CrossTenant-mailboxtype: HOSTED
X-MS-Exchange-CrossTenant-userprincipalname: nfs5VRhK1WE20Qwqq/TicYvsSw2TJekK3E6GVaqqM2bnk5XjP7XWtW9FSGBuaoucRA25YaqS8zR9DWfSRRZFCg==
X-MS-Exchange-Transport-CrossTenantHeadersStamped: DS0PR14MB7181
X-Proofpoint-GUID: 7xZMbbn5XorT9U2ummp1-Qf0hJCD8B-I
X-Proofpoint-ORIG-GUID: 7xZMbbn5XorT9U2ummp1-Qf0hJCD8B-I
X-Proofpoint-Virus-Version: vendor=baseguard
engine=ICAP:2.0.219,Aquarius:18.0.930,Hydra:6.0.562,FMLib:17.11.170.22
definitions=2023-02-16_18,2023-02-16_01,2023-02-09_01
X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0
impostorscore=0 phishscore=0
bulkscore=0 spamscore=0 malwarescore=0 adultscore=0 clxscore=1015
mlxscore=0 mlxlogscore=973 suspectscore=0 lowpriorityscore=0
priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1
engine=8.12.0-2212070000 definitions=main-2302170022
X-Content-Filtered-By: Mailman/MimeDel 2.1.39
X-BeenThere: python-list@python.org
X-Mailman-Version: 2.1.39
Precedence: list
List-Id: General discussion list for the Python programming language
<python-list.python.org>
List-Unsubscribe: <https://mail.python.org/mailman/options/python-list>,
<mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive: <https://mail.python.org/pipermail/python-list/>
List-Post: <mailto:python-list@python.org>
List-Help: <mailto:python-list-request@python.org?subject=help>
List-Subscribe: <https://mail.python.org/mailman/listinfo/python-list>,
<mailto:python-list-request@python.org?subject=subscribe>
X-Mailman-Original-Message-ID: <SJ0PR14MB5864935B923047D8EFF0FD54B9A19@SJ0PR14MB5864.namprd14.prod.outlook.com>
X-Mailman-Original-References: <9CTGL.3255637$miq3.78888@fx02.ams4>
<a00f333f-b3cf-1122-4efa-62fd07ce6748@wichmann.us>
<mailman.1831.1676481401.20444.python-list@python.org>
<NPaHL.2601707$14z3.887943@fx11.ams4>
 by: Weatherby,Gerard - Fri, 17 Feb 2023 02:40 UTC

I think this does the trick:

https://gist.github.com/Gerardwx/c60d200b4db8e7864cb3342dd19d41c9

#!/usr/bin/env python3
import collections
import random
from typing import Hashable, Any, Optional, Dict, Tuple

class LruCache:
"""Dictionary like storage of most recently inserted values"""

def __init__(self, size: int = 1000):
""":param size number of cached entries"""
assert isinstance(size, int)
self.size = size
self.insert_counter = 0
self.oldest = 0
self._data : Dict[Hashable,Tuple[Any,int]]= {} # store values and age index
self._lru: Dict[int, Hashable] = {} # age counter dictionary

def insert(self, key: Hashable, value: Any) -> None:
"""Insert into dictionary"""
existing = self._data.get(key, None)
self._data[key] = (value, self.insert_counter)
self._lru[self.insert_counter] = key
if existing is not None:
self._lru.pop(existing[1], None) # remove old counter value, if it exists
self.insert_counter += 1
if (sz := len(self._data)) > self.size: # is cache full?
assert sz == self.size + 1
while (
key := self._lru.get(self.oldest, None)) is None: # index may not be present, if value was reinserted
self.oldest += 1
del self._data[key] # remove oldest key / value from dictionary
del self._lru[self.oldest]
self.oldest += 1 # next oldest index
assert len(self._lru) == len(self._data)

def get(self, key: Hashable) -> Optional[Any]:
"""Get value or return None if not in cache"""
if (tpl := self._data.get(key, None)) is not None:
return tpl[0]
return None

if __name__ == "__main__":
CACHE_SIZE = 1000
TEST_SIZE = 1_000_000
cache = LruCache(size=CACHE_SIZE)

all = []
for i in range(TEST_SIZE):
all.append(random.randint(-5000, 5000))

summary = collections.defaultdict(int)
for value in all:
cache.insert(value, value * value)
summary[value] += 1
smallest = TEST_SIZE
largest = -TEST_SIZE
total = 0
for value, count in summary.items():
smallest = min(smallest, count)
largest = max(largest, count)
total += count
avg = total / len(summary)
print(f"{len(summary)} values occurrences range from {smallest} to {largest}, average {avg:.1f}")

recent = set() # recent most recent entries
for i in range(len(all) - 1, -1, -1): # loop backwards to get the most recent entries
value = all[i]
if len(recent) < CACHE_SIZE:
recent.add(value)
if value in recent:
if (r := cache.get(value)) != value * value:
raise ValueError(f"Cache missing recent {value} {r}")
else:
if cache.get(value) != None:
raise ValueError(f"Cache includes old {value}")

From: Python-list <python-list-bounces+gweatherby=uchc.edu@python.org> on behalf of Dino <dino@no.spam.ar>
Date: Wednesday, February 15, 2023 at 3:07 PM
To: python-list@python.org <python-list@python.org>
Subject: Re: LRU cache
*** Attention: This is an external email. Use caution responding, opening attachments or clicking on links. ***

Thank you Mats, Avi and Chris

btw, functools.lru_cache seems rather different from what I need, but
maybe I am missing something. I'll look closer.

On 2/14/2023 7:36 PM, Mats Wichmann wrote:
> On 2/14/23 15:07, Dino wrote:
>>

--
https://urldefense.com/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!jb3Gr2BFAPLJ2YuI5rFdJUtalqWcijhxHAfdmCI3afnLFDdcekALxDYAQwpE1L_JlJBBJ-BB3BuLdoSE$<https://urldefense.com/v3/__https:/mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!jb3Gr2BFAPLJ2YuI5rFdJUtalqWcijhxHAfdmCI3afnLFDdcekALxDYAQwpE1L_JlJBBJ-BB3BuLdoSE$>

Re: LRU cache

<uhQHL.3488380$MJk2.2293686@fx06.ams4>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=21728&group=comp.lang.python#21728

  copy link   Newsgroups: comp.lang.python
Path: i2pn2.org!i2pn.org!usenet.blueworldhosting.com!feed1.usenet.blueworldhosting.com!peer03.iad!feed-me.highwinds-media.com!peer03.ams1!peer.ams1.xlned.com!news.xlned.com!peer03.ams4!peer.am4.highwinds-media.com!news.highwinds-media.com!fx06.ams4.POSTED!not-for-mail
MIME-Version: 1.0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101
Thunderbird/102.7.2
Subject: Re: LRU cache
Newsgroups: comp.lang.python
References: <9CTGL.3255637$miq3.78888@fx02.ams4>
<a00f333f-b3cf-1122-4efa-62fd07ce6748@wichmann.us>
<mailman.1831.1676481401.20444.python-list@python.org>
<NPaHL.2601707$14z3.887943@fx11.ams4>
<SJ0PR14MB5864935B923047D8EFF0FD54B9A19@SJ0PR14MB5864.namprd14.prod.outlook.com>
<mailman.1840.1676601634.20444.python-list@python.org>
Content-Language: en-US
From: din...@no.spam.ar (Dino)
In-Reply-To: <mailman.1840.1676601634.20444.python-list@python.org>
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Lines: 107
Message-ID: <uhQHL.3488380$MJk2.2293686@fx06.ams4>
X-Complaints-To: abuse@eweka.nl
NNTP-Posting-Date: Fri, 17 Feb 2023 19:09:14 UTC
Organization: Eweka Internet Services
Date: Fri, 17 Feb 2023 14:09:15 -0500
X-Received-Bytes: 5482
 by: Dino - Fri, 17 Feb 2023 19:09 UTC

Thank you, Gerard. I really appreciate your help

Dino

On 2/16/2023 9:40 PM, Weatherby,Gerard wrote:
> I think this does the trick:
>
> https://gist.github.com/Gerardwx/c60d200b4db8e7864cb3342dd19d41c9
>
>
> #!/usr/bin/env python3
> import collections
> import random
> from typing import Hashable, Any, Optional, Dict, Tuple
>
>
> class LruCache:
> """Dictionary like storage of most recently inserted values"""
>
> def __init__(self, size: int = 1000):
> """:param size number of cached entries"""
> assert isinstance(size, int)
> self.size = size
> self.insert_counter = 0
> self.oldest = 0
> self._data : Dict[Hashable,Tuple[Any,int]]= {} # store values and age index
> self._lru: Dict[int, Hashable] = {} # age counter dictionary
>
> def insert(self, key: Hashable, value: Any) -> None:
> """Insert into dictionary"""
> existing = self._data.get(key, None)
> self._data[key] = (value, self.insert_counter)
> self._lru[self.insert_counter] = key
> if existing is not None:
> self._lru.pop(existing[1], None) # remove old counter value, if it exists
> self.insert_counter += 1
> if (sz := len(self._data)) > self.size: # is cache full?
> assert sz == self.size + 1
> while (
> key := self._lru.get(self.oldest, None)) is None: # index may not be present, if value was reinserted
> self.oldest += 1
> del self._data[key] # remove oldest key / value from dictionary
> del self._lru[self.oldest]
> self.oldest += 1 # next oldest index
> assert len(self._lru) == len(self._data)
>
> def get(self, key: Hashable) -> Optional[Any]:
> """Get value or return None if not in cache"""
> if (tpl := self._data.get(key, None)) is not None:
> return tpl[0]
> return None
>
>
> if __name__ == "__main__":
> CACHE_SIZE = 1000
> TEST_SIZE = 1_000_000
> cache = LruCache(size=CACHE_SIZE)
>
> all = []
> for i in range(TEST_SIZE):
> all.append(random.randint(-5000, 5000))
>
> summary = collections.defaultdict(int)
> for value in all:
> cache.insert(value, value * value)
> summary[value] += 1
> smallest = TEST_SIZE
> largest = -TEST_SIZE
> total = 0
> for value, count in summary.items():
> smallest = min(smallest, count)
> largest = max(largest, count)
> total += count
> avg = total / len(summary)
> print(f"{len(summary)} values occurrences range from {smallest} to {largest}, average {avg:.1f}")
>
> recent = set() # recent most recent entries
> for i in range(len(all) - 1, -1, -1): # loop backwards to get the most recent entries
> value = all[i]
> if len(recent) < CACHE_SIZE:
> recent.add(value)
> if value in recent:
> if (r := cache.get(value)) != value * value:
> raise ValueError(f"Cache missing recent {value} {r}")
> else:
> if cache.get(value) != None:
> raise ValueError(f"Cache includes old {value}")
>
> From: Python-list <python-list-bounces+gweatherby=uchc.edu@python.org> on behalf of Dino <dino@no.spam.ar>
> Date: Wednesday, February 15, 2023 at 3:07 PM
> To: python-list@python.org <python-list@python.org>
> Subject: Re: LRU cache
> *** Attention: This is an external email. Use caution responding, opening attachments or clicking on links. ***
>
> Thank you Mats, Avi and Chris
>
> btw, functools.lru_cache seems rather different from what I need, but
> maybe I am missing something. I'll look closer.
>
> On 2/14/2023 7:36 PM, Mats Wichmann wrote:
>> On 2/14/23 15:07, Dino wrote:
>>>
>
> --
> https://urldefense.com/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!jb3Gr2BFAPLJ2YuI5rFdJUtalqWcijhxHAfdmCI3afnLFDdcekALxDYAQwpE1L_JlJBBJ-BB3BuLdoSE$<https://urldefense.com/v3/__https:/mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!jb3Gr2BFAPLJ2YuI5rFdJUtalqWcijhxHAfdmCI3afnLFDdcekALxDYAQwpE1L_JlJBBJ-BB3BuLdoSE$>

1
server_pubkey.txt

rocksolid light 0.9.8
clearnet tor