I’m confused about the temporary container changing to a red black tree, as when I looked at the code, it already was one, and that code hadn’t changed in many years.
Noting that RB trees have a high instruction count for the critical loop, and making some guesses about typical instruction counts, I concluded that, even without the high instruction count, it would take more than the low double figures of milliseconds that I thought would be an acceptable time for locking a global resource in Asterisk.
I’m maybe being a little over strict in saying low tens of milliseconds, as that assumes that the lock gets applied for every RTP packet, which might not be the case.
What I seem to be missing here is why you are issuing the command, most CLI commands are not intended to be used in routine operation, and the only expected use of this one is for debugging.
I’m assuming that most of the time is on the sort, but the copy may also be quite expensive, as it may involve allocating memory for each entry, and I suppose it is possible that it is repeatedly having to pass over large numbers of too small memory fragments in that process. I haven’t looked into the details of how that is done by Asterisk, and by libc.
• stasis statistics show topics already uses a temporary RB-tree snapshot.
• stasis show topics still uses a temporary list; that’s where the “switch to RB-tree” one-liner applies.
If alloc_list takes a sort function argument, it is likely to have O(n^2) time complexity, so be worse than red black trees (or the argument is not used).
I think the suggestion actually made was to use a red black container, rather than a hash container, but you really need a temporary store to decouple the readout from the console output.
If you wanted to make it really fast, I think you would either need to pre-allocate memory for the complete contents (not sure how you would calculate the size), then do a fast copy into that, followed by sorting outside the lock, or you would need to add some sort of option to the hash read out to reduce the locking, so that lock times were reduced, but with the possibility of not returning a result that is consistent at a given point in time. That might increase the number of locks taken in normal operation, as I presume you can’t do a completely unlocked read, as a deletion might lead you off into freed and re-used memory, so you would probably have to lock at least the chain for each has bucket, assuming it is using chains.
I still haven’t seen a reason for doing this on a normally operating system, and making changes for abnormal uses risks introducing bugs into normal cases.
Please note I don’t know if duplicating creates a shallow, or a deep copy, and I’ve not looked deeply into the internal memory allocaiton and locking used by ao2 containers.