Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6eb27ef9 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Cache least recently used output buffer."

parents b6d3eecb 19f8adfb
Loading
Loading
Loading
Loading
+7 −3
Original line number Original line Diff line number Diff line
@@ -64,9 +64,13 @@ public class FastDataPerfTest {
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        while (state.keepRunning()) {
        while (state.keepRunning()) {
            os.reset();
            os.reset();
            final FastDataOutput out = new FastDataOutput(os, BUFFER_SIZE);
            final FastDataOutput out = FastDataOutput.obtain(os);
            try {
                doWrite(out);
                doWrite(out);
                out.flush();
                out.flush();
            } finally {
                out.release();
            }
        }
        }
    }
    }


+7 −2
Original line number Original line Diff line number Diff line
@@ -124,7 +124,7 @@ public final class BinaryXmlSerializer implements TypedXmlSerializer {
            throw new UnsupportedOperationException();
            throw new UnsupportedOperationException();
        }
        }


        mOut = new FastDataOutput(os, BUFFER_SIZE);
        mOut = FastDataOutput.obtain(os);
        mOut.write(PROTOCOL_MAGIC_VERSION_0);
        mOut.write(PROTOCOL_MAGIC_VERSION_0);


        mTagCount = 0;
        mTagCount = 0;
@@ -138,8 +138,10 @@ public final class BinaryXmlSerializer implements TypedXmlSerializer {


    @Override
    @Override
    public void flush() throws IOException {
    public void flush() throws IOException {
        if (mOut != null) {
            mOut.flush();
            mOut.flush();
        }
        }
    }


    @Override
    @Override
    public void startDocument(@Nullable String encoding, @Nullable Boolean standalone)
    public void startDocument(@Nullable String encoding, @Nullable Boolean standalone)
@@ -157,6 +159,9 @@ public final class BinaryXmlSerializer implements TypedXmlSerializer {
    public void endDocument() throws IOException {
    public void endDocument() throws IOException {
        mOut.writeByte(END_DOCUMENT | TYPE_NULL);
        mOut.writeByte(END_DOCUMENT | TYPE_NULL);
        flush();
        flush();

        mOut.release();
        mOut = null;
    }
    }


    @Override
    @Override
+50 −3
Original line number Original line Diff line number Diff line
@@ -30,6 +30,7 @@ import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.HashMap;
import java.util.Objects;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;


/**
/**
 * Optimized implementation of {@link DataOutput} which buffers data in memory
 * Optimized implementation of {@link DataOutput} which buffers data in memory
@@ -41,23 +42,26 @@ import java.util.Objects;
public class FastDataOutput implements DataOutput, Flushable, Closeable {
public class FastDataOutput implements DataOutput, Flushable, Closeable {
    private static final int MAX_UNSIGNED_SHORT = 65_535;
    private static final int MAX_UNSIGNED_SHORT = 65_535;


    private static final int BUFFER_SIZE = 32_768;

    private static AtomicReference<FastDataOutput> sOutCache = new AtomicReference<>();

    private final VMRuntime mRuntime;
    private final VMRuntime mRuntime;
    private final OutputStream mOut;


    private final byte[] mBuffer;
    private final byte[] mBuffer;
    private final long mBufferPtr;
    private final long mBufferPtr;
    private final int mBufferCap;
    private final int mBufferCap;


    private OutputStream mOut;
    private int mBufferPos;
    private int mBufferPos;


    /**
    /**
     * Values that have been "interned" by {@link #writeInternedUTF(String)}.
     * Values that have been "interned" by {@link #writeInternedUTF(String)}.
     */
     */
    private HashMap<String, Short> mStringRefs = new HashMap<>();
    private final HashMap<String, Short> mStringRefs = new HashMap<>();


    public FastDataOutput(@NonNull OutputStream out, int bufferSize) {
    public FastDataOutput(@NonNull OutputStream out, int bufferSize) {
        mRuntime = VMRuntime.getRuntime();
        mRuntime = VMRuntime.getRuntime();
        mOut = Objects.requireNonNull(out);
        if (bufferSize < 8) {
        if (bufferSize < 8) {
            throw new IllegalArgumentException();
            throw new IllegalArgumentException();
        }
        }
@@ -65,6 +69,48 @@ public class FastDataOutput implements DataOutput, Flushable, Closeable {
        mBuffer = (byte[]) mRuntime.newNonMovableArray(byte.class, bufferSize);
        mBuffer = (byte[]) mRuntime.newNonMovableArray(byte.class, bufferSize);
        mBufferPtr = mRuntime.addressOf(mBuffer);
        mBufferPtr = mRuntime.addressOf(mBuffer);
        mBufferCap = mBuffer.length;
        mBufferCap = mBuffer.length;

        setOutput(out);
    }

    /**
     * Create a new FastDataOutput object or retrieve one from cache.
     */
    public static FastDataOutput obtain(@NonNull OutputStream out) {
        FastDataOutput instance = sOutCache.getAndSet(null);
        if (instance != null) {
            instance.setOutput(out);
            return instance;
        }
        return new FastDataOutput(out, BUFFER_SIZE);
    }

    /**
     * Put a FastDataOutput object back into the cache.
     * You must not touch the object after this call.
     */
    public void release() {
        if (mBufferPos > 0) {
            throw new IllegalStateException("Lingering data, call flush() before releasing.");
        }

        mOut = null;
        mBufferPos = 0;
        mStringRefs.clear();

        if (mBufferCap == BUFFER_SIZE) {
            // Try to return to the cache.
            sOutCache.compareAndSet(null, this);
        }
    }

    /**
     * Re-initializes the object for the new output.
     */
    private void setOutput(@NonNull OutputStream out) {
        mOut = Objects.requireNonNull(out);
        mBufferPos = 0;
        mStringRefs.clear();
    }
    }


    private void drain() throws IOException {
    private void drain() throws IOException {
@@ -83,6 +129,7 @@ public class FastDataOutput implements DataOutput, Flushable, Closeable {
    @Override
    @Override
    public void close() throws IOException {
    public void close() throws IOException {
        mOut.close();
        mOut.close();
        release();
    }
    }


    @Override
    @Override