Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
8b13dc2
Refactor code to improve consistency and clarity, including updates t…
peter-lawrey Nov 19, 2025
723a73b
Add CLAUDE.md and GEMINI.md for project guidance and documentation
peter-lawrey Nov 19, 2025
c3e3a24
Refactor ByteBuffer handling to use BufferUtil methods for improved c…
peter-lawrey Nov 19, 2025
614074d
Refine documentation formatting for clarity and consistency
peter-lawrey Nov 19, 2025
08e1544
Add BufferUtil class for ByteBuffer compatibility with Java 8+
peter-lawrey Nov 19, 2025
866b39a
Refactor documentation for clarity and consistency across multiple files
peter-lawrey Nov 19, 2025
fc8d058
Import ISO_8859_1 charset for byte manipulation
peter-lawrey Nov 19, 2025
8a22264
Code Analysis fixes
peter-lawrey Nov 21, 2025
b3a7e92
Enhance documentation for JMH benchmarks, adding detailed description…
peter-lawrey Nov 24, 2025
df92edd
Remove unnecessary blank lines in various classes for improved code r…
peter-lawrey Nov 24, 2025
10b99fd
Remove unnecessary blank lines in various classes for improved code r…
peter-lawrey Nov 24, 2025
64fadc8
Mark multiple methods and classes as deprecated, scheduled for remova…
peter-lawrey Nov 27, 2025
fe22862
Add deprecation warnings to suppressions across multiple classes for …
peter-lawrey Nov 27, 2025
59605a8
Remove deprecated annotation from index method in SourceContext for c…
peter-lawrey Nov 28, 2025
2ce13aa
Enhance documentation for Chronicle Bytes: add system properties over…
peter-lawrey Dec 1, 2025
30f64a8
Add documentation for JMH benchmark classes and package-info; improve…
peter-lawrey Dec 1, 2025
091fa11
Enhance documentation and clean up code in BytesStore and related cla…
peter-lawrey Dec 1, 2025
1ac633c
Refactor test classes: add missing Javadoc comments and clean up comm…
peter-lawrey Dec 1, 2025
62e734b
Add CLAUDE and GEMINI documentation; update AGENTS and README files
peter-lawrey Dec 1, 2025
232d863
Merge branch 'adv/javadoc' into adv/develop
peter-lawrey Dec 1, 2025
01636e8
Refactor BufferUtil usage across multiple classes for improved clarit…
peter-lawrey Dec 1, 2025
94900b9
Update deprecation year for isPresent field in AbstractBytes class
peter-lawrey Dec 1, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 63 additions & 10 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Guidance for AI agents, bots, and humans contributing to Chronicle Software's OpenHFT projects.

Follow the root `AGENTS.md` for base rules; this file adds Chronicle-Bytes specifics. Durable docs live in `src/main/docs/` with the landing page at `README.adoc`.

LLM-based agents can accelerate development only if they respect our house rules. This file tells you:

* how to run and verify the build;
Expand All @@ -8,11 +10,12 @@ LLM-based agents can accelerate development only if they respect our house rules

## Language & character-set policy

| Requirement | Rationale |
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
| **British English** spelling (`organisation`, `licence`, *not* `organization`, `license`) except technical US spellings like `synchronized` | Keeps wording consistent with Chronicle's London HQ and existing docs. See the University of Oxford style guide for reference. |
| **ISO-8859-1** (code-points 0-255), except in string literals. Avoid smart quotes, non-breaking spaces and accented characters. | ISO-8859-1 survives every toolchain Chronicle uses, incl. low-latency binary wire formats that expect the 8th bit to be 0. |
| If a symbol is not available in ISO-8859-1, use a textual form such as `micro-second`, `>=`, `:alpha:`, `:yes:`. This is the preferred approach and Unicode must not be inserted. | Extended or '8-bit ASCII' variants are *not* portable and are therefore disallowed. |
| Requirement | Rationale |
|--------------|-----------|
| **British English** spelling (`organisation`, `licence`, *not* `organization`, `license`) except technical US spellings like `synchronized` | Keeps wording consistent with Chronicle's London HQ and existing docs. See the [University of Oxford style guide](https://www.ox.ac.uk/public-affairs/style-guide) for reference. |
| **ISO-8859-1** (code-points 0-255). Avoid smart quotes, non-breaking spaces and accented characters. | ISO-8859-1 survives every toolchain Chronicle uses. |
| If a symbol is not available in ISO-8859-1, use a textual form such as `>=`, `:alpha:`, `:yes:`. This is the preferred approach and Unicode must not be inserted. | Extended or '8-bit ASCII' variants are *not* portable and are therefore disallowed. |
| Tools to check ASCII compliance include `iconv -f ascii -t ascii` and IDE settings that flag non-ASCII characters. | These help catch stray Unicode characters before code review. |

