|
Raw types are defined in the com.neeve.raw package. They wrap a non primitive object type's encoded byte representation to avoid allocation costs associated with the creation of the wrapped type's value during the course of application processing. Raw types are currently supported for UUID and String values, but more raw types may be added over time. Raw Types accessors are provided on generated messages and entities for all supported encodings, but at present they are most effective withe Xbuf encoding as the platform has direct access to the backing buffer in that case.
If a non primitive type needs to be maintained in memory for a long period of time as part of an application's state, the creation of the type would normally create garbage that generational garbage collection would have to promote into tenured memory. For latency sensitive applications this promotion leads to garbage which leads to garbage collection pauses. RawType
s allow preallocation of memory for such fields to reduce gc overhead.
A RawType
may be preallocated via RawDataFactory
using one if its factory methods. The RawType
and its backing buffer will be promoted to the tenured generation, at the beginning of the application's life cycle, allowing the tenuring cost to be paid up front.
When the RawType
is later assigned from another RawType
the backing buffer can be copied from it without any garbage being created. A typical example of this would be where a transport layer reads a field off the wire and passes it off to the application. The networking layer wraps the encoded buffer in a pooled RawType
and can pass it off to application code that has a preallocated RawType
that serves as the target. The network buffer is copied into the preallocated target without instantiating the underlying non primitive type meaning that no garbage is created in the course of setting the field.
However even if the underlying value is materialized by application code via a call to getValue()
, the cost in garbage can remain low providing the application doesn't keep a reference to the materialized value because because the materialized value needn't be promoted to an eden survivor space or the tenured generation which is the more expensive operation in garbage collection. The application keeps a reference to the RawType
only and can continue to transiently decode the value and release it as needed.
In the case where a value needs to be transfered from one serializable object to another, a RawType allows the transfer of the field without decoding or reencoding the value. For latency sensitive application this is important for two reasons. Firstly decoding to a value introduces intermediate garbage in the form of the materialized value returned by getValue()
, and secondly the decode/encode operation costs clock cycles, particulary for types like a String
where encoding and decoding is an expensive operation.
As alluded to above, for a networking application that reuses its network buffers, a RawType
can be layered on top of a network buffer and presented to the application which can pass the RawType
to an outbound network buffer where it can be written without (de)serialization and (d)encoding. When the backing buffer is a direct or native buffer this provides a mechanism for field transfer with zero intermediate copy.
A RawType
created via one of the factory methods of RawDataFactory
is immutable from the point that it is initialized unless it is specifically created otherwise (not generally reccomended). Once initialized via initialize(Object)
or initializeFrom(RawType)
, a factory created RawType
is threadsafe.
However, not all RawType
s are threadsafe or immutable: platform created RawType
may not always be immutable. Applications can test for immutability and initialization of a RawType
via isImmutable()
and isInitialized()
. When dealing with RawType
returned by platform classes the documentation of the class should be consulted to determine what threadsafety and immutability guarantees are provided. In cases where the platform doesn't guaranteed immutability, application can make use of copyInto(RawType)
to create an immutable version of the RawType
if needs be.