Hi Paul,

On Dec 21, 2017, at 10:28 AM, Paul Sandoz <paul.san...@oracle.com> wrote:

> This looks ok, i think it’s definitely reached it’s complexity budget, and 
> arguably over spent.

I concur that this horse is almost dead from the beatings but since I already 
hacked up Peter’s suggestion which eliminates intermediate copies I might as 
well hang it out there (see below).

> —
> 
> I do have one follow on investigation we discussed off list that is worth 
> measuring. At the end use the Unsafe array allocation with no zeroing, since 
> the resulting array will be fully written into. This might result in an 
> observable improvement.

I’ve not forgotten about that but do not know whether we want to include it as 
part of this issue or a subsequent one.

Thanks,

Brian

    public byte[] readAllBytes() throws IOException {
        List<byte[]> bufs = null;
        byte[] result = null;
        int total = 0;
        int n;
        do {
            byte[] buf = new byte[DEFAULT_BUFFER_SIZE];
            int nread = 0;

            // read to EOF which may read more or less than buffer size
            while ((n = read(buf, nread, buf.length - nread)) > 0) {
                nread += n;
            }

            if (nread > 0) {
                if (MAX_BUFFER_SIZE - total < nread) {
                    throw new OutOfMemoryError("Required array size too large");
                }
                total += nread;
                if (result == null) {
                    result = buf;
                } else {
                    if (bufs == null) {
                        bufs = new ArrayList<>();
                        bufs.add(result);
                    }
                    bufs.add(buf);
                }
            }
        } while (n >= 0); // if the last call to read returned -1, then break

        if (bufs == null) {
            if (result == null) {
                return new byte[0];
            }
            return result.length == total ?
                result : Arrays.copyOf(result, total);
        }

        result = new byte[total];
        int offset = 0;
        int remaining = total;
        for (byte[] b : bufs) {
            int len = Math.min(b.length, remaining);
            System.arraycopy(b, 0, result, offset, len);
            offset += len;
            remaining -= len;
        }

        return result;
    }

Reply via email to