## Javadoc guidelines

Expand All @@ -26,16 +29,39 @@ noise and slows readers down.
| Prefer `@param` for *constraints* and `@throws` for *conditions*, following Oracle's style guide. | Pad comments to reach a line-length target. |
| Remove or rewrite autogenerated Javadoc for trivial getters/setters. | Leave stale comments that now contradict the code. |

The principle that Javadoc should only explain what is *not* manifest from the signature is well-established in the
wider Java community.
The principle that Javadoc should only explain what is *not* manifest from the
signature is well-established in the wider Java community.

Inline comments should also avoid noise. The following example shows the
difference:

```java
// BAD: adds no value
int count; // the count

// GOOD: explains a subtlety
// count of messages pending flush
int count;
```

## Build & test commands

Agents must verify that the project still compiles and all unit tests pass before opening a PR:
Agents must verify that the project still compiles and all unit tests pass before opening a PR. Running from a clean checkout avoids stale artifacts:

```bash
# From repo root
mvn -q verify
mvn -q clean verify
```
The command should exit with code `0` to indicate success.

For static analysis and coverage:

* From the repo root, run `mvn -P quality clean verify` to apply the shared Checkstyle and SpotBugs rules from `root-parent-pom`.
* From the repo root, run `mvn -P sonar clean verify` to generate JaCoCo coverage and SonarCloud inputs.
* For a single-module quality pass on Chronicle-Bytes with Checkstyle and SpotBugs bound as gating checks on Java 11+, run:

```bash
mvn -q -pl :chronicle-bytes -am clean verify
```

## Commit-message & PR etiquette
Expand All @@ -45,6 +71,13 @@ mvn -q verify
3. In *body*: *root cause -> fix -> measurable impact* (latency, allocation, etc.). Use ASCII bullet points.
4. **Run `mvn verify`** again after rebasing.

### When to open a PR

* Open a pull request once your branch builds and tests pass with `mvn -q clean verify`.
* Link the PR to the relevant issue or decision record.
* Keep PRs focused: avoid bundling unrelated refactoring with new features.
* Re-run the build after addressing review comments to ensure nothing broke.

## What to ask the reviewers

* *Is this AsciiDoc documentation precise enough for a clean-room re-implementation?*
Expand Down Expand Up @@ -151,11 +184,31 @@ Notes/Links::
Do not rely on indentation for list items in AsciiDoc documents. Use the following pattern instead:

```asciidoc
section:: Top Level Section
section :: Top Level Section (Optional)
* first level
** nested level
```

### Emphasis and Bold Text

In AsciiDoc, an underscore `_` is _emphasis_; `*text*` is *bold*.

### Section Numbering

Use automatic section numbering for all `.adoc` files.

* Add `:sectnums:` to the document header.
* Do not prefix section titles with manual numbers to avoid duplication.

```asciidoc
= Document Title
Chronicle Software
:toc:
:sectnums:
:lang: en-GB
:source-highlighter: rouge

The document overview goes here.

== Section 1 Title
```
274 changes: 274 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Overview

Chronicle Bytes is a low-level memory access library that provides a high-performance alternative to Java's `ByteBuffer`. It offers off-heap memory management with deterministic resource cleanup, support for 63-bit sizes, and rich APIs for reading/writing primitives, strings (UTF-8/ISO-8859-1), and complex data structures.

