RBNB V2.0 FAQ

This document provides a list of Frequently Asked Questions and answers to those questions for the RBNB V2.0 software. It also addresses differences between V1.x and V2.0 when the differences are likely to cause misunderstandings.

Table of Contents

How is byte order handled?
Where are automatic time-stamps generated?
What is the ring buffer?
How do I configure the the ring buffer?
When is data written to the archive?
How do I load an archive back into the server?
How do I set V2 timestamps?

How is byte order handled?

Normally, byte order is handled automatically by the RBNB system. The API automatically determines the source byte order and swaps bytes as needed to ensure that the sink gets the data in the byte order it expects. For example, arrays of primitives (shorts, floats, Java longs, etc.) in Java and C can be put into the RBNB system and then retrieved by any other Java or C application. So long as the source application has or can convert the data into such an array,  sink applications do not need to handle byte order.

For a complete list of the primitive types supported by the RBNB system, see the ChannelMap.TYPE_xxx fields.

When the source's byte order is significant and must be maintained (as with legacy applications), the data should be passed through the RBNB system in the form of an array of bytes using  TYPE_INT8. This turns off the automatic byte order handling in the RBNB system and leaves the user responsible for dealing with any byte order issues. Programs such as rbnbPlot that expect to be informed of the data type are unable to display such data.

Where are automatic time-stamps generated?

Automatic time-stamps are generated by the client-side API. This is unlike V1.x, where the server generates automatic time-stamps.  In a future V2 release, we may restore server-side automatic timestamps, as this provides a convenient way to synchronize multiple source clients.  Keep in mind that automatic timestamps are meant to be a convenient but approximate solution.  Use explicit PutTime methods to more precisely control the timestamps.

What is the ring buffer?

The Ring Buffered part of the "Ring Buffered Network Bus" refers to the way that data is stored in the RBNB system. A ring buffer stores data in what appears to be a seamless ring of slots, each slot holding one block (termed a "frame") of data. At data arrives, it is placed in the next slot in the ring, replacing any previous frame stored in the slot. Pointers are maintained to the slot containing the oldest and newest data still stored in the ring buffer.

In V2.0, as with V1.x, the ring buffer actually consists of two main parts:

  1. An in-memory "cache", and
  2. A disk file "archive".
Unlike V1.x, where a single frame was the unit size for both adding and removing objects from the cache and archive, V2.0 adds two new hierarchical objects that increase the granularity of the ring buffer, while reducing the effort required to maintain its integrity when new data replaces older data. These two new objects are:
  1. FrameSets, which are the basic blocks of the cache, and
  2. FileSets, which are the basic blocks of the archive.
Frames (sent when a source flushes a ChannelMap) are added to the current active frameset as they arrive in the cache. Once the frameset reaches a configurable size, it is closed and a new one is created. Framesets are added to the current active fileset in the archive as they are closed by the cache. Once the fileset reaches a configurable size, it is closed and a new one is created. Closed framesets and filesets are read-only; no further frames or framesets are added, nor are any removed.

When the cache reaches its configured maximum size, a new frameset replaces the oldest frameset still in the cache. The oldest frameset is simply removed from the cache. Similarly, when the archive reaches its configured maximum size, new filesets replace the oldest fileset still in the archive. This is done by simply deleting the fileset, which consists of a directory containing several files.

How do I configure the the ring buffer?

The desired sizes of the cache and archive in frames are set by the source application when creating the source handle via the simple API. The actual maximum sizes of the cache and archive may be adjusted to maintain efficient integral relationships between:
  1. Frameset size for the cache
  2. Maximum size of the cache (frameset size times number of framesets)
  3. Fileset size for the archive
  4. Maximum size of the archive (fileset size times number of filesets)
The simple API does not currently allow the user to directly set the number of framesets and filesets. Instead, the server starts with a default of 10, and may adjust this to make sure that every frameset contains one or more frames, and every fileset contains one or more framesets.

When is data written to the archive?

Data is written to the archive whenever a frameset is closed. At that time, the contents of the frameset are written to the archive in the current fileset.

This is similar to the asynchronous mode in V1.x and, as with that mode, there is the danger that frames added to the most current frameset may not get written out to the archive if the server (or the host machine it is running on) should crash. This vulnerability will be addressed in a future release.

How do I load an archive back into the server?

When the source application creates its source handle via the constructor or through the use of the SetRingBuffer method. In addition to the size of the cache and the archive, there is a archive mode field which can take the following values: When an archive is loaded, no new data can be added to it. When an archive is opened for append, then the archive size is adjusted to match the new desired size as closely as possible. The frameset and fileset sizes are not changed.
 

How do I set V2 timestamps?

In V2 RBNB, timestamps are designed to be simple yet efficient.  The timestamp(s) you specify with the PutTime methods remain the "current" time that applies to subsequent PutData calls.  Thus, for the simplest case, you can set the time once for all data, as in:
PutTime
BeginLoop
PutData
EndLoop
If you want to explicitly set the time for every PutData, then structure your code to pair the PutTime/PutData calls, as in:
BeginLoop
PutTime
PutData
EndLoop