reth icon indicating copy to clipboard operation
reth copied to clipboard

Switch `net::LruCache` to not use `LinkedHashSet`

Open Rjected opened this issue 1 year ago • 12 comments

Right now the LruCache data structure uses a LinkedHashSet. This data structure is responsible for a large number of allocations. We don't strictly need to use this dependency, and there may be related memory leaks, re: https://github.com/paradigmxyz/reth/issues/6765#issuecomment-1966558358

Rjected avatar Feb 28 '24 01:02 Rjected

Hi @Rjected , what would you suggest to use instead of LinkedHashSet ?

PanGan21 avatar Mar 05 '24 20:03 PanGan21

essentially schnellru::LruMap::new(ByLength::new(max_length))

but there's one problem:

https://github.com/paradigmxyz/reth/blob/6725d43f053d3eba66c0a516af041c5018452bd9/crates/net/network/src/cache.rs#L39-L39

I don't think the api supports this, but we currently rely on this for some cleanup:

https://github.com/paradigmxyz/reth/blob/6725d43f053d3eba66c0a516af041c5018452bd9/crates/net/network/src/transactions/fetcher.rs#L407-L410

so unclear if we can easily do this

mattsse avatar Mar 05 '24 23:03 mattsse

Will give it a try, since LruMap support pop_oldest, which is the same as LinkedHashSet::pop_front https://docs.rs/schnellru/latest/schnellru/struct.LruMap.html#method.pop_oldest

AbnerZheng avatar Mar 06 '24 17:03 AbnerZheng

this is unfortunately not equivalent because this forcefully pops, so we'd always need to check limits first

mattsse avatar Mar 06 '24 18:03 mattsse

We can create a LRUMap with len = limit + 1, then the code of insert_and_get_evicted would keep the same except replacing LinkedHashSet::pop_front with LruMap::pop_oldest.

AbnerZheng avatar Mar 07 '24 04:03 AbnerZheng

We can create a LRUMap with len = limit + 1, then the code of insert_and_get_evicted would keep the same except replacing LinkedHashSet::pop_front with LruMap::pop_oldest.

this would impact the ordering though, right?

Rjected avatar Mar 07 '24 04:03 Rjected

In my opinion, they are both following the same logic, remove the least recently used entry and return it.

AbnerZheng avatar Mar 07 '24 05:03 AbnerZheng

remove the least recently used entry and return it.

but that's all it does, no insert, so this needs to be done manually, so I guess we need the wrapper type and implement insert_and_get_evicted manually

mattsse avatar Mar 07 '24 10:03 mattsse

Ah, I got it. You want to find a LRU library that is able to support insert_and_get_evicted natively, even though the current implementation of LRUCache implemented the logic manually.

AbnerZheng avatar Mar 07 '24 10:03 AbnerZheng

@Rjected I just go through the implementation of the LinkedHashSet and it's not optimal, and at the same time the way we use the unlimited memory for LRU can cause crash. If everyone is busy with other issues, then I can take this one.

ghost avatar Mar 22 '24 08:03 ghost

@0xJepsen can you type a short msg here so I can assign you?

onbjerg avatar Apr 22 '24 10:04 onbjerg

This issue is stale because it has been open for 21 days with no activity.

github-actions[bot] avatar May 14 '24 01:05 github-actions[bot]