**Key concepts:**
- **Bytes vs BytesStore**: `Bytes` instances are elastic and track read/write positions; `BytesStore` instances have fixed capacity and no position tracking
- **Off-heap memory**: Most implementations work with native memory outside the Java heap
- **Reference counting**: All off-heap resources must be explicitly released via `releaseLast()` or similar
- **Flyweight pattern**: Bytes objects act as views over underlying memory

## Build Commands

### Basic Build and Test

```bash
# Clean build with tests
mvn clean verify

# Build without tests (faster iteration)
mvn clean install -DskipTests

# Quiet mode (less output)
mvn -q clean verify
```

### Running Single Tests

```bash
# Run specific test class
mvn -Dtest=BytesTest test

# Run specific test method
mvn -Dtest=BytesTest#testAllocateElasticDirect test
```

### Code Quality Checks

```bash
# Run Checkstyle (checks coding standards)
mvn checkstyle:check

# Run SpotBugs (static analysis)
mvn spotbugs:check

# Quality profile with all checks
mvn -P quality clean verify

# Code coverage with JaCoCo
mvn -P sonar clean verify
```

### Benchmarks

```bash
# Run microbenchmarks
mvn -P run-benchmarks clean test
```

## Project Structure

```
src/main/java/net/openhft/chronicle/bytes/
├── Bytes.java # Main interface - elastic, position-aware
├── BytesStore.java # Fixed-size memory block interface
├── BytesIn.java # Read operations interface
├── BytesOut.java # Write operations interface
├── BytesMarshallable.java # Serialization support
├── MappedBytes.java # Memory-mapped file wrapper
├── NativeBytes.java # Off-heap implementation
├── VanillaBytes.java # Standard implementation
├── HexDumpBytes.java # Debug wrapper with hex output
├── algo/ # Algorithms (hashing, compression)
├── internal/ # Internal implementation classes
├── pool/ # Object pooling
├── ref/ # Reference types
└── util/ # Utility classes

src/main/docs/ # AsciiDoc documentation (canonical location)
├── project-requirements.adoc
├── architecture-overview.adoc
├── decision-log.adoc
└── security-review.adoc
```

## Architecture Principles

### Memory Management
- Chronicle Bytes uses **reference counting** for deterministic cleanup of off-heap resources
- Always call `bytes.releaseLast()` when done (or use try-with-resources)
- Tests MUST use `assertReferencesReleased()` from `Chronicle-Test-Framework` to verify cleanup

### Position Tracking
Every `Bytes` instance maintains four key positions:
- `readPosition`: where to read from next
- `writePosition`: where to write to next
- `readLimit`: maximum position that can be read
- `writeLimit`: maximum position that can be written

Unlike `ByteBuffer`, you don't need to flip between reading and writing.

### Threading
- `Bytes` instances are NOT thread-safe by default
- `BytesStore` can be shared across threads if data access is synchronized
- Atomic operations (CAS, volatile reads/writes) are available for `int`, `long`, `float`, `double`

