Skip to content

WIP: RingBuffer #7250

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

Closed

Conversation

therealbnut
Copy link
Contributor

@therealbnut therealbnut commented Feb 4, 2017

This introduces an experimental internal collection type, RingBuffer<T> and resolves rdar://problem/21885650 (presumably).

FIXME: rdar://problem/21885650 Create reusable RingBuffer

This needs more work, but I thought I'd check it's wanted before I do that.

Remaining work:

  • tests probably need to be adapted to be similar to existing tests
    • validation-test/stdlib that uses StdlibCollectionUnittest
  • new files need to be added to the build?
  • tests need to be run with the swift build process
  • RingBuffer should use _ContiguousArrayBuffer?
  • RingBuffer needs to trap on invalid access
  • RingBuffer should implement more defaulted methods
  • Can this be added to Arrays.swift.gyb? (behaviour differs probably)
  • Comments for public interface usage
  • Comments for implementation details
  • Benchmark
  • Investigate RangeReplaceableCollection on init() and reserveCapacity(Int)

@bitjammer
Copy link
Contributor

CC @dabrahams

@therealbnut
Copy link
Contributor Author

Thanks @bitjammer :)

@dabrahams
Copy link
Contributor

@airspeedswift we should re-evaluate the role of the experimental directory now that Swift is open-source. It served a purpose for us once upon a time, but I'm not sure it does anymore. I may not make sense to accept pull requests on it.

@therealbnut
Copy link
Contributor Author

@dabrahams how about swift/test/Prototypes/*?

This PR does not expose any new public interfaces, it does fix a FIXME in the public stdlib/public/core/Sequence.swift.

This PR currently relies on swift/test/Prototypes/Algorithms.swift.gyb, I think it makes more sense to be there.

Is it worth continuing to work on this PR?

@dabrahams
Copy link
Contributor

@therealbnut Thanks for the contribution; I need to consult with others to make a determination.

@therealbnut
Copy link
Contributor Author

@dabrahams no problem, thanks for your time

return AnySequence([s0, s1].joined())
}
let capacity = Swift.min(maxLength, underestimatedCount)
var ringBuffer = RingBuffer<Iterator.Element>(capacity: capacity)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to me this can't possibly build, since the standard library doesn't define RingBuffer anywhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I was intending that it's internal in the stdlib, for now - I've only just moved it over from a separate project so I haven't worked out all the details of integrating it into the stdlib yet. I'm not going to do that until I know it's a welcome contribution though :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the PR is just meant to fix the FIXME, it's definitely welcome! However, you'll have to get it integrated so we can run the tests and benchmarks. And if there's no benchmark that will be affected by your improvement, I'll ask you to please write one ;-)

@dabrahams
Copy link
Contributor

@swift-ci Please smoke test

@dabrahams
Copy link
Contributor

@swift-ci Please benchmark

@therealbnut
Copy link
Contributor Author

therealbnut commented Feb 5, 2017

@dabrahams this is very much WIP - I expect it's not ready for review, or tests :)

Now that I know it's welcome I can do those necessary steps. I'll add "benchmark" to my TODO list. I'm happy to close the PR until it's ready.

result.append(ringBuffer[i])
ringBuffer[i] = element
i = ringBuffer.index(after: i) % n
if ringBuffer.isFull, let first = ringBuffer.first {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use popFirst here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ringBuffer.append(element) later will be equivalent to popFirst().

I expect that popFirst is less performant on the current ring buffer implementation. It could use a startIndex and an endIndex to change that.

Copy link
Contributor Author

@therealbnut therealbnut Feb 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to implement it like that, but I needed to investigate existing array-like structures more first. I'd like a structure that's not reallocated, and can have its elements initialised and de-initialized out-of-order as needed. I think _ContiguousArrayBuffer is probably that, but I haven't looked into it enough yet.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You want ManagedBuffer. Cheers!

@dabrahams
Copy link
Contributor

Should also have a test in validation-test/stdlib that uses StdlibCollectionUnittest

@therealbnut
Copy link
Contributor Author

Closing until this is ready for review

@therealbnut therealbnut closed this Feb 5, 2017
@swift-ci
Copy link
Contributor

swift-ci commented Feb 5, 2017

Build comment file:

Build failed before running benchmark.


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants