BufferingCharParser

upickle.core.BufferingCharParser

Models a growable buffer of Chars, which are Chars or Bytes. We maintain an Array[Char] as a buffer, and read Chars into it using readDataIntoBuffer and drop old Chars using dropBufferUntil.

In general, BufferingCharParser allows us to keep the fast path fast:

  • Reading char-by-char from the buffer is a bounds check and direct Array access, without any indirection or polymorphism.
  • We load Chars in batches into the buffer, which allows us to take advantage of batching APIs like InputStream.read
  • We amortize the overhead of the indirect/polymorphic readDataIntoBuffer call over the size of each batch

Note that dropBufferUntil only advances a dropped index and does not actually zero out the dropped Chars; instead, we wait until we need to call growBuffer, and use that as a chance to copy the remaining un-dropped Chars to either the start of the current buffer or the start of a newly-allocated bigger buffer (if necessary)

Attributes

Graph
Supertypes
class Object
trait Matchable
class Any

Members list

Value members

Abstract methods

def readDataIntoBuffer(buffer: Array[Char], bufferOffset: Int): (Array[Char], Boolean, Int)

Concrete methods

def appendCharsToBuilder(chars: CharBuilder, charsStart: Int, charsLength: Int): Unit
def dropBufferUntil(i: Int): Unit
def getBuffer: Array[Char]
def getBufferCopyCount(): Int
def getBufferGrowCount(): Int
def getBufferLength(): Int
def getCharSafe(i: Int): Char
def getCharUnsafe(i: Int): Char
def getFirstIdx: Int
def getLastIdx: Int
def growBuffer(until: Int): Unit

Copies the non-dropped Chars in the current buffer to the start of either the current buffer, or a newly-allocated larger buffer if necessary.

Copies the non-dropped Chars in the current buffer to the start of either the current buffer, or a newly-allocated larger buffer if necessary.

Attributes

protected def requestUntil(until: Int): Boolean

Used to ensure that charents up to until are available to read; returns whether or not we have read off the end of the input.

Used to ensure that charents up to until are available to read; returns whether or not we have read off the end of the input.

In the fast path, when until is less than the lastIdx we have buffered, there is no work to do and we return false.

In the slow path, when until is more than lastIdx, we then run growBuffer to grow the buffer if necessary, and then readDataIntoBuffer to populate it. readDataIntoBuffer returns a newDone value to indicate whether we have read off the end of the input or not.

Note that for some subclasses, growBuffer may be a no-op when we already know we have reached the end of input.

Attributes

protected def requestUntilGetSafeIndex(until: Int): Int

Used to ask for data up to a certain index, as a best effort (unlike requestUntil), returning the "safe index" which it was actually able to fetch data for. This is used so the caller can use the safe index to know how far it is able to run getCharUnsafe calls without further checks, improving performance over calling getCharSafe every time which performs additional checks and logic

Used to ask for data up to a certain index, as a best effort (unlike requestUntil), returning the "safe index" which it was actually able to fetch data for. This is used so the caller can use the safe index to know how far it is able to run getCharUnsafe calls without further checks, improving performance over calling getCharSafe every time which performs additional checks and logic

Attributes

def sliceArr(i: Int, n: Int): (Array[Char], Int, Int)
def sliceString(i: Int, k: Int): String
def unsafeCharSeqForRange(start: Int, length: Int): WrapCharArrayCharSeq