### Encoding
- **Binary encoding**: Fixed-width primitives, stop-bit compression
- **Text encoding**: Parsing and appending primitives as text
- **String encoding**: Both ISO-8859-1 (8-bit) and UTF-8 supported
- **Stop-bit encoding**: Variable-length compression (see https://github.com/OpenHFT/RFC/blob/master/Stop-Bit-Encoding/Stop-Bit-Encoding-1.0.adoc)

## Common Development Tasks

### Creating Bytes Instances

```java
// On-heap, elastic
Bytes<byte[]> bytes = Bytes.allocateElasticOnHeap();

// Off-heap, elastic (must release)
Bytes<?> bytes = Bytes.allocateElasticDirect();
try {
// use bytes
} finally {
bytes.releaseLast();
}

// Memory-mapped file
MappedBytes bytes = MappedBytes.mappedBytes(file, chunkSize);
```

### Reading and Writing

```java
// Binary primitives
bytes.writeInt(42);
bytes.writeLong(123L);
int value = bytes.readInt();

// With explicit positions (random access)
bytes.writeInt(offset, 42);
int value = bytes.readInt(offset);

// Strings
bytes.writeUtf8("hello");
bytes.write8bit("world");
String s = bytes.readUtf8();

// Stop-bit compressed
bytes.writeStopBit(1234567L);
long value = bytes.readStopBit();
```

### Testing Resource Cleanup

```java
@Test
public void testBytesCleanup() {
Bytes<?> bytes = Bytes.allocateElasticDirect();
bytes.writeInt(42);
bytes.releaseLast();

// Verify all off-heap resources released
assertReferencesReleased();
}
```

## Code Style Requirements

### Language and Character Set
- **British English** spelling (`synchronise`, `behaviour`, `colour`)
- **ISO-8859-1** characters only - no smart quotes, em-dashes, or Unicode
- Use `>=`, `<=` instead of Unicode symbols
- Check with: `iconv -f ascii -t ascii`

### Javadoc
- Only document what's NOT obvious from the method signature
- Explain behaviour, contracts, thread-safety, edge cases, performance
- Remove autogenerated "Gets the X" / "Sets the Y" comments
- Keep first sentence concise (it becomes the summary)

**Good Javadoc:**
```java
/**
* Reads a stop-bit encoded long value. Values in range [-63, 127]
* consume 1 byte; larger values use variable-length encoding.
*
* @return the decoded long value
* @throws BufferUnderflowException if insufficient bytes available
*/
long readStopBit();
```

**Bad Javadoc:**
```java
/**
* Reads stop bit.
*
* @return long the long
*/
long readStopBit();
```

### Dependencies
This module depends on:
- `chronicle-core` - foundational utilities (`Jvm`, `OS`, resource management)
- `posix` - native OS calls
- `chronicle-test-framework` - test utilities (use for `assertReferencesReleased()`)

When adding dependencies, use versions from `chronicle-bom` or `third-party-bom`.

## Important System Properties

Set these via `-Dproperty=value`:

| Property | Default | Purpose |
|----------|---------|---------|
| `bytes.guarded` | `false` | Enable additional safety checks |
| `bytes.bounds.unchecked` | `false` | Disable bounds checking (performance) |
| `trace.mapped.bytes` | `false` | Debug mapped file lifecycle |
| `bytes.max-array-len` | `16777216` | Max array length for reads |

See `src/main/docs/system-properties.adoc` for complete list.

## Documentation Standards

- **Format**: AsciiDoc (`.adoc`)
- **Location**: `src/main/docs/` (canonical)
- **Language**: British English
- **Character set**: ISO-8859-1
- **Source highlighter**: `:source-highlighter: rouge`
- **Section numbering**: Use `:sectnums:` in header

Key documentation files:
- `project-requirements.adoc` - Functional requirements with Nine-Box tags (FN, NF-P, etc.)
- `decision-log.adoc` - Architecture Decision Records
- `architecture-overview.adoc` - High-level design
- `security-review.adoc` - Security considerations

## Testing Guidelines

- Use **JUnit 5** for new tests (JUnit 4 supported for legacy)
- Test class naming: `*Test` suffix
- Always verify resource cleanup with `assertReferencesReleased()`
- Use `SystemTimeProvider` for time-dependent tests
- Surefire config: `forkCount=4, reuseForks=true`

## Before Opening a PR

1. Run `mvn clean verify` - must exit with code 0
2. Run `mvn checkstyle:check` if touching production code
3. Verify all new off-heap allocations are released
4. Update relevant `.adoc` documentation
5. Write commit message: imperative mood, ≤72 chars, reference JIRA/GitHub issue
6. Explain: root cause → fix → measurable impact

## Common Pitfalls

1. **Forgetting to release**: Off-heap `Bytes` instances must call `releaseLast()`
2. **Thread safety**: `Bytes` is NOT thread-safe; use `BytesStore` with synchronization
3. **Position confusion**: Remember `writePosition` is also the `readLimit`
4. **Character encoding**: Don't use Unicode in source files - ISO-8859-1 only
5. **Javadoc noise**: Remove "Gets X" / "Sets Y" comments that add no value

## Additional Resources

- README.adoc - User-facing introduction with examples
- AGENTS.md - General AI agent guidelines (Javadoc policy, build commands)
- `src/main/docs/system-properties.adoc` - Complete system property reference
- `src/main/docs/decision-log.adoc` - Architecture decisions
Loading