The Talon Manual

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 7 Current »

In This Section

What is an XString?

Java Strings pose challenges for ultra low latency applications looking to achieve zero garbage. Because java.lang.Strings are immutable they are not conducive to pooling and preallocation, and encoding and decoding of String can be cpu intensive. Consequently, Talon provides an alternate implementation, XString. An XString wraps an encoded set of bytes representing a string. An XString provides the ability to manipulate String values without generating the garbage associated with Java's String implementation. An XString is often referred to as a 'RawString' which is a historical moniker that reflects XString raw access to the String underlying serialized byte form.

This class serves the following purposes:

Zero Garbage Preallocation

If a String needs to be maintained in memory for a long period of time as part of an application's state, late allocation of the String would normally produce an object that generational garbage collection would have to promote into tenured memory. For latency sensitive application's promotion of the String to the tenured generation will leads to garbage collection pauses. A XString allows preallocation of memory for such a field up front whereas a String can't be preallocated because it is immutable.

An XString may be preallocated via one of its factory methods or via the factory methods for XString in XFactory. The XString 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 thereby eliminating pauses that would result from minor gc during normal application operation.

When the XString is later assigned from another XString, 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 XString and can pass it off to application code that has a preallocated XString 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 XString only and can continue to transiently decode the value and release it as needed.

Zero Copy/Reencode Serializable Field Transfer

In the case where a value needs to be transfered from one serializable object to another, an XString allows the transfer of the field without costly character decoding or reencoding the value. For latency sensitive application this is important for two reasons. Firstly, decoding to a String introduces intermediate garbage in the form of the materialized value returned by getValue(), and secondly the decode/encode operation costs clock cycles.

As alluded to above, for a networking application that reuses its network buffers, a XString can be layered on top of a network buffer and presented to the application which can pass the XString to an outbound network buffer where it can be written without (de)serialization and (re)encoding. When the backing buffer is a direct or native buffer this provides a mechanism for field transfer with zero intermediate copy.

Immutability of XString

An immutable XString created via one of the factory methods of XFactory is immutable from the point that it is initialized. Once initialized via a setter method, a factory created XString is threadsafe.

However, not all XStrings are threadsafe or immutable: platform created XString may not always be immutable. Applications can test for immutability and initialization of a XString via isImmutable() and isInitialized(). When dealing with XStrings returned by platform classes the documentation of the class should be consulted to determine what thread safety and immutability guarantees are provided. In cases where the platform doesn't guaranteed immutability, applications can make use of copyInto(XString) to create an immutable version of the XString if needs be.

Character Encoding

For interoperability XString implements Appendable and CharSequence. Currently XString only supports ascii encdodable characters when working with these interfaces, or any of the other char based methods it supports. An XString can opaquely wrap and and pass non ascii encodabled XStrings, but for performance reasons direct character manipulation of non ascii text is not supported.

CharSequence view

XString implements CharSequence. The hashCode() and equals(Object) implementations of this view and those returned by subSequence(int, int) are not guaranteed to be remain stable when an XString is mutable or not yet initialized.

Equality and hashCode

XStrings that are immutable obey the contract for object equality and hashCode. Additionally, an XString will equal another XString.subSequence(int, int) if they have the same value. An XString will not equal another String of the same value.

XString ADM Accessors

ADM generated messages and entities provide specialized setters and getters for String fields that accept an XString which allows zero garbage operation. The following tables list String related accessors for a field named XXX, and highlights whether or not the accessor is zerog garbage when using Xbuf encoding. 

GettersDescriptionZero Garbage
String getXXX()

Returns the field value as a String.

No
String getXXX(String defaultIfNotSet)

Returns the field value as a String, or the provided value if the field is not set.

No

XString getXXXUnsafe()

Returns the raw XString which may be pooled along with the message and point to its backing buffer.

(warning) Note: The caller may not hold a reference to or modify the returned value beyond the pooling lifespan of the object which is typically a message handler.

Yes

XString getXXXUnsafe(XString defaultIfNotSet)

Returns the getXXXUnsafe() or the provided XString if the field is not set. The same Yes
void getXXXTo(XString to)

Copying accessor. Copies the value of the field into the provided XString.

This method is a safer alternative to getXXXUnsafe as the copied value is safe to retain beyond thepooling lifespan of the object.

Yes

void getXXXTo(XString to, XString defaultIfNotSet)

Copying accessor. This is equivalent to getXXXTo(XString to), but if the field is not set the default value is copied into the provided value.

Yes
<T extends XString> T getXXXTo(XString.Factory<T> factory)

Copying accessor. Similar to getXXXTo, but draws the value to copy into from the provided XString factory.

This method is useful when working with a string field that is declared as poolable. This allows the application to preallocate a pool of XStrings to draw upon when copying string fields from a message

Yes
<T extends XString> T getXXXTo(XString.Factory<T>factory, T defaultIfNotSet)

Copying accessor. Similar to getXXXTo(factory), but will copy in the provided default value if the field is not set on the object.

Yes
SettersDescription 

void setXXX(String val)

Sets the value of the fieldYes
void setXXXFrom(long val)Encodes the provider long value as a decimal string.Yes
void setXXXFrom(XString val)Copying setter. This method copies the provided value into the object. This method can be more efficient than the setXXX(String) as it can copy the provided value's backing buffer directly.Yes
void lendXXX(XString)

This method is equivalent to setXXX except that it allows this object to defer copying the value until this object is next serialized.

(warning) Note: This means that the caller must not modify or dispose the value being passed in to this method. See the javadoc on the generated method for more deatils.

(lightbulb) Prior to the version 3.8, ADM generated code would not allow lending of a null value and would result in a NullPointerException, this retriction was relaxed in 3.8 to treat a null value as clearing the field.

Yes

See also: XBuf - Repeated Field Bulk Copies

  • No labels