<div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Fri, Mar 21, 2025 at 10:58 AM Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com">maurizio.cimadamore@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><u></u>

  
  <div>
    <p><br>
    </p>
    <div>On 21/03/2025 15:44, David Lloyd wrote:<br>
    </div>
    <blockquote type="cite">
      
      <div dir="ltr">
        <div dir="ltr">
          <div style="font-family:arial,helvetica,sans-serif"><br>
          </div>
        </div>
        <br>
        <div class="gmail_quote">
          <div dir="ltr" class="gmail_attr">On Fri, Mar 21, 2025 at
            10:25 AM Maurizio Cimadamore <<a href="mailto:maurizio.cimadamore@oracle.com" target="_blank">maurizio.cimadamore@oracle.com</a>>
            wrote:<br>
          </div>
          <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
            <div>
              <p><br>
              </p>
              <div>On 21/03/2025 15:17, David Lloyd wrote:<br>
              </div>
              <blockquote type="cite">
                <div dir="ltr">
                  <div dir="ltr">
                    <div dir="ltr">
                      <div style="font-family:arial,helvetica,sans-serif">Yes,
                        you *could* wrap a byte[] with a MemorySegment,
                        but then you'd just have a heap memory segment;
                        this is probably not what the user is looking
                        for (otherwise they'd probably just build to a
                        byte[] to begin with). By using the
                        user-supplied allocator, I can (for example)
                        write the class bytes directly to a
                        memory-mapped file.</div>
                    </div>
                  </div>
                </div>
              </blockquote>
              <p>Ah! I now see that first allocator parameter -- which
                makes sense.</p>
              <p>I'd suggest to turn that into SegmentAllocator -- note
                that Arena is also a SegmentAllocator, so you can pass
                either your own allocating lambda, or directly use an
                arena which is nice (I think).</p>
            </div>
          </blockquote>
          <div><br>
          </div>
          <div>
            <div style="font-family:arial,helvetica,sans-serif">Ah, that's
              an interesting idea. The idea with using the plain
              function is that the user would explicitly be in charge of
              deciding all of the characteristics of the buffer
              (including, for example, alignment). I'm not quite sure
              how that shakes out (ergonomically speaking) with using a
              `SegmentAllocator`, because either I'd have to send in the
              alignment (which means, I guess, accepting it as a
              parameter in the `buildToMemorySegment` methods), or else
              rely on the user to override that method in their
              allocator. With a plain function, the user could always
              pass in `mySegmentAllocator::allocate` or `size ->
              mySegmentAllocator.allocate(size, 8)` or whatever. Also,
              with a plain function, I could pass one in which easily
              yields a subsegment of a parent segment e.g. `size ->
              parentSegment.asSlice(offset, size)`. Would it still be
              easy to do this while accepting a `SegmentAllocator`?</div>
          </div>
        </div>
      </div>
    </blockquote>
    <p>Note: SementAllocator is a functional interface. So you can
      always pass a lambda to implement it -- e.g.</p>
    <p>buildToMemorySegment((size, _) -> getMeASegment(size));</p>
    <p>And, SegmentAllocator already suports sliced allocation - see
      SegmentAllocator::slicingAllocator (which creates a segment
      allocator from an existing segment and keeps slicing from it, at
      consecutive offsets until it runs out), or
      SegmentAllocator::prefixAllocator (which creates a segment
      allocator from an existing segment and keeps slicing from it from
      the start of the segment -- possibly overwriting each time)</p></div></blockquote><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">Ah, perfect. I can make that change then.</div></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><blockquote type="cite"><div dir="ltr"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><p>ByteBuffer don't have the allocation abstraction -- so
                I wonder if we really should let them go, and maybe only
                add the segment API with the allocator parameter. Or
                maybe have a simpler API for ByteBuffer w/o allocator
                parameter, which always allocates a heap buffer. Then if
                users want something more complex (e.g. a mapped byte
                buffer) they can use the MS API instead, and then wrap
                the MS into a BB after the fact.</p>
            </div>
          </blockquote>
        </div>
      </div>
    </blockquote>
    <blockquote type="cite">
      <div dir="ltr">
        <div class="gmail_quote">
          <div><br>
          </div>
          <div>
            <div style="font-family:arial,helvetica,sans-serif">Well,
              ByteBuffer has the same allocation abstraction that (for
              example) arrays do when you're calling
              `Collection.toArray(generator)` - that is,
              `IntFunction<T>`. Using this abstraction, one can
              basically get all the same benefits described above - the
              ability to select direct or heap, the ability to return a
              subslice of a parent buffer, etc. But I agree, it seems
              that semantically the buffer stuff is pretty much exactly
              redundant with respect to the MemorySegment variations
              (since we have `MemorySegment.asByteBuffer()` and
              `MemorySegment.ofBuffer()`), so I could see dropping it
              and just living with the minor asymmetry with
              `ClassLoader.defineClass(...)`.</div>
          </div>
        </div>
      </div>
    </blockquote>
    <p>Yeah -- we could go both ways... I guess my sense is that since
      SegmentAllocator is an official thing (TM ;-) ), it has more right
      to be in the API than a "random" BB-generating function. Also, I
      guess what I'm saying is that, if you squint, the memory
      segment-accepting methods are really the primitve ones as all the
      others (including byte[]) can be derived from there.</p></div></blockquote><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">OK, I think I'll go ahead and drop the `ByteBuffer` variants then.<span style="font-family:Arial,Helvetica,sans-serif"> </span></div></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><p> But, at the
      moment we know we can't go all the way down there...</p></div></blockquote><div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">Yeah, that's a pity.</div></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div></div><span class="gmail_signature_prefix">-- </span><br><div dir="ltr" class="gmail_signature"><div dir="ltr">- DML • he/him<br></div></div></div>