On 14 March 2016 at 10:44, Alex Bligh <
al...@alex.org.uk> wrote:
>
> On 14 Mar 2016, at 10:09, Dave Cheney <
da...@cheney.net> wrote:
>
>> Maybe you don't want a map, but a slice instead, then choosing a random element is simple. What other kinds of access to you do to the "map" besides addition ?
>
> The map is frequently indexed by its key, for insert, delete, and get, i.e. all the normal map operations. What I wanted is something just like a map, with the additional property of being able to pick a random element. It's in essence a cache of a fixed size that evicts at random rather by LRU, but that's by the by. I don't need it to be cryptographically random, but I do need it to evict different elements each time called on the same run if the cache is set up the same way (so using the 'first' element in the hash won't work).
It actually will work in Go as it currently is, and I don't see that changing
any time soon.
for key := range someMap {
delete(someMap, key)
break
}
It's certainly not cryptographically random, and it's perhaps not even *that*
random, but it may well be good enough for your purposes.
But the "keep an extra slice" code is quite straightforwardly implemented too:
http://play.golang.org/p/hiRpc-bJK_
You might want to add code to shrink the slice if the map shrinks too much
so that you don't get left with garbage from a spike in usage.
> So I'd really like a put() call that returned the item it evicted if any.
>
> I realise I can do this with another data structure (the slice containing the data with a map between key and index is quite neat, except I think it means I need to keep the key twice so I know the key of the data I'm evicting). I could also use (e.g.) an LLRB tree and descend a random path.
>
> I was really wondering whether there is some way to look into the back end implementation of the map, and (e.g.) pick a random bucket (by choosing a random hash value) and walk the chain a random distance (I'm assuming here it's bucket plus chain) which if the hash algorithm is good should produce a (roughly) random result.
>
> If I'm being honest, in practical terms I'm quite happy with the sledgehammer method of using another data structure (with all the nasty mess of casts that involves if I want it applicable to multiple types of map), but I was wondering if there was some elegant way of *just* using a map.
>
> --
> Alex Bligh
>
>
>
>