This example demonstrates how to use Fory's row format for cache-friendly binary random access.
Row format is ideal for scenarios where you need:
- Partial serialization/deserialization: Read specific fields without deserializing entire objects
- Random field access: Access fields by index without full deserialization
- Interoperability with columnar formats: Convert between row and column formats
- Data processing pipelines: Efficient data transformation and filtering
- CMake 3.16 or higher (for CMake build)
- Bazel 8+ (for Bazel build)
- C++17 compatible compiler (GCC 7+, Clang 5+, MSVC 2017+)
include(FetchContent)
FetchContent_Declare(
fory
GIT_REPOSITORY https://github.com/apache/fory.git
GIT_TAG main
SOURCE_SUBDIR cpp
)
FetchContent_MakeAvailable(fory)
target_link_libraries(your_app PRIVATE fory::row_format)cd examples/cpp/hello_row
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . --parallel
./hello_rowOr use the provided script:
./run.shFrom the repository root:
bazel build //examples/cpp/hello_row:hello_row
bazel run //examples/cpp/hello_row:hello_rowOr use the provided script:
./run_bazel.shFor your own project using Fory as a dependency:
- Copy
MODULE.bazel.exampletoMODULE.bazelin your project root - Copy
BUILD.standalonetoBUILDin your source directory - Adjust the git commit or use
local_path_overridefor local development
# In your MODULE.bazel
bazel_dep(name = "fory", version = "0.16.0")
git_override(
module_name = "fory",
remote = "https://github.com/apache/fory.git",
commit = "main", # Use specific commit for reproducibility
)
# In your BUILD file
cc_binary(
name = "my_app",
srcs = ["main.cc"],
deps = [
"@fory//cpp/fory/encoder:fory_encoder",
"@fory//cpp/fory/row:fory_row_format",
],
)This example demonstrates:
- Manual row writing: Creating rows with schema definition
- Automatic encoding: Using
RowEncoderfor struct encoding - Nested structs: Encoding structs containing other structs
- Array encoding: Encoding vectors of structs
- Direct array creation: Creating arrays from vectors
Use the FORY_STRUCT macro to enable automatic encoding:
struct Employee {
std::string name;
int32_t id;
float salary;
FORY_STRUCT(Employee, name, id, salary);
};using namespace fory::row;
// Define schema
auto name_field = field("name", utf8());
auto age_field = field("age", int32());
std::vector<FieldPtr> fields = {name_field, age_field};
auto row_schema = schema(fields);
// Create and write row
RowWriter writer(row_schema);
writer.reset();
writer.write_string(0, "Alice");
writer.write(1, static_cast<int32_t>(25));
// Read back
auto row = writer.to_row();
std::cout << row->get_string(0) << std::endl; // "Alice"
std::cout << row->get_int32(1) << std::endl; // 25using namespace fory::row;
Employee emp{"Bob", 1001, 75000.0f};
encoder::RowEncoder<Employee> enc;
enc.encode(emp);
auto row = enc.get_writer().to_row();
std::cout << row->get_string(0) << std::endl; // "Bob"
std::cout << row->get_int32(1) << std::endl; // 1001
std::cout << row->get_float(2) << std::endl; // 75000.0Row format supports these field types:
| Function | Type |
|---|---|
int8() |
8-bit integer |
int16() |
16-bit int |
int32() |
32-bit int |
int64() |
64-bit int |
float32() |
32-bit float |
float64() |
64-bit float |
utf8() |
UTF-8 string |
binary() |
Binary data |
list(T) |
List of T |
struct(Fs) |
Struct fields |
# Link to row format library (includes serialization)
target_link_libraries(your_app PRIVATE fory::row_format)#include "fory/row/row.h"
#include "fory/row/schema.h"
#include "fory/row/writer.h"
#include "fory/encoder/row_encoder.h"
#include "fory/encoder/row_encode_trait.h"