-
Notifications
You must be signed in to change notification settings - Fork 60
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
Provide an API for performant bulk or sequential read/writes #135
Comments
Just wanted to mention, that from my perspective this should be implemented taking into account future feature from #131: |
An implementation will definitely take different memory types into account, otherwise, it'll be hard to make performant reads/writes. |
I am trying to implement a custom |
@rnett, that's correct. Once solved, this issue should allow more easily implementing things like |
Here's an update with the details on an API we will implement. IntroIn general, there are two groups of cases when existing public API works poorly both performance- and convenience-wise:
The first group usually requires taking as much data as possible and passing it down to other API, or, reserving some The second group is about various extensions that need to access some variadic amount of bytes in an efficient manner. Proposed APIOne of the goals we're trying to achieve with an unsafe/bulk API is to provide a way to write efficient code, meaning, among anything else, that the amount of data copying should be minimal. That requires segment data to be directly accessible. The proposed API consists of the following three tiers:
These tiers are intertwined, and sometimes boundaries are fuzzy. I'm mentioning them mostly to structure the document and make it more approachable. 1. A Bulk APIThe API aimed for integration with other APIs and consists of the following functions:
On JVM, the following extensions will be provided:
There will be no Additionally, there's a SegmentReadContext.withData function allowing to access segment data. Note that for Native, extensions similar to JVMs could also be provided. 2. Buffer iteration APITo iterate over buffer segments, we're going to make Will all that being said, one can start iteration from either buffer's head or a segment covering a specific offset: These functions supply a BufferIterationContext that could be used to get a next segment.
3. Byte-granular read/write APIGiven a SegmentReadContext (that could be obtained by calling Given a SegmentWriteContext (could be obtained by calling Total number of readable bytes always lies in range A total number of writable bytes is always within AlternativesSeveral alternatives were considered, namely: Using Okio's
|
If kotlinx-benchmarks is in a good state, it would also be nice to add benchmarks for JS and Native, to see how they compare over time. |
Previously, Buffer's segments were organized into a circular list. That allowed storing only a single reference to buffer's head, and also facilitated insertion/removal of new list nodes. The downside of a circular list is that one has to always compare a current node with a head when iterating over segments. That complicates the implementation of a public API for segments iterations. See #135 (comment) for details on segment iteration API.
The API aimed to facilitate integration with other frameworks and libraries. Implemented API was initially described in the "Bulk API" subsection of #135 (comment)
Previously, Buffer's segments were organized into a circular list. That allowed storing only a single reference to buffer's head, and also facilitated insertion/removal of new list nodes. The downside of a circular list is that one has to always compare a current node with a head when iterating over segments. That complicates the implementation of a public API for segments iterations. See #135 (comment) for details on segment iteration API.
The API aimed to facilitate integration with other frameworks and libraries. Implemented API was initially described in the "Bulk API" subsection of #135 (comment)
The API aimed to facilitate integration with other frameworks and libraries. Implemented API was initially described in the "Bulk API" subsection of #135 (comment)
Previously, Buffer's segments were organized into a circular list. That allowed storing only a single reference to the buffer's head and also facilitated the insertion/removal of new list nodes. The downside of a circular list is that one has to always compare a current node with a head when iterating over segments. That complicates the implementation of a public API for segment iterations. See #135 (comment) for details on segment iteration API.
The API aimed to facilitate integration with other frameworks and libraries. Implemented API was initially described in the "Bulk API" subsection of #135 (comment)
* Introduce unsafe API for bulk read/write ops. The API aimed to facilitate integration with other frameworks and libraries. Implemented API was initially described in the "Bulk API" subsection of #135 (comment)
…cess its data (#336) This is a second portion of unsafe API described in #135. This particular part aimed to facilitate the implementation of various Buffer extensions. The implemented API was initially described in "2. Buffer iteration API" and "3. Byte-granular read/write API" subsections of #135 (comment) This PR concludes the changes required to implement the API from #135, but our journey won't end here! The next patch in the queue is rewriting all existing extensions using the new API and then encapsulating all segments' internals.
As stated in #132,
kotlinx-io
don't include Okio APIs aimed for performant sequential and bulk ops (like, UnsafeCursor).Such API is required to implement previously removed functionality (like select) efficiently. It's also required for integration with platform-specific APIs (like hash functions implementation using Java's
MessageDigest
API).This issue claims the intent to provide such functionality, but the actual API will be discussed later.
The text was updated successfully, but these errors were encountered: