Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: container/list: add trimming APIs #42040

Closed
siaminator opened this issue Oct 17, 2020 · 4 comments
Closed

proposal: container/list: add trimming APIs #42040

siaminator opened this issue Oct 17, 2020 · 4 comments

Comments

@siaminator
Copy link

Motivation
LinkedLists are a good candidate for creating dynamic sliding windows over streams of data, and maintain some aggregated values for the data captured inside the window. They are suitable because they have O(1) Time complexity to push data to the back of the window, without performance issues of dynamic array/slice size. Also a pointer to the beginning of the window would be simply a pointer to an element in the list to allow O(1) access.
But there is one downside to this application: as the stream continues to flow, the LinkedList inside which we are maintaing our window would keep growing in size and there is no way currently in the Go container/list implementation to cut the old data which are past the window off it.
Ofcourse I am certain one could think of many more general use cases for the functionalities I am going to propose.

Proposal
So I am proposing to add 2 APIs to the Go's LinkedList implementation to provide Left Trim and Right Trim functionality, which would simply let the user cut the list into smaller one which considering the LinkedList structure, could be accomplished by as easy as modifying the root and start/end elements pointers to their neighbours.
As an addition a SubList API could also be provided which would allow for cutting both ends based on the provided elements at once.

How
Well the how is very simple and I have already mentioned that in the Proposal section, but to be more specific, I have already applied my thoughts on a copy of the Go container/list, which could be used as an ultimate demonstation of my thoughts accompanied with tests.
https://github.com/siaminator/linked-list/blob/7c49a02b37803a6ca379a4546b95f2145d433ad9/list.go#L242
https://github.com/siaminator/linked-list/blob/7c49a02b37803a6ca379a4546b95f2145d433ad9/list.go#L259

There is one caveat to this functionality on LinkedList, which is to maintain the correct length of the list after trimming. there is no way other than iterating through the cut part elements to be able to calculate the new lenght of the resulting array. I have took advantage of this iteration to unlink cut elements from each other to faciliate grabage collection.

@gopherbot gopherbot added this to the Proposal milestone Oct 17, 2020
@ianlancetaylor
Copy link
Contributor

Can't you do this already using Remove? Is there something that an implementation in container/list can do that can't be done just using the existing API?

@ianlancetaylor ianlancetaylor changed the title Proposal: functionality: Add trimming APIs to container/list proposal: container/list: add trimming APIs Oct 17, 2020
@ianlancetaylor ianlancetaylor added this to Incoming in Proposals (old) Oct 17, 2020
@siaminator
Copy link
Author

The point is that for accomplishing the same result as the Trim functions i have proposed, you need to iterate the elements from front/back of the list, remove each of them up to the element to want your list to be trimmed to, which could go up to O(n-1) in time complexity.
But the the linked list structure, allows for a much performant approach, which would be simply unlinking the element up to/from which you want to trim, from the leading/trailing elements, which is a simple O(1) time complexity.

p.s: While in my implementation of the trim functions, I did not work on finding a workaround not to iterate through the elements being trimmed off, to maintain the correct length of the resulting list,. But I suppose an specific implementation is off the topic of the proposal. and even if there would not be a get away from that, these 2 APIs would provide a standard, safe and more performant (more perfomant than series of Removes, because the remove approach would need to keep weaving sides of the element being removed to each other by the pointers) way, encapsulated in the library itself, for achieving a common behaviour over the LinkedList.

@rsc
Copy link
Contributor

rsc commented Oct 21, 2020

When generics happens, we are likely to deprecate list entirely in favor of new, properly typed APIs.
This API was an interesting demo but is essentially deprecated already, certainly frozen.

This seems like a likely decline because we are not modifying this API anymore (ever).

But feel free to use the code as the base of an implementation that does exactly what you want.

@rsc rsc moved this from Incoming to Likely Decline in Proposals (old) Oct 21, 2020
@rsc
Copy link
Contributor

rsc commented Oct 28, 2020

No change in consensus, so declined.

@rsc rsc closed this as completed Oct 28, 2020
@rsc rsc moved this from Likely Decline to Declined in Proposals (old) Oct 28, 2020
@golang golang locked and limited conversation to collaborators Oct 28, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
No open projects
Development

No branches or pull requests

4 participants