Using Protocol Buffer Objects

The sosscli::NamedProtobufCache<T> class performs automatic serialization and deserialization of classes that were generated by the Protocol Buffer ("protobuf") compiler using .proto files that you define.

// Sample protobuf Message Specification: StockQuote.proto

package NativeClientSample;  // 1
option optimize_for = SPEED;

// Stock object
message StockQuote
{
  required string ticker = 1;
  required float price = 2;
  required int64 volume = 3;
}

1

The package specification here corresponds to the C++ namespace that the generated classes will belong to. We use "NativeClientSample" for the StockQuote class that’s used throughout this guide, which is why you will see "using namespace NativeClientSample;" statements in many of the C++ code examples.

Running a .proto file through the protobuf compiler (protoc) on the command line will generate C++ headers and source files for each message type that is defined, which can then be added to your project. In the simplest case, protoc takes arguments like those below:

$ protoc --cpp_out=. --proto_path=/usr/include StockQuote.proto
[Note] Note

Visit the Protocol Buffer project page or view the protoc help output for details on the protobuf compiler’s options.

The NamedProtobufCache supports indexing of protobuf fields in the StateServer service and the ability to filter on those fields when performing queries. If, for example, we wanted to be able to perform a query against the StateServer service and filter out StockQuotes based on the price and/or volume fields, we could change the StockQuote’s .proto file as follows:

import "soss_client/SossIndex.proto";  // 1

package NativeClientSample;
option optimize_for = SPEED;

// Stock object
message StockQuote
{
  required string ticker = 1;
  required float price = 2  [(sosscli.SossIndex) = Hashable];   // 2
  required int64 volume = 3 [(sosscli.SossIndex) = Hashable];
}

1

The SossIndex.proto that’s being imported here contains custom Protocol Buffer options that can be used to annotate fields in your message definitions. Import this file if you’d like the StateServer service to index your protobuf objects.

2

Fields annotated with the sosscli.SossIndex option will be indexed in the StateServer service, allowing them to be used in a query filter expression.

The sosscli.SossIndex option can be assigned one of three values:

Hashable
The field’s value will be indexed and entered into the service’s internal property index hashtable, resulting in faster filter performance. Up to 8 fields in your class can have values stored in the service’s hashtable.
HighPriorityHashable
The field’s value will be indexed and entered into the service’s internal property index hashtable, resulting in faster filter performance. If more than 8 fields have been marked as Hashable, then those marked as HighPriorityHashable will take precedence. Note that even if an indexed field’s value is not in the hashtable then it can still be used in a query filter expression, albeit with reduced performance.
NotHashable
The field’s value will be indexed but will not be entered into the service’s internal property index hashtable.

Remember to rerun your .proto files through the Protocol Buffer compiler after editing them, otherwise the generated classes in your file won’t reflect your latest changes. Also, when importing the SossIndex.proto file, you may need to add a new --proto_path option to protoc to tell it where ScaleOut’s SossIndex.proto file resides—the location may vary depending on your OS/distro, but it will typically be located in the C++ Native Client API’s include directory with the rest of the API’s header files, for example:

$ protoc --cpp_out=. --proto_path=/usr/include --proto_path=/usr/local/soss/cpp_api/include  StockQuote.proto