{"id":19765700,"url":"https://github.com/openhft/chronicle-values","last_synced_at":"2026-01-29T01:13:04.799Z","repository":{"id":27773394,"uuid":"31261879","full_name":"OpenHFT/Chronicle-Values","owner":"OpenHFT","description":null,"archived":false,"fork":false,"pushed_at":"2024-05-29T07:45:52.000Z","size":684,"stargazers_count":103,"open_issues_count":4,"forks_count":38,"subscribers_count":32,"default_branch":"ea","last_synced_at":"2024-05-29T07:50:54.292Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://chronicle.software  ","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpenHFT.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.adoc","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-02-24T13:44:32.000Z","updated_at":"2024-05-30T12:15:37.992Z","dependencies_parsed_at":"2023-02-17T00:10:20.479Z","dependency_job_id":"960c2d2a-a6a1-4b17-a4a9-6070e3f4f873","html_url":"https://github.com/OpenHFT/Chronicle-Values","commit_stats":null,"previous_names":[],"tags_count":61,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenHFT%2FChronicle-Values","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenHFT%2FChronicle-Values/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenHFT%2FChronicle-Values/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenHFT%2FChronicle-Values/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenHFT","download_url":"https://codeload.github.com/OpenHFT/Chronicle-Values/tar.gz/refs/heads/ea","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247174454,"owners_count":20896078,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-12T04:19:10.875Z","updated_at":"2026-01-29T01:13:04.793Z","avatar_url":"https://github.com/OpenHFT.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"= Chronicle-Values\nChronicle Software\n:css-signature: demo\n:toc: macro\n:toclevels: 3\n\nimage:https://maven-badges.herokuapp.com/maven-central/net.openhft/chronicle-values/badge.svg[link=https://maven-badges.herokuapp.com/maven-central/net.openhft/chronicle-values]\nimage:https://javadoc.io/badge2/net.openhft/chronicle-values/javadoc.svg[link=https://www.javadoc.io/doc/net.openhft/chronicle-values/latest/index.html]\nimage:https://img.shields.io/badge/release%20notes-subscribe-brightgreen[link=https://chronicle.software/release-notes/]\nimage:https://sonarcloud.io/api/project_badges/measure?project=OpenHFT_Chronicle-Values\u0026metric=alert_status[link=https://sonarcloud.io/dashboard?id=OpenHFT_Chronicle-Values]\n\ntoc::[]\n\n== About\n\nGeneration of constantly-sized flyweight accessors to https://github.com/OpenHFT/Chronicle-Bytes[Chronicle Bytes] and simple bean-style on-heap implementations from interfaces.\nInterfaces that can be processed by Chronicle-Values generation are called *value interfaces*.\n\n*Project status: Stable* - the feature matrix (see below) is very vast and not expected to be implemented further.\nPlease write the value interface according to the specification below, with *unit tests for your interface*.\nIf the generation from the value interface (according to spec) doesn't work, please report the case via GitHub issues.\n\nAll classes in the package `net.openhft.chronicle.values.internal` and its subpackages are internal implementation details.\nThey may change without notice and must not be referenced directly.\n\n=== Value interface specification\n\nValue interfaces must belong to a non-empty package (they cannot sit in the default package).\n\n.Simple example\n[source,java]\n----\npackage test;\n\ninterface Balance {\n    long getDollars();\n    void setDollars(long dollars);\n    long addDollars(long addition);\n\n    int getCents();\n    void setCents(int cents);\n}\n----\nThe above is compiled into either a 12-byte flyweight or a regular bean with `long dollars` and `int cents`.\n\n==== Supported field types\n\n===== All Java primitives\n`byte`, `boolean`, `char`, `short`, `int`, `long`, `float`, `double`\n\n===== String or CharSequence\nMust be annotated with `@MaxUtf8Length`:\n\n[source,java]\n----\ninterface Client {\n    CharSequence getName();\n    void setName(@MaxUtf8Length(20) CharSequence name);\n\n    CharSequence getStateCode();\n    void setStateCode(@NotNull @MaxUtf8Length(2) CharSequence stateCode);\n}\n----\n\nThe value supplied to `@MaxUtf8Length` is the allowed size once the text is encoded as UTF-8. The native form checks this limit when writing to the backing `BytesStore`.\nHeap implementations assume the caller supplies a compliant value and any breach is detected only when copied to a native instance.\n\n===== Another value interface\nAllows nested structures:\n\n[source,java]\n----\ninterface Point {\n    double getX();\n    void setX(double x);\n\n    double getY();\n    void setY(double y);\n}\n\ninterface Circle {\n    Point getCenter();\n    void getUsingCenter(Point using);\n    void setCenter(Point center);\n\n    double getRadius();\n    void setRadius(double radius);\n}\n----\n(Self-references are forbidden.)\n\n===== Any Java enum type\n[source,java]\n----\ninterface Order {\n    enum State { NEW, CANCELLED, FILLED }\n\n    State getState();\n    void setState(@NotNull State state);\n}\n----\nThe generated classes keep a reference to the array of constants for each enum field.\nThe `Enums` helper obtains this array via reflection from `EnumSet.getUniverse(Class)`.\nCaching the array lets the marshalling code translate ordinals without calling `values()` on every access.\n\n===== java.util.Date\n\n===== Array fields\nUse the `-At` suffix and make the first parameter `int index`:\n\n[source,java]\n----\ninterface SomeStats {\n    @Array(length = 100)\n    long getPercentFreqAt(int index);\n    void setPercentFreqAt(int index, long percentFreq);\n    long addPercentFreqAt(int index, long addition);\n}\n----\n\n==== Supported methods\n\n===== Simple get/set\n`[get]FieldName[At]`, `[set]FieldName[At]`, or `isFieldName` for boolean fields.\nYou may omit the `get`/`set` prefixes:\n\n[source,java]\n----\ninterface Point {\n    double x();\n    void x(double x);\n\n    double y();\n    void y(double y);\n}\n----\n\n===== Volatile get/set\n`getVolatileFieldName[At]`, `setVolatileFieldName[At]`\n\n===== Ordered set\n`setOrderedFieldName[At]` (similar to `AtomicInteger.lazySet`)\n\n===== Simple add\n`type addFieldName[At]([int index, ]type addition)`\nWorks for numeric primitives.\n\n===== Atomic add\n`type addAtomicFieldName[At]([int index, ]type addition)`\nAtomic variant for numeric primitives.\n\n===== Compare-and-swap\n`boolean compareAndSwapFieldName[At]([int index, ]type expected, type newValue)`\nWorks for primitives, enums, and `Date`.\n\n===== getUsing\n`getUsingFieldName[At]([int index, ]Type using)`\nFor `String`/`CharSequence`, `using` must be a `StringBuilder`.\nFor nested value interfaces, `using` is that interface.\n\n==== Table of supported methods\n\n[cols=\"1,^1,^1,^1,^1,^1,^1,^1\",options=\"header\"]\n|===\n| | Integer (`byte`-`long`) | `float`, `double` | `boolean` | Char sequence | Value interface | `enum` | `Date`\n\n| get / set\n| \u0026#x2713; | \u0026#x2713; | \u0026#x2713; | \u0026#x2713; | \u0026#x2713; | \u0026#x2713; | \u0026#x2713;\n\n| Volatile get/set, ordered set\n| \u0026#x2713; | \u0026#x2713; | \u0026#x2713; |  |  | \u0026#x2713; | \u0026#x2713;\n\n| Compare-and-swap\n| \u0026#x2713; | \u0026#x2713; | \u0026#x2713; |  |  | \u0026#x2713; | \u0026#x2713;\n\n| Simple add, atomic add\n| \u0026#x2713; | \u0026#x2713; |  |  |  |  |\n\n| getUsing\n|  |  |  | \u0026#x2713; | \u0026#x2713; |  |\n|===\n\n=== Field configuration via annotations\n\n==== Field ordering in flyweight layout\nFields are laid out group by group.\nUse `@Group` to cluster fields and control their ordering.\nFields without `@Group` form the default group, which always comes first:\n\n[source,java]\n----\ninterface Complex {\n    @Group(1)\n    double real();\n    void real(double real);\n\n    @Group(2)\n    double imaginary();\n    void imaginary(double imaginary);\n}\n----\n\n==== Field nullability\n`enum` and string fields are nullable by default; mark with `@NotNull` to forbid `null`:\n\n[source,java]\n----\ninterface Instrument {\n    CharSequence getSymbol();\n    void setSymbol(@NotNull @MaxUtf8Length(5) CharSequence symbol);\n}\n----\n\nWhen a field is nullable the generated native form stores a marker instead of the text.\nHeap implementations use an extra boolean for `CharSequence` fields to track a null value.\nWith `@NotNull` the setters emit a `NullPointerException` if given `null`.\n\n==== Numeric field ranges\nAnnotate with `@Range(min=, max=)` to reduce flyweight size:\n\n[source,java]\n----\ninterface Transaction {\n    int getSecondFromDayStart();\n    void setSecondFromDayStart(@Range(min = 0, max = 24 * 60 * 60) int secondFromDayStart);\n}\n----\n\n==== Field alignment\nEnsure a field does not cross a cache-line boundary, for example:\n\n[source,java]\n----\ninterface Message {\n\n    // ... other fields ...\n\n    @Align(dontCross = 64)\n    long getImportantField();\n    void setImportantField(long importantValue);\n}\n----\nSee the Javadocs of `@Align` and `@Array` for details.\n\n== Using Chronicle Values\n\n[source,java]\n----\n// Flyweight\nPoint offHeapPoint = Values.newNativeReference(Point.class);\n((Byteable) offHeapPoint).bytesStore(bytesStore, offset, 16);\noffHeapPoint.setX(0);\noffHeapPoint.setY(0);\n\n// On-heap\nPoint onHeapPoint = Values.newHeapInstance(Point.class);\nonHeapPoint.setX(1);\nonHeapPoint.setY(2);\n----\n\nGenerated classes implement:\n\n* `Copyable\u003cPoint\u003e` - e.g. `onHeapPoint.copyFrom(offHeapPoint)`\n* `BytesMarshallable` (Chronicle-Bytes)\n* Correct `equals`, `hashCode`, `toString`\n* `Byteable` (no-op on the heap implementation)\n\nThe `Copyable` feature allows an on-heap value to take a snapshot of a native instance or vice versa.\nThis provides a simple way to shuttle data between the two representations.\n\nYou may extend these in the interface to avoid casting:\n\n[source,java]\n----\ninterface Point extends Byteable, BytesMarshallable, Copyable\u003cPoint\u003e { ... }\n\nPoint offHeapPoint = Values.newNativeReference(Point.class);\n// no cast required\noffHeapPoint.bytesStore(bytesStore, offset, offHeapPoint.maxSize());\n----\n\n== Why Use Chronicle-Values and How It Fits In\n\nChronicle-Values empowers you to work with structured data with high performance and type safety, especially when interfacing with low-latency and off-heap memory systems.\nIt achieves this by generating efficient data accessors from Java interfaces.\n\n=== Core Benefits\n\nChronicle-Values is designed to provide:\n\n* **High Performance \u0026 Low Latency:** Access and manipulate data with minimal overhead, crucial for systems where every microsecond counts. This is particularly true when using its \"native\" (off-heap) implementations.\n* **Minimized GC Impact:** Through the use of off-heap 'flyweight' objects, which act as lightweight views onto raw byte data. This significantly reduces garbage collection pressure by avoiding the creation of numerous heap objects.\n* **Type Safety:** Define your data structures using standard Java interfaces. This provides compile-time checking, clear API contracts, and reduces runtime errors.\n* **Developer Convenience:** The library automatically generates the necessary accessor boilerplate (getters, setters, etc.) based on your interface definition and intuitive annotations. This saves development time and reduces manual coding errors.\n* **\"Zero-Deserialization\" Access:** Read data directly from memory without the traditional cost of hydrating full heap objects, allowing for faster processing.\n* **Seamless Integration:** Designed to work smoothly with other Chronicle libraries like Chronicle Map (for off-heap key-value stores) and Chronicle Queue (for low-latency messaging), enabling efficient data storage and exchange.\n\n=== Primary Use Cases\n\nChronicle-Values is ideal when you need to work with data that has a **fixed, well-defined structure at compile time**.\nCommon scenarios include:\n\n* Representing financial messages (e.g., FIX, SBE, or custom binary protocols).\n* Defining event payloads for event-sourcing architectures.\n* Creating complex, fixed-layout keys or values for use with Chronicle Map or Chronicle Queue.\n* Any situation where you need performant, typed access to structured binary data, whether on-heap or off-heap.\n\n=== How Chronicle-Values Complements Chronicle-Bytes\n\nChronicle-Values operates on top of Chronicle-Bytes, which provides the foundational layer for byte manipulation.\nWhile Values offers a higher-level, typed abstraction for _structured_ data, Chronicle-Bytes remains essential for:\n\n* Low-level, direct manipulation of byte sequences.\n* Implementing custom serialization or deserialization logic for arbitrary formats.\n* Parsing and constructing binary network protocols from scratch.\n* Handling dynamic, unstructured, or schema-less binary data.\n\n**Typical Workflow:**\nA common pattern is to use Chronicle-Bytes for initial I/O operations (e.g., reading from a network socket or a file) or to parse the outer envelope of a raw data stream.\nOnce you've identified a segment of that stream that corresponds to a known, fixed structure defined by a value interface, you can then map a Chronicle-Values native reference (flyweight) over that region for typed, convenient, and performant access.\n\n=== Heap vs. Native (Flyweight) Implementations\n\nFor every value interface, Chronicle-Values can generate two types of implementations:\n\n* **Native (Flyweight) References (`Values.newNativeReference(..)`):**\n** These are lightweight views onto a `BytesStore` (which can be on-heap or off-heap memory).\n** They provide maximum performance and are central to off-heap data strategies.\n** They do not store data themselves; they merely provide typed accessors to the underlying bytes.\n** Careful management of the backing `BytesStore`'s lifecycle is crucial (see section on Lifecycle Management).\n* **Heap Instances (`Values.newHeapInstance(..)`):**\n** These are standard Java objects (POJOs) that store their data on the Java heap.\n** Useful for interacting with other parts of your system that expect POJOs, or when off-heap performance is not the primary concern for a particular data structure.\n** Data can be easily copied between native and heap instances using the generated `copyFrom()` method (from the `Copyable` interface).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenhft%2Fchronicle-values","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenhft%2Fchronicle-values","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenhft%2Fchronicle-values/lists"}