diff --git a/.gitignore b/.gitignore index c2c9b499..c361c527 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,8 @@ *.iml *.ipr *.iws -.idea +.idea/ +.claude/ compat_reports # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml @@ -25,4 +26,4 @@ target # tests *.bin -*.deleteme \ No newline at end of file +*.deleteme diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..5c83c58f --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,161 @@ +# Guidance for AI agents, bots, and humans contributing to Chronicle Software's OpenHFT projects. + +LLM-based agents can accelerate development only if they respect our house rules. This file tells you: + +* how to run and verify the build; +* what *not* to comment; +* when to open pull requests. + +## 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. | + +## Javadoc guidelines + +**Goal:** Every Javadoc block should add information you cannot glean from the method signature alone. Anything else is +noise and slows readers down. + +| Do | Don't | +|----|-------| +| State *behavioural contracts*, edge-cases, thread-safety guarantees, units, performance characteristics and checked exceptions. | Restate the obvious ("Gets the value", "Sets the name"). | +| Keep the first sentence short; it becomes the summary line in aggregated docs. | Duplicate parameter names/ types unless more explanation is needed. | +| 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. + +## Build & test commands + +Agents must verify that the project still compiles and all unit tests pass before opening a PR: + +```bash +# From repo root +mvn -q verify +``` + +## Commit-message & PR etiquette + +1. **Subject line <= 72 chars**, imperative mood: Fix roll-cycle offset in `ExcerptAppender`. +2. Reference the JIRA/GitHub issue if it exists. +3. In *body*: *root cause -> fix -> measurable impact* (latency, allocation, etc.). Use ASCII bullet points. +4. **Run `mvn verify`** again after rebasing. + +## What to ask the reviewers + +* *Is this AsciiDoc documentation precise enough for a clean-room re-implementation?* +* Does the Javadoc explain the code's *why* and *how* that a junior developer would not be expected to work out? +* Are the documentation, tests and code updated together so the change is clear? +* Does the commit point back to the relevant requirement or decision tag? +* Would an example or small diagram help future maintainers? + +## Project requirements + +See the [Decision Log](src/main/docs/decision-log.adoc) for the latest project decisions. +See the [Project Requirements](src/main/docs/project-requirements.adoc) for details on project requirements. + +## Elevating the Workflow with Real-Time Documentation + +Building upon our existing Iterative Workflow, the newest recommendation is to emphasise *real-time updates* to documentation. +Ensure the relevant `.adoc` files are updated when features, requirements, implementation details, or tests change. +This tight loop informs the AI accurately and creates immediate clarity for all team members. + +### Benefits of Real-Time Documentation + +* **Confidence in documentation**: Accurate docs prevent miscommunications that derail real-world outcomes. +* **Reduced drift**: Real-time updates keep requirements, tests and code aligned. +* **Faster feedback**: AI can quickly highlight inconsistencies when everything is in sync. +* **Better quality**: Frequent checks align the implementation with the specified behaviour. +* **Smoother onboarding**: Up-to-date AsciiDoc clarifies the system for new developers. +* **Incremental changes**: AIDE flags newly updated files so you can keep the documentation synchronised. + +### Best Practices + +* **Maintain Sync**: Keep documentation (AsciiDoc), tests, and code synchronised in version control. Changes in one area should prompt reviews and potential updates in the others. +* **Doc-First for New Work**: For *new* features or requirements, aim to update documentation first, then use AI to help produce or refine corresponding code and tests. For refactoring or initial bootstrapping, updates might flow from code/tests back to documentation, which should then be reviewed and finalised. +* **Small Commits**: Each commit should ideally relate to a single requirement or coherent change, making reviews easier for humans and AI analysis tools. +- **Team Buy-In**: Encourage everyone to review AI outputs critically and contribute to maintaining the synchronicity of all artefacts. + +## AI Agent Guidelines + +When using AI agents to assist with development, please adhere to the following guidelines: + +* **Respect the Language & Character-set Policy**: Ensure all AI-generated content follows the British English and ISO-8859-1 guidelines outlined above. +Focus on Clarity: AI-generated documentation should be clear and concise and add value beyond what is already present in the code or existing documentation. +* **Avoid Redundancy**: Do not generate content that duplicates existing documentation or code comments unless it provides additional context or clarification. +* **Review AI Outputs**: Always review AI-generated content for accuracy, relevance, and adherence to the project's documentation standards before committing it to the repository. + +## Company-Wide Tagging + +This section records **company-wide** decisions that apply to *all* Chronicle projects. All identifiers use the --xxx prefix. The `xxx` are unique across in the same Scope even if the tags are different. Component-specific decisions live in their xxx-decision-log.adoc files. + +### Tag Taxonomy (Nine-Box Framework) + +To improve traceability, we adopt the Nine-Box taxonomy for requirement and decision identifiers. These tags are used in addition to the existing ALL prefix, which remains reserved for global decisions across every project. + +.Adopt a Nine-Box Requirement Taxonomy + +|Tag | Scope | Typical examples | +|----|-------|------------------| +|FN |Functional user-visible behaviour | Message routing, business rules | +|NF-P |Non-functional - Performance | Latency budgets, throughput targets | +|NF-S |Non-functional - Security | Authentication method, TLS version | +|NF-O |Non-functional - Operability | Logging, monitoring, health checks | +|TEST |Test / QA obligations | Chaos scenarios, benchmarking rigs | +|DOC |Documentation obligations | Sequence diagrams, user guides | +|OPS |Operational / DevOps concerns | Helm values, deployment checklist | +|UX |Operator or end-user experience | CLI ergonomics, dashboard layouts | +|RISK |Compliance / risk controls | GDPR retention, audit trail | + +`ALL-*` stays global, case-exact tags. Pick one primary tag if multiple apply. + +### Decision Record Template + +```asciidoc +=== [Identifier] Title of Decision + +Date:: YYYY-MM-DD +Context:: +* What is the issue that this decision addresses? +* What are the driving forces, constraints, and requirements? +Decision Statement:: +* What is the change that is being proposed or was decided? +Alternatives Considered:: +* [Alternative 1 Name/Type]: +** *Description:* Brief description of the alternative. +** *Pros:* ... +** *Cons:* ... +* [Alternative 2 Name/Type]: +** *Description:* Brief description of the alternative. +** *Pros:* ... +** *Cons:* ... +Rationale for Decision:: +* Why was the chosen decision selected? +* How does it address the context and outweigh the cons of alternatives? +Impact & Consequences:: +* What are the positive and negative consequences of this decision? +* How does this decision affect the system, developers, users, or operations? +- What are the trade-offs made? +Notes/Links:: +** (Optional: Links to relevant issues, discussions, documentation, proof-of-concepts) +``` + +## Asciidoc formatting guidelines + +### List Indentation + +Do not rely on indentation for list items in AsciiDoc documents. Use the following pattern instead: + +```asciidoc +section:: Top Level Section +* first level + ** nested level +``` + +### Emphasis and Bold Text + +In AsciiDoc, an underscore `_` is _emphasis_; `*text*` is *bold*. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..755b7790 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,287 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +--- + +## Repository Overview + +Chronicle-Algorithms is a zero-allocation, high-performance Java library providing low-latency primitives for: + +* Fast non-cryptographic hashing (Murmur3, CityHash, xxHash) for data structures and indexing +* Cache-friendly bit set implementations for dense and sparse scenarios +* Unified byte accessors for on-heap arrays, direct buffers, Chronicle Bytes, and raw memory without hidden copying +* Lightweight, off-heap-capable lock strategies tuned for Chronicle primitives + +It is a foundational Chronicle library that: + +* Depends on **Chronicle-Core** and **Chronicle-Bytes** +* Is consumed by higher-level components like **Chronicle-Map** and **Chronicle-Queue** +* Is part of the wider **OpenHFT Chronicle** suite, focusing on performance-critical operations with minimal memory allocation + +--- + +## Build and Test Commands + +### Building + +```bash +# Full build with tests +mvn clean verify + +# Quiet mode (suppress Maven info logs) +mvn -q clean verify + +# Build without tests (faster iteration) +mvn -DskipTests clean install + +# Simple install (equivalent to full build unless customised) +mvn clean install +``` + +### Running Tests + +```bash +# Run all tests +mvn test + +# Run a single test class +mvn -Dtest=LongHashFunctionTest test +mvn test -Dtest=BitSetTest + +# Run a specific test method +mvn -Dtest=LongHashFunctionTest#testSpecificMethod test +mvn test -Dtest=BitSetTest#testFlip +``` + +### Code Coverage + +* Code coverage is measured with **JaCoCo**, configured in `pom.xml`. +* Current targets: + + * Line coverage: **57.9%** + * Branch coverage: **36.4%** + +When adding or modifying code, aim to keep coverage at or above these thresholds, and improve them where practical. + +--- + +## Code Architecture + +### Package Structure + +The codebase is organised under `net.openhft.chronicle.algo` into four main functional areas. + +**Public API packages:** + +* `net.openhft.chronicle.algo` + Core utilities (for example, `MemoryUnit`). + +* `net.openhft.chronicle.algo.hashing` + Non-cryptographic hash functions: + + * `LongHashFunction` (abstract base for hash implementations) + * `MurmurHash_3` + * `CityHash_1_1` + * `XxHash_r39` + +* `net.openhft.chronicle.algo.bytes` + Unified byte access abstractions: + + * `Access` / `ReadAccess` / `WriteAccess` / `AccessCommon` + * Accessors for arrays, `ByteBuffer`, `BytesStore`, `CharSequence` + * Key implementations: `NativeAccess`, `ByteBufferAccess`, `BytesAccesses`, array accessors + +* `net.openhft.chronicle.algo.bitset` + Bit set implementations: + + * `BitSet` (rigid `logicalSize()` unlike `java.util.BitSet`) + * `BitSetAlgorithm` (static utilities on raw memory via Access pattern) + * `BitSetFrame`, `SingleThreadedFlatBitSetFrame`, `ConcurrentFlatBitSetFrame` + * `ReusableBitSet` for reusing instances over different storage + +* `net.openhft.chronicle.algo.locks` + Lightweight locking strategies: + + * `LockingStrategy` and lock state interfaces + * `ReadWriteLockState` / `ReadWriteLockingStrategy` + * `ReadWriteUpdateLockState` / `ReadWriteUpdateLockingStrategy` + * `ReadWriteUpdateWithWaitsLockState` / corresponding strategy + * `AcquisitionStrategy`, `TryAcquireOperation`, `TryAcquireOperations` + * Vanilla implementations such as `VanillaReadWriteUpdateWithWaitsLockingStrategy`, `VanillaReadWriteWithWaitsLockingStrategy` + +**Internal/non-public packages:** + +* `net.openhft.chronicle.algo.internal` + Implementation details; not supported for external use and may change without notice. + +* `net.openhft.chronicle.algorithms.measures` + Hash quality evaluation tools and support tooling; not part of the stable public API. + +### Key Design Patterns + +1. **Access / Accessor Abstraction** + + The bytes package uses a two-level abstraction: + + * `Access` / `ReadAccess` / `WriteAccess` / `AccessCommon` + Define the primitive operations to read and write bytes (and primitives) for a handle type `T`. + + * `Accessor` + Converts a source type `S` (arrays, `ByteBuffer`, `BytesStore`, `CharSequence`) into an `Access` handle `T` using strategy `A`. + + This enables uniform, zero-copy operations over heterogeneous storage (heap arrays, direct buffers, off-heap memory) while keeping algorithms storage-agnostic. + +2. **Flyweight Pattern for Bit Sets** + + * `BitSetFrame` and `ReusableBitSet` act as views over underlying storage. + * Frames overlay contiguous memory (on-heap or off-heap) and provide `set/clear/flip` operations without additional allocation. + * All operations enforce `IndexOutOfBoundsException` for invalid indices. + +3. **Lock State and Strategy Separation** + + * Lock state (`ReadWriteLockState`, `ReadWriteUpdateLockState`, etc.) is separated from acquisition strategy (`LockingStrategy`, `AcquisitionStrategy`). + * This allows different lock behaviours (with/without waits, with update locks, etc.) to reuse the same state encoding and memory layout. + +4. **Zero-Allocation and Off-Heap Focus** + + * Core algorithms are designed to avoid allocations in hot paths. + * Operations work via the Access pattern on both heap and off-heap memory, minimising GC pressure. + * Reusable structures (for example, `ReusableBitSet`) and primitive-based APIs are preferred. + +5. **Strategy Pattern** + + * Hashing and locking algorithms use strategy interfaces to allow algorithm selection and customisation without changing call sites. + * This is particularly important for choosing different lock implementations or hash functions in performance-sensitive code. + +--- + +## Dependencies + +This module depends on: + +* **chronicle-core** + Low-level utilities (`Jvm`, `OS`, resource management, etc.). + +* **chronicle-bytes** + Off-heap memory access and buffer management. + +* **slf4j-api** + Logging facade (if used, should be minimal in hot paths). + +* **JetBrains annotations** (`annotations`) + For nullability and other code annotations. + +Version management is driven by BOMs: + +* `chronicle-bom` (for Chronicle artefacts, e.g. `2.27ea-SNAPSHOT`) +* `third-party-bom` (for third-party libraries, e.g. `3.27ea7`) + +Test dependencies: + +* JUnit 4 and JUnit 5 (Jupiter) +* Mockito +* Guava testlib + +--- + +## Testing + +* Frameworks: **JUnit 4** and **JUnit 5** +* Naming convention: test classes end with `*Test.java`. + +Typical commands: + +```bash +# Run all tests +mvn test + +# Run a specific package's tests +mvn -Dtest="net.openhft.chronicle.algo.hashing.*Test" test + +# Run a single test class +mvn -Dtest=LongHashFunctionTest test +mvn test -Dtest=BitSetTest + +# Run a specific test method +mvn -Dtest=LongHashFunctionTest#testSpecificMethod test +mvn test -Dtest=BitSetTest#testFlip +``` + +Guidance for changes: + +* Prefer deterministic tests for hashing (distribution/avalanche) and bit sets (boundary indices, dense/sparse cases). +* Keep tests compatible with both JUnit 4 and JUnit 5 where applicable. +* Ensure new tests integrate cleanly with existing Maven Surefire configuration and JaCoCo coverage rules. + +--- + +## Documentation + +Documentation is maintained in `src/main/docs/` using AsciiDoc: + +* `architecture-overview.adoc` – High-level architecture +* `project-requirements.adoc` – Functional/non-functional requirements with Nine-Box tags +* `decision-log.adoc` – Architecture Decision Records (ADRs) +* `testing-strategy.adoc` – Testing approach +* `security-review.adoc` – Security analysis + +**Documentation standards:** + +* Format: AsciiDoc (`.adoc`) +* Language: British English +* Character set: ISO-8859-1 +* Source highlighter: `:source-highlighter: rouge` + +When updating code, keep these docs in sync, especially requirements and decision logs. + +--- + +## Code Quality + +The repository follows Chronicle ecosystem quality standards: + +* Keep **Checkstyle** and **SpotBugs** clean; justify any suppressions inline. +* Avoid allocations in hot paths; maintain zero-allocation behaviour for core algorithms. +* Maintain off-heap bounds checks in all changes involving direct or Bytes-based access. +* Prefer deterministic property-based tests for hashing and bit set operations. +* Respect existing JaCoCo coverage thresholds; if they are temporarily reduced, document and justify the trade-off. + +See `AGENTS.md` for module-specific quality guidelines and Nine-Box requirement mappings. + +--- + +## Important Notes + +1. **Non-cryptographic Hashes Only** + Murmur3, CityHash, and xxHash are designed for speed and distribution, not security. + Do **not** use them for integrity checking, authentication, or confidentiality. + +2. **Internal Packages** + Anything under `net.openhft.chronicle.algo.internal` or `net.openhft.chronicle.algorithms.measures` is **not** public API. + Do not reference these from external code; treat them as implementation details. + +3. **Off-Heap Focus and Safety** + APIs are designed for zero-allocation operation with off-heap memory. + Changes must preserve: + + * Memory safety (bounds checking at API boundaries), + * Clear ownership and lifetime semantics for underlying storage. + +4. **Stable API Surface** + Public interfaces and classes under documented API packages should remain stable within a major version. + Internal implementations may evolve freely, but public behaviour must remain consistent with requirements and ADRs. + +5. **Nine-Box Requirements** + Code and comments may reference requirement IDs such as `ALGO-FN-010`, `ALGO-NF-P-001`, etc. + When modifying behaviour: + + * Preserve or update these tags as appropriate. + * Keep `project-requirements.adoc` and `decision-log.adoc` in sync with code changes. + +--- + +## License + +* **License:** Apache 2.0 (SPDX-License-Identifier: Apache-2.0) +* **Copyright:** 2013–2025 chronicle.software diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 00000000..1943c4fc --- /dev/null +++ b/GEMINI.md @@ -0,0 +1,30 @@ +# Chronicle-Algorithms + +## Project Overview + +Chronicle-Algorithms is a Java library providing zero-allocation, efficient algorithms for hashing, bit set operations, raw byte access, and lightweight off-heap-friendly locking. It is designed for high-performance, low-latency applications and is part of the OpenHFT/Chronicle ecosystem. + +The project is built with Maven and has dependencies on `chronicle-core` and `chronicle-bytes`. The public APIs are located in the `net.openhft.chronicle.algo` package and its subpackages: `.bitset`, `.bytes`, `.hashing`, and `.locks`. + +## Building and Running + +To build the project and run all tests, use the following Maven command: + +```sh +mvn -q clean verify +``` + +To build the project without running tests, you can use: + +```sh +mvn -pl Chronicle-Algorithms -am -DskipTests install +``` + +## Development Conventions + +* **Off-heap friendly:** APIs are designed to work with `Chronicle Bytes` and direct buffers, minimizing allocations. +* **Performance-focused:** The library prioritizes cache-friendly data structures and efficient algorithms. +* **Stable APIs:** Public interfaces are intended to be stable within a major version. +* **Clear Separation:** Internal packages (`net.openhft.chronicle.algo.internal`) are not meant for external use. +* **Testing:** The project uses JUnit and Mockito for testing. It also includes performance and benchmark tests using JMH. +* **Code Style:** The code follows standard Java conventions with clear Javadoc documentation. diff --git a/README.adoc b/README.adoc new file mode 100644 index 00000000..d36f9a29 --- /dev/null +++ b/README.adoc @@ -0,0 +1,250 @@ += Chronicle-Algorithms +:license: Apache 2.0 +:toc: macro +:toclevels: 3 +:lang: en-GB +:source-highlighter: rouge + +image:[https://maven-badges.herokuapp.com/maven-central/net.openhft/chronicle-algorithms/badge.svg[link="https://maven-badges.herokuapp.com/maven-central/net.openhft/chronicle-algorithms](https://maven-badges.herokuapp.com/maven-central/net.openhft/chronicle-algorithms/badge.svg[link=%22https://maven-badges.herokuapp.com/maven-central/net.openhft/chronicle-algorithms)"] +image:[https://javadoc.io/badge2/net.openhft/chronicle-algorithms/javadoc.svg[link="https://javadoc.io/doc/net.openhft/chronicle-algorithms](https://javadoc.io/badge2/net.openhft/chronicle-algorithms/javadoc.svg[link=%22https://javadoc.io/doc/net.openhft/chronicle-algorithms)"] +image:[https://img.shields.io/badge/License-Apache%202.0-blue.svg[link="https://opensource.org/licenses/Apache-2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg[link=%22https://opensource.org/licenses/Apache-2.0)"] + +Chronicle-Algorithms is a Java library providing zero-allocation, high-performance algorithms for hashing, bit set operations, off-heap locking, and low-level memory access. It is designed for latency-sensitive systems where garbage collection pauses are critical concerns. + +Zero-allocation, efficient algorithms for hashing, bit set operations, raw byte access, and lightweight off-heap-friendly locking. + +toc::[] + +== Features + +* **Hashing** +** Non-cryptographic 64-bit hash functions including CityHash 1.1, MurmurHash3, and xxHash r39. +** Optimised for performance and zero allocation, with consistent results across big-endian and little-endian platforms. + +* **Bit Sets** +** High-performance, rigid-capacity bit sets with both single-threaded and concurrent implementations. +** Cache-friendly, flat representations suitable for dense and sparse scenarios. +** Operate over raw memory or byte stores with strict bounds checking. + +* **Bytes Access** +** Unified abstractions for accessing raw bytes from diverse sources (arrays, `ByteBuffer`s, `String`s, off-heap memory, Chronicle Bytes) with zero allocation. +** Unified accessors for on-heap arrays, direct buffers, and Chronicle Bytes without hidden copying. + +* **Locking** +** Off-heap read-write-update locking strategies for concurrent access control. +** Lightweight locks tuned for Chronicle primitives rather than `java.util.concurrent` abstractions. + +* **Hash-Quality Evaluation Helpers** +** Hash-quality evaluation tools in `net.openhft.chronicle.algorithms.measures` for benchmarking and analysis (support tooling, not public API). + +== Package Layout + +* **Public APIs** +`net.openhft.chronicle.algo` and subpackages: + +* `.bitset` +* `.bytes` +* `.hashing` +* `.locks` + +* **Internal-only code** +`net.openhft.chronicle.algo.internal` and hash-quality tooling in `net.openhft.chronicle.algorithms.measures` are not supported for external use and may change without notice. + +== Documentation + +Documentation is maintained under `src/main/docs/`: + +* Architecture overview: link:src/main/docs/architecture-overview.adoc[] +* Requirements: link:src/main/docs/project-requirements.adoc[] +* Decision log: link:src/main/docs/decision-log.adoc[] +* Testing strategy: link:src/main/docs/testing-strategy.adoc[] +* Security review: link:src/main/docs/security-review.adoc[] + +Additional online resources: + +* Javadoc: [https://javadoc.io/doc/net.openhft/chronicle-algorithms](https://javadoc.io/doc/net.openhft/chronicle-algorithms) +* Maven Central metadata: [https://search.maven.org/artifact/net.openhft/chronicle-algorithms](https://search.maven.org/artifact/net.openhft/chronicle-algorithms) + +== Hashing + +The library provides a unified API for several non-cryptographic 64-bit hash functions through the `LongHashFunction` class. These implementations are optimised for performance, produce consistent results across platforms (big-endian and little-endian), and generate zero garbage. + +=== Supported Algorithms + +* **CityHash 1.1** – Based on Google's CityHash algorithm. +* **MurmurHash3** – Based on the SMHasher suite implementation. +* **xxHash r39** – Based on Cyan4973's xxHash (r39 revision). + +=== Usage Examples + +## [source,java,opts=novalidate] + +import net.openhft.chronicle.algo.hashing.LongHashFunction; + +public class HashingExample { +public static void main(String[] args) { +String input = "Hello World"; + +``` + // Get an instance of the hash function + LongHashFunction xxHash = LongHashFunction.xx_r39(); + + // Hash a String + long hash = xxHash.hashChars(input); + + // Hash a primitive + long longHash = xxHash.hashLong(123456789L); + + // Hash a byte array + byte[] data = new byte[] {1, 2, 3, 4, 5}; + long bytesHash = LongHashFunction.city_1_1().hashBytes(data); + + // Hash off-heap memory (unsafe access) + // long address = ...; // unsafe memory address + // long length = 64; + // long memoryHash = LongHashFunction.murmur_3().hashMemory(address, length); +} +``` + +## } + +== Bit Sets + +The `net.openhft.chronicle.algo.bitset` package provides `BitSet` implementations that operate over raw memory or byte stores. Unlike `java.util.BitSet`, which has dynamic capacity, Chronicle bit sets have a rigid logical size and throw `IndexOutOfBoundsException` for out-of-bounds access. + +=== Implementations + +* **SingleThreadedFlatBitSetFrame** – Not thread-safe, optimised for single-threaded access. +* **ConcurrentFlatBitSetFrame** – Thread-safe implementation using CAS (compare-and-swap) operations for concurrent access. +* **ReusableBitSet** – Adapter for reusing `BitSet` instances with different underlying storage. + +=== Usage Examples + +## [source,java,opts=novalidate] + +import net.openhft.chronicle.algo.bitset.BitSetFrame; +import net.openhft.chronicle.algo.bitset.SingleThreadedFlatBitSetFrame; +import net.openhft.chronicle.algo.bitset.ReusableBitSet; +import net.openhft.chronicle.algo.bytes.Access; +import java.nio.ByteBuffer; + +// Create a frame definition for 64 bits +BitSetFrame frame = new SingleThreadedFlatBitSetFrame(64); + +// Create a ByteBuffer to back the bit set +ByteBuffer buffer = ByteBuffer.allocate(8); // 64 bits = 8 bytes + +// Create the ReusableBitSet wrapper +ReusableBitSet bitSet = new ReusableBitSet(frame, Access.checkedByteBufferAccess(), buffer, 0); + +// Operations +bitSet.set(1); +bitSet.set(3); +boolean isSet = bitSet.get(1); // true +long nextSet = bitSet.nextSetBit(0); // 1 +----------------------------------------- + +== Bytes Access + +The `net.openhft.chronicle.algo.bytes` package provides a unified `Access` and `Accessor` abstraction to read and write primitives from various underlying sources without creating objects. This enables zero-allocation operations across heterogeneous data types. + +=== Supported Sources + +* **Native memory** – Direct access via `Unsafe`. +* **ByteBuffer** – Both heap and direct `ByteBuffer`s. +* **Arrays** – All primitive array types (`byte[]`, `long[]`, `int[]`, etc.). +* **CharSequence/String** – Efficient access to `String` internals (including compact strings in Java 9+). +* **BytesStore** – Chronicle Bytes abstractions. + +## [source,java,opts=novalidate] + +import net.openhft.chronicle.algo.bytes.Access; +import net.openhft.chronicle.algo.bytes.NativeAccess; + +// Native access singleton +Access unsafeAccess = NativeAccess.instance(); +long value = unsafeAccess.readLong(object, offset); +--------------------------------------------------- + +== Locking + +The `net.openhft.chronicle.algo.locks` package provides logic for read-write-update locks that can be stored off-heap or in shared memory. + +* **Read lock** – Multiple readers allowed. +* **Update lock** – Only one update lock allowed, but allows concurrent readers. Can upgrade to write lock. +* **Write lock** – Exclusive access. + +=== Locking Strategy + +The primary implementation is `VanillaReadWriteUpdateWithWaitsLockingStrategy`, which supports: + +* Lock upgrading (Read -> Update -> Write). +* Lock downgrading. +* Waiting strategies. + +All locking is implemented through the `Access` abstraction, enabling the lock state to reside in off-heap or shared memory regions. + +== Build and Test + +Quick commands: + +* Full build and tests: `mvn -q clean verify` +* Standard build and install: `mvn clean install` +* Module-only build (skip tests): `mvn -pl Chronicle-Algorithms -am -DskipTests install` +* Run all tests: `mvn test` +* Run specific test: `mvn test -Dtest=BitSetTest` + +=== Building from Source + +## [source,bash] + +# Clone the repository + +git clone [https://github.com/OpenHFT/Chronicle-Algorithms.git](https://github.com/OpenHFT/Chronicle-Algorithms.git) +cd Chronicle-Algorithms + +# Build and run tests + +mvn clean install + +# Run specific test + +## mvn test -Dtest=BitSetTest + +== Maven Dependency + +To include Chronicle-Algorithms in your project, add the following dependency to your `pom.xml`: + +## [source,xml] + + + net.openhft + chronicle-algorithms + 2.27ea1 + +---- + +NOTE: Check link:[https://search.maven.org/artifact/net.openhft/chronicle-algorithms[Maven](https://search.maven.org/artifact/net.openhft/chronicle-algorithms[Maven) Central] for the latest available version. + +== Support + +For questions, issues, or feature requests: + +* GitHub Issues: [https://github.com/OpenHFT/Chronicle-Algorithms/issues](https://github.com/OpenHFT/Chronicle-Algorithms/issues) +* Documentation: [https://javadoc.io/doc/net.openhft/chronicle-algorithms](https://javadoc.io/doc/net.openhft/chronicle-algorithms) +* Chronicle Software: [https://chronicle.software](https://chronicle.software) + +== Related Projects + +Part of the OpenHFT Chronicle suite: + +* link:[https://github.com/OpenHFT/Chronicle-Core[Chronicle-Core](https://github.com/OpenHFT/Chronicle-Core[Chronicle-Core)] – Low-level utilities and memory management. +* link:[https://github.com/OpenHFT/Chronicle-Bytes[Chronicle-Bytes](https://github.com/OpenHFT/Chronicle-Bytes[Chronicle-Bytes)] – Zero-copy bytes abstractions. +* link:[https://github.com/OpenHFT/Chronicle-Queue[Chronicle-Queue](https://github.com/OpenHFT/Chronicle-Queue[Chronicle-Queue)] – Persisted low-latency messaging. +* link:[https://github.com/OpenHFT/Chronicle-Map[Chronicle-Map](https://github.com/OpenHFT/Chronicle-Map[Chronicle-Map)] – Off-heap key-value store. + +== License + +Copyright 2013-2025 chronicle.software + +Licensed under the Apache License, Version 2.0. See the link:LICENSE file for details. diff --git a/README.md b/README.md deleted file mode 100644 index 4ee14d18..00000000 --- a/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Chronicle-Algorithms - - - - - - - - -Zero allocation, efficient algorithms for - -- hashing -- bit set operations -- access the raw bytes of an data type -- off heap locking diff --git a/measures/src/main/java/net/openhft/chronicle/algorithms/measures/AddressWrapper.java b/measures/src/main/java/net/openhft/chronicle/algorithms/measures/AddressWrapper.java index f33235cc..b553b876 100644 --- a/measures/src/main/java/net/openhft/chronicle/algorithms/measures/AddressWrapper.java +++ b/measures/src/main/java/net/openhft/chronicle/algorithms/measures/AddressWrapper.java @@ -4,10 +4,25 @@ package net.openhft.chronicle.algorithms.measures; /** - * Created by peter on 21/08/15. + * Minimal adapter that exposes a contiguous block of memory so hashing strategies can be compared + * without caring about the backing implementation. + *

+ * Implementations typically wrap off-heap memory and feed it into a hash function that operates on + * raw addresses instead of Java arrays. */ public interface AddressWrapper { + /** + * Point the wrapper at the supplied address range. + * + * @param address start address of the readable data + * @param length number of readable bytes from that address + */ void setAddress(long address, long length); + /** + * Hash the currently configured address range. + * + * @return hash value calculated over the configured memory region + */ long hash(); } diff --git a/measures/src/main/java/net/openhft/chronicle/algorithms/measures/AddressWrappers.java b/measures/src/main/java/net/openhft/chronicle/algorithms/measures/AddressWrappers.java index 9cdd6e8b..cc4bf2f1 100644 --- a/measures/src/main/java/net/openhft/chronicle/algorithms/measures/AddressWrappers.java +++ b/measures/src/main/java/net/openhft/chronicle/algorithms/measures/AddressWrappers.java @@ -14,9 +14,16 @@ import java.util.Random; /** - * Created by peter on 21/08/15. + * Collection of {@link AddressWrapper} implementations used to exercise hashing strategies over + * native memory. + *

+ * Each constant implements {@link #setAddress(long, long)} and {@link #hash()} using a different + * hashing approach so quality and performance can be compared by the score harnesses. */ public enum AddressWrappers implements AddressWrapper { + /** + * Returns a random {@code long} irrespective of the provided address. + */ RANDOM { Random rand = new Random(); @@ -29,6 +36,9 @@ public long hash() { return rand.nextLong(); } }, + /** + * Uses {@link SecureRandom} to return unpredictable values. + */ SECURE_RANDOM { SecureRandom rand = new SecureRandom(); @@ -42,6 +52,9 @@ public long hash() { } }, + /** + * Wraps the address as a {@link Bytes} and hashes using {@link OptimisedBytesStoreHash}. + */ VANILLA { int length; Bytes bytes; @@ -59,6 +72,9 @@ public long hash() { return OptimisedBytesStoreHash.applyAsLong32bytesMultiple(bytes, length); } }, + /** + * Hashes the memory region using {@link LongHashFunction#city_1_1()}. + */ CITY_1_1 { long address,length; @@ -73,6 +89,9 @@ public long hash() { return LongHashFunction.city_1_1().hash((Object) null, NativeAccess.instance(), address, length); } }, + /** + * Hashes the memory region using {@link LongHashFunction#murmur_3()}. + */ MURMUR_3 { long address,length; @@ -87,6 +106,10 @@ public long hash() { return LongHashFunction.murmur_3().hash((Object) null, NativeAccess.instance(), address, length); } }, + /** + * Builds a 32-bit hash by iterating over bytes as characters and applying the JDK + * {@link java.util.HashMap} agitation function to reduce collisions. + */ STRING32 { Bytes bytes; @@ -115,6 +138,9 @@ int hash(int h) { return h ^ (h >>> 7) ^ (h >>> 4); } }, + /** + * Builds a 64-bit hash using a similar approach to {@link #STRING32} but keeping more entropy. + */ STRING64 { Bytes bytes; @@ -139,6 +165,9 @@ long hash(long h) { return h ^ (h >>> 14) ^ (h >>> 7); } }, + /** + * Generates the raw 32-bit polynomial hash without the extra agitation step. + */ STRING32_WITHOUT_AGITATE { Bytes bytes; diff --git a/measures/src/main/java/net/openhft/chronicle/algorithms/measures/AvalancheScore.java b/measures/src/main/java/net/openhft/chronicle/algorithms/measures/AvalancheScore.java index 3478ccc0..3183aaff 100644 --- a/measures/src/main/java/net/openhft/chronicle/algorithms/measures/AvalancheScore.java +++ b/measures/src/main/java/net/openhft/chronicle/algorithms/measures/AvalancheScore.java @@ -9,16 +9,18 @@ import java.util.Arrays; /** - * Created by peter on 22/08/15. + * Measures the avalanche behaviour of a hash function using a SMHasher inspired workload. + *

+ * The test repeatedly flips individual input bits and observes how close the output comes to the + * ideal 50/50 bit flip distribution. A lower returned value indicates better avalanche properties. */ public class AvalancheScore { /** - * Based on the SMHasher Avalanche test - *

- * search for biases bits. - * when flipping a single bit of the input, the output should have a 49% - 51% chance of flipping. Some randomness is expected. + * Runs the avalanche test and reports the 99th percentile drift from the ideal 50 percent flip + * rate. * - * @return the worst flip bias. + * @param wrapper implementation used to hash raw memory + * @return 99th percentile deviation from the ideal bit flip percentage */ public static double score(AddressWrapper wrapper) { int runs = 1000; diff --git a/measures/src/main/java/net/openhft/chronicle/algorithms/measures/CheckMain.java b/measures/src/main/java/net/openhft/chronicle/algorithms/measures/CheckMain.java index 89cf190a..4e9373e7 100644 --- a/measures/src/main/java/net/openhft/chronicle/algorithms/measures/CheckMain.java +++ b/measures/src/main/java/net/openhft/chronicle/algorithms/measures/CheckMain.java @@ -38,6 +38,18 @@ Mask of Hash: 99%tile collisions: 1816 */ public class CheckMain { + + /** + * Command line harness that runs the hash quality measures for all configured address wrapper + * variants and prints summary statistics. + * + *

For each {@link AddressWrappers} entry this tool evaluates orthogonal bit scores, + * avalanche behaviour, and masked hash collisions using {@link OrtogonalBitsScore}, + * {@link AvalancheScore}, and {@link MaskHashScore}. The output is intended for manual + * inspection when comparing hash implementations, not for use on application hot paths. + * + * @param args ignored + */ public static void main(String[] args) { for (AddressWrappers aw : AddressWrappers.values()) { System.out.println(aw); diff --git a/measures/src/main/java/net/openhft/chronicle/algorithms/measures/MainBytes.java b/measures/src/main/java/net/openhft/chronicle/algorithms/measures/MainBytes.java index 50a588a6..99b8c556 100644 --- a/measures/src/main/java/net/openhft/chronicle/algorithms/measures/MainBytes.java +++ b/measures/src/main/java/net/openhft/chronicle/algorithms/measures/MainBytes.java @@ -19,6 +19,18 @@ import java.lang.reflect.Method; import java.util.concurrent.TimeUnit; +/** + * JMH microbenchmark that compares different hashing strategies over {@link Bytes} payloads. + * + *

The benchmark fills a direct {@link Bytes} instance with pseudo random 64 bit values and + * measures the throughput and latency of several hashing functions, including + * {@link OptimisedBytesStoreHash}, {@link LongHashFunction#city_1_1()}, {@link LongHashFunction#murmur_3()}, + * and {@link LongHashFunction#xx_r39()}. Payload size is controlled by the {@link #size} parameter. + * + *

When run under a debugger ({@link Jvm#isDebug()} is true) the benchmark methods are invoked + * directly. In normal operation the {@link Runner} entry point is used to execute the configured + * JMH benchmarks. + */ @State(Scope.Thread) public class MainBytes { static final LongHashFunction city_1_1 = LongHashFunction.city_1_1(); diff --git a/measures/src/main/java/net/openhft/chronicle/algorithms/measures/MaskHashScore.java b/measures/src/main/java/net/openhft/chronicle/algorithms/measures/MaskHashScore.java index 99815b09..ac6078cd 100644 --- a/measures/src/main/java/net/openhft/chronicle/algorithms/measures/MaskHashScore.java +++ b/measures/src/main/java/net/openhft/chronicle/algorithms/measures/MaskHashScore.java @@ -11,13 +11,14 @@ import java.util.Set; /** - * Created by peter on 22/08/15. + * Evaluates how evenly the low bits of a hash function are distributed. + *

+ * The routine hashes many one-bit variations of an input buffer and counts collisions after + * applying a bitmask, highlighting bias in the lower bits of the hash output. */ public class MaskHashScore { /** - * This test looks at how many collision you get in the lower bits. - * It generates 8K hashes, for 8Kbit input and look at at the lower 14 bits (for 16K values) - * The ideal is 8K unique hashes after mask. + * Run the masked hash collision test and return the 99th percentile number of collisions. */ public static double score(AddressWrapper wrapper) { int runs = 2000; diff --git a/measures/src/main/java/net/openhft/chronicle/algorithms/measures/OrtogonalBitsScore.java b/measures/src/main/java/net/openhft/chronicle/algorithms/measures/OrtogonalBitsScore.java index 277362cb..f5d73e3b 100644 --- a/measures/src/main/java/net/openhft/chronicle/algorithms/measures/OrtogonalBitsScore.java +++ b/measures/src/main/java/net/openhft/chronicle/algorithms/measures/OrtogonalBitsScore.java @@ -9,9 +9,18 @@ import java.util.Arrays; /** - * Created by peter on 21/08/15. + * Scores how orthogonal the outputs of a hash function are when single input bits flip. + *

+ * The metric penalises pairs of outputs whose Hamming distance is too small, providing a measure of + * output independence across nearby inputs. */ public class OrtogonalBitsScore { + /** + * Execute the orthogonality test and return the 99th percentile penalty score. + * + * @param wrapper implementation used to hash a native memory block + * @return high percentile cumulative penalty; lower values indicate better independence + */ public static long score(AddressWrapper wrapper) { int runs = 1000; long[] scores = new long[runs]; diff --git a/measures/src/main/java/net/openhft/chronicle/algorithms/measures/package-info.java b/measures/src/main/java/net/openhft/chronicle/algorithms/measures/package-info.java new file mode 100644 index 00000000..910c790f --- /dev/null +++ b/measures/src/main/java/net/openhft/chronicle/algorithms/measures/package-info.java @@ -0,0 +1,15 @@ +/** + * Hash function quality measures and related tooling. + * + *

This package contains small utilities and command line tools used to + * evaluate the statistical properties of hash functions, for example + * avalanche behaviour and bit flip bias. It is primarily intended for + * benchmarking and research, not for use on application hot paths. + * + *

The contents of this package are considered internal test support for + * Chronicle Algorithms and may change without notice. Applications should + * depend on the hashing and bytes abstractions in + * {@code net.openhft.chronicle.algo.hashing} and + * {@code net.openhft.chronicle.algo.bytes} instead. + */ +package net.openhft.chronicle.algorithms.measures; diff --git a/pom.xml b/pom.xml index 8bf112d6..d6c61d45 100644 --- a/pom.xml +++ b/pom.xml @@ -31,7 +31,7 @@ net.openhft third-party-bom - 3.27ea5 + 3.27ea7 pom import diff --git a/src/main/docs/architecture-overview.adoc b/src/main/docs/architecture-overview.adoc new file mode 100644 index 00000000..9d10791b --- /dev/null +++ b/src/main/docs/architecture-overview.adoc @@ -0,0 +1,26 @@ += Chronicle-Algorithms Architecture Overview +:toc: +:sectnums: +:lang: en-GB +:source-highlighter: rouge + +== Purpose +Chronicle-Algorithms provides zero-allocation, low-latency primitives for hashing, bit set operations, byte access abstractions, and lightweight lock strategies used across Chronicle libraries. + +== Module Scope +- Public packages: `net.openhft.chronicle.algo`, `.bitset`, `.bytes`, `.hashing`, `.locks` +- Internal packages: `net.openhft.chronicle.algo.internal` (do not use directly) +- Test/analysis utilities: `net.openhft.chronicle.algorithms.measures` (hash quality evaluations) + +== Design Points +- Off-heap friendly APIs: operate on Chronicle Bytes and direct buffers without allocation. +- Stable surface area: keep public interfaces stable within a major version; allow internal evolution. +- Performance focus: cache-friendly flat data structures and branch-light hashing paths. + +== Interactions +- Depends on Chronicle Core/Bytes for low-level buffer access. +- Consumed by higher-level Chronicle components that require hashing, bit set, and lock primitives. + +== Usage Notes +- Treat `internal` packages as implementation details. +- Prefer Chronicle Bytes-backed accessors where off-heap or zero-copy is required. diff --git a/src/main/docs/decision-log.adoc b/src/main/docs/decision-log.adoc new file mode 100644 index 00000000..df36e636 --- /dev/null +++ b/src/main/docs/decision-log.adoc @@ -0,0 +1,222 @@ += Chronicle-Algorithms Decision Log +:toc: +:sectnums: +:lang: en-GB +:source-highlighter: rouge + +Chronicle-Algorithms records architectural and design decisions using two ID streams: + +* `ALGO-DEC-*` for module-level decisions aligned to requirements. +* `ADR-*` for architectural decision records that may cut across multiple features. + +Both sets are captured in this unified decision log. + +[[ALGO-DEC-001]] +== Decision ALGO-DEC-001: Non-Cryptographic Hash Focus +*Status:* Accepted +*Linked requirements:* <>, <>, <> + +=== Context +The module supplies hashes for data structures and indexing, where throughput and distribution matter more than cryptographic strength. + +=== Decision +Provide fast 64-bit non-cryptographic hashes (Murmur3, CityHash, xxHash) as the default set. + +=== Alternatives Considered + +* Cryptographic hashes: rejected due to higher latency and unnecessary security properties for this module's scope. + +=== Consequences + +* High throughput and good distribution for Chronicle data structures. +* Callers must not rely on these hashes for integrity or confidentiality; security-sensitive uses must choose other algorithms. + +[[ALGO-DEC-002]] +== Decision ALGO-DEC-002: Flat Bit Set Representation +*Status:* Accepted +*Linked requirements:* <>, <> + +=== Context +Bit sets back Chronicle structures that need predictable latency and cache-friendly scans. + +=== Decision +Represent bit sets as flat arrays of machine words with single-writer-friendly algorithms. + +=== Alternatives Considered + +* Hierarchical or segmented bit sets: rejected for higher traversal overhead and cache cost in target workloads. + +=== Consequences + +* Excellent sequential performance and memory locality. +* Extremely sparse large spaces may need additional upstream structures to avoid wasted memory. + +[[ALGO-DEC-003]] +== Decision ALGO-DEC-003: Zero-Copy Byte Access Abstractions +*Status:* Accepted +*Linked requirements:* <>, <>, <> + +=== Context +Hashing and related algorithms must read bytes from varied backings (on-heap, direct buffers, Chronicle Bytes) with minimal overhead and safe bounds. + +=== Decision +Provide accessor interfaces that wrap caller-owned storage without copying, while enforcing bounds checks at API edges. + +=== Alternatives Considered + +* Copy inputs into owned buffers: rejected to avoid allocation and duplicate storage. + +=== Consequences + +* Minimal allocation and no implicit copies. +* Callers remain responsible for storage lifecycle and for ensuring buffers stay valid during use. + +[[ADR-001]] +== Decision ADR-001: Abstraction of Memory Access via `Access` Interface +*Status:* Accepted + +=== Context +The library must perform operations (hashing, locking, bit set manipulation) on data that may reside: + +* On the Java heap (byte arrays), +* In direct memory (`ByteBuffer`), +* At raw memory addresses (off-heap). + +Implementing algorithms separately for each data source leads to code duplication and maintenance issues. + +=== Decision +Introduce a generic `Access` interface (extending `ReadAccess` and `WriteAccess`) to abstract memory access. + +=== Details + +* The `Access` interface defines primitive read and write methods (for example, `readLong`, `writeInt`) and atomic operations (for example, `compareAndSwap`). +* Implementations are created for specific sources, such as: + +* `NativeAccess` (Unsafe-backed), +* `ByteBufferAccess`, +* Array-backed accessors. +* Algorithms accept an `Access` instance and a handle `T`, allowing the same logic to run regardless of where the data lives. + +=== Consequences + +* Algorithms are written once and reused for all memory types. +* JIT-compilation can inline accessor calls, giving near zero-overhead abstraction in hot paths. +* Slightly higher complexity in method signatures (passing accessors and handles). + +[[ADR-002]] +== Decision ADR-002: Stateless Hash Function Design +*Status:* Accepted + +=== Context +Standard Java `MessageDigest` and many object `hashCode` implementations: + +* Often require object allocation, +* Maintain internal mutable state, + +which increases GC pressure in high-frequency trading and other latency-sensitive environments. + +=== Decision +Implement `LongHashFunction` as immutable, stateless singletons (or simple data holders for seeds). + +=== Details + +* Methods such as `hashBytes` or `hashMemory` take the input data directly and return a `long`. +* No heap objects are allocated during the hashing process. +* Concrete implementations (City, Murmur, xxHash) are exposed via static factory methods on `LongHashFunction`. + +=== Consequences + +* Zero-allocation hashing suitable for latency-critical paths. +* Thread-safe by design since the functions are stateless and immutable. + +[[ADR-003]] +== Decision ADR-003: Three-Tier Locking Strategy (Read-Write-Update) +*Status:* Accepted + +=== Context +Standard `ReentrantReadWriteLock` does not support an "Update" lock state where: + +* A thread intends to write but can still read, +* Other writers are blocked, +* Other readers may still proceed until the actual write. + +Standard JDK locks also cannot easily be stored in off-heap shared memory for inter-process coordination. + +=== Decision +Implement `ReadWriteUpdateLockingStrategy` interfaces that operate over the `Access` abstraction to support a three-tier lock model: Read, Update, and Write. + +=== Details + +* Locks are represented by state words (integers or longs) in memory. +* The Update lock state is: + +* Mutually exclusive with other Update and Write locks, +* Compatible with concurrent Readers. +* Supports atomic upgrades and downgrades: + +* Read -> Update -> Write, +* Write -> Read (and similar patterns as required). +* Lock state can be stored in shared memory mapped files or off-heap regions via `Access`. + +=== Consequences + +* Enables concurrency patterns not possible with standard JDK locks (for example, optimistic read with reserved write intent). +* Locks can be placed in shared memory for inter-process synchronisation. +* Complexity of reasoning about lock states is higher and must be carefully documented and tested. + +[[ADR-004]] +== Decision ADR-004: Fixed-Size Flat Bit Sets +*Status:* Accepted + +=== Context +`java.util.BitSet` is dynamic and heap-based. Chronicle-Algorithms requires bit sets that: + +* Map onto fixed memory regions (for example, hardware registers, shared memory buffers), +* Offer deterministic memory layout and size. + +This aligns with and elaborates on <>. + +=== Decision +Implement `BitSetFrame` and `ReusableBitSet` as fixed-size, "flat" bit set abstractions. + +=== Details + +* "Flat" means the bit set is a contiguous block of memory without dynamic expansion. +* Implementations are provided for: + +* Single-threaded usage (non-atomic operations), +* Concurrent usage (atomic CAS operations). +* Bit sets can be overlaid onto arbitrary memory regions (for example, network packets, shared memory segments). + +=== Consequences + +* Deterministic memory usage and layout. +* Bit sets can be used directly over hardware-facing or shared memory structures. +* Cannot resize dynamically; capacity is strictly bounded by the initial configuration, so upstream code must size correctly. + +[[ADR-005]] +== Decision ADR-005: Native Byte Order Optimisation +*Status:* Accepted + +=== Context +Hashing algorithms frequently process data in 4- or 8-byte chunks. Converting byte sequences to integers or longs must respect endianness: + +* Java's abstract view is big-endian, +* Common hardware (for example, x86) is little-endian. + +Naive implementations that always normalise to a single byte order can pay unnecessary byte-swapping costs. + +=== Decision +Detect `ByteOrder.nativeOrder()` at runtime and provide specialised implementations per native endianness. + +=== Details + +* Classes such as `CityHash_1_1` and `MurmurHash_3` have internal static subclasses or strategy variants for big-endian and little-endian. +* A small indirection on first use chooses the implementation matching the architecture. +* Subsequent calls are dispatched directly to the chosen variant. + +=== Consequences + +* Maximises performance on the host architecture by avoiding unnecessary byte-swapping. +* Hash results may differ between little-endian and big-endian platforms for the same byte input unless normalisation is explicitly added. +* Cross-platform consistency must be considered explicitly by callers that depend on identical hash values across architectures. diff --git a/src/main/docs/project-requirements.adoc b/src/main/docs/project-requirements.adoc new file mode 100644 index 00000000..b75600ee --- /dev/null +++ b/src/main/docs/project-requirements.adoc @@ -0,0 +1,223 @@ += Project Requirements: Chronicle-Algorithms +:toc: left +:sectnums: +:lang: en-GB +:source-highlighter: rouge +:icons: font + +== 1. Overview + +The **Chronicle-Algorithms** project provides a library of high-performance, zero-allocation algorithms designed for low-latency Java applications. The primary focus is on: + +* efficiency and predictable latency, +* off-heap memory capabilities, +* minimising Garbage Collection (GC) pressure. + +The library encompasses four main functional areas: + +. Hashing +. Bit set operations +. Memory access (Bytes and related abstractions) +. Off-heap locking strategies + +The remainder of this document captures both a concise requirements matrix (with IDs for traceability) and detailed narrative requirements for each area. + +== 2. Functional Requirements + +=== 2.1 Summary Matrix + +[%autowidth,cols="1,3,2"] +|=== +| ID | Requirement | Verification + +| [[ALGO-FN-001]]ALGO-FN-001 +| Provide high-throughput non-cryptographic hash functions (Murmur3, CityHash, xxHash) for Chronicle data structures. +| Unit tests, property tests for avalanche and distribution, JMH baselines. + +| [[ALGO-FN-002]]ALGO-FN-002 +| Offer flat, cache-friendly bit set implementations suitable for dense and sparse cases. +| Boundary and unit tests for indices and density extremes; property tests for set and scan operations. + +| [[ALGO-FN-003]]ALGO-FN-003 +| Expose byte access abstractions that unify on-heap arrays, direct buffers, and Chronicle Bytes inputs without copies. +| Compatibility tests across backings; fuzz tests for bounds and offset handling. + +| [[ALGO-FN-004]]ALGO-FN-004 +| Supply lightweight lock models tailored to Chronicle data structures without full `java.util.concurrent` overhead. +| Concurrency unit tests for state transitions and contention; microbenchmarks for hot paths. +|=== + +The following sub-sections elaborate these requirements. + +=== 2.2 Hashing (details for <>) + +The system must provide efficient, non-cryptographic hash functions capable of processing various inputs and producing 64-bit hash values. + +*Algorithms* + +* Must implement **CityHash 1.1**. +* Must implement **MurmurHash3**. +* Must implement **xxHash r39**. + +*Input support* + +* Must support hashing of Java primitives: `long`, `int`, `short`, `char`, `byte`, `boolean`. +* Must support hashing of: +** byte arrays (`byte[]`), +** `ByteBuffer`, +** `String`, +** `StringBuilder`. +* Must support hashing of raw memory addresses (off-heap memory). + +*Configuration and semantics* + +* Must allow hashing with and without seed values. +* Must handle endianness (little-endian versus big-endian) correctly, optimising for native byte order where possible (see performance requirement <>). +* Hash functions are non-cryptographic and must not be positioned or documented as suitable for integrity or confidentiality guarantees. + +=== 2.3 Bit Set Operations (details for <>) + +The system must provide bit set implementations that operate efficiently on contiguous memory regions, including off-heap memory, and are suitable for dense and sparse cases. + +*Core operations* + +* Support standard bit manipulations: `set`, `clear`, `flip`, `get`. +* Support range operations: `setRange`, `clearRange`, `flipRange`. +* Support search operations: `nextSetBit`, `nextClearBit`, `previousSetBit`, `previousClearBit`. +* Support continuous block operations: finding and setting or clearing `N` continuous bits. + +*Concurrency* + +* Must provide a single-threaded implementation (for example, `SingleThreadedFlatBitSetFrame`) for maximum raw performance. +* Must provide a thread-safe, concurrent implementation (for example, `ConcurrentFlatBitSetFrame`) using atomic operations (CAS). + +*Storage model* + +* Must abstract storage so that bit sets can reside: +** on-heap (arrays, `ByteBuffer`), and +** off-heap (direct `ByteBuffer`, raw pointers). +* Implementations must be flat and cache-friendly (contiguous machine words) to support predictable scans and low tail latency. + +=== 2.4 Memory Access (Bytes) (details for <>) + +The system must provide a unified abstraction layer for accessing memory to decouple algorithms from the underlying storage mechanism. + +*Access API* + +* Define generic `ReadAccess` and `WriteAccess` interfaces. +* Provide concrete implementations for: +** `NativeAccess` (using `Unsafe` for raw memory and arrays). +** `ByteBufferAccess` (for `java.nio.ByteBuffer`). +** `BytesStore`-backed access (integration with Chronicle-Bytes). +** `RandomDataInput` and `RandomDataOutput`. +* Support reading and writing of all Java primitive types and unsigned variants at arbitrary offsets. + +*Concurrency primitives* + +* Support atomic compare-and-swap (CAS) operations for fields used by locks and other concurrency primitives. +* Respect the off-heap safety constraints in <> by providing bounds enforcement where appropriate. + +=== 2.5 Locking Strategies (details for <>) + +The system must provide locking mechanisms designed for shared memory and inter-process communication (IPC) scenarios and tuned for Chronicle data structures. + +*Lock types* + +* *Read-write locks*: allow multiple readers or one writer. +* *Read-write-update locks*: introduce an "Update" state allowing atomic upgrade from Read to Write while still permitting concurrent readers until commit. + +*Features* + +* Locks must be implementable over the generic `Access` interface, enabling off-heap or shared-memory lock placement. +* Must support "wait" strategies (for example, spin, yield, back-off) to handle contention without forcing specific policy into the algorithm layer. +* Must provide `tryLock` capabilities for non-blocking attempts. +* Must support lock state upgrades and downgrades: +** Read -> Update -> Write, +** Write -> Read (and other safe transitions as defined in the locking strategy). + +== 3. Non-Functional Requirements + +=== 3.1 Summary Matrix + +[%autowidth,cols="1,3,2"] +|=== +| ID | Requirement | Verification + +| [[ALGO-NF-P-001]]ALGO-NF-P-001 +| Performance: minimise allocation; hot-path methods avoid copying and favour predictable branches. +| JMH regression suite; allocation profiling on representative payloads. + +| [[ALGO-NF-S-001]]ALGO-NF-S-001 +| Off-heap safety: enforce bounds checks for any direct or Bytes-backed accessors and reject overflow sizes. +| Negative and bounds tests; fuzz inputs near overflow; SpotBugs and Checkstyle for unsafe patterns. + +| [[ALGO-NF-O-001]]ALGO-NF-O-001 +| Compatibility: maintain API stability within a major version; document any breaking changes. +| API compatibility review per release; deprecation notices; release notes. + +| [[ALGO-NF-O-002]]ALGO-NF-O-002 +| Observability: primitives remain deterministic with no hidden threads or background work; signal misuse explicitly. +| Unit tests asserting deterministic results and explicit exceptions; static analysis for thread creation or logging in hot paths. +|=== + +=== 3.2 Performance (details for <>) + +* Algorithms must generate zero garbage (zero allocation) during steady-state operation. +* Hash functions must be optimised for native byte order execution and must avoid unnecessary byte swapping. +* Bit set and locking operations must minimise branches and favour predictable branching where possible. +* Performance characteristics must be validated with: +** JMH regression suites over representative payload sizes and distributions. +** Allocation profiling to confirm zero or near-zero allocation in hot paths. + +=== 3.3 Safety and Off-Heap Access (details for <>) + +* Any direct or off-heap accessors must enforce bounds checks at API edges and reject overflow sizes. +* Unsafe or `Unsafe`-based implementations may assume valid inputs in some internal methods for speed, but public APIs must provide mechanisms for validation. +* Safety guarantees must be backed by: +** Negative tests and bounds tests that probe underflow and overflow scenarios. +** Fuzz tests that exercise offsets and lengths near boundaries. +** Static analysis (SpotBugs, Checkstyle) to detect unsafe usage patterns. + +=== 3.4 Compatibility (details for <>) + +* The library must be modular, with a clear separation between algorithm logic and memory access logic. +* Must support Java 8 and newer (for example, usage of `java.util.function` and diamond operators). +* Within a major version: +** Public APIs should remain stable. +** Any breaking change must be explicitly documented with: +*** Deprecation periods where feasible. +*** Clear notes in release documentation. +*** Migration hints for downstream users. + +=== 3.5 Observability and Determinism (details for <>) + +* Algorithms and primitives must be deterministic: +** No hidden background threads. +** No implicit scheduling or asynchronous tasks started from hot paths. +* Hot paths must avoid logging; any logging present must be clearly outside latency-critical sections. +* Misuse must be surfaced through explicit exceptions (for example, bounds violations) rather than silent coercion or truncation. +* Metrics or telemetry concerns are delegated to upstream Chronicle components; APIs should, however, be straightforward to wrap with metrics or tracing. + +== 4. Testing and Validation Expectations + +These expectations apply across all functional and non-functional requirements. + +* Keep Checkstyle and SpotBugs clean; justify any suppressions inline and tie them to specific requirements where relevant. +* Prefer deterministic unit and property tests for: +** Boundary indices (start, end, and out-of-range). +** Empty inputs and minimal sizes. +** Dense and sparse bit set cases. +** Hashing avalanche and distribution characteristics. +* Maintain performance baselines for representative workloads when changing algorithms; capture any material regression and document trade-offs. +* Log seeds on property test failures to aid exact reproduction of issues. + +== 5. Observability Expectations (expanded guidance for <>) + +* No background services or implicit threads may be created by this library without explicit opt-in API calls. +* Behaviour must remain deterministic across runs for the same inputs, excluding documented sources of non-determinism (for example, native CPU features). +* Signal misuse via: +** Clear, specific exception types and messages. +** Avoiding silent data truncation, wrap-around, or out-of-range coercion unless explicitly documented. +* Leave metrics and telemetry emission to upstream components, but: +** Keep APIs simple to decorate with metrics, tracing, or logging. +** Avoid patterns that make wrapping difficult (for example, extensive use of statics with hidden state). diff --git a/src/main/docs/security-review.adoc b/src/main/docs/security-review.adoc new file mode 100644 index 00000000..4d542af0 --- /dev/null +++ b/src/main/docs/security-review.adoc @@ -0,0 +1,23 @@ += Chronicle-Algorithms Security Review (Initial) +:toc: +:sectnums: +:lang: en-GB +:source-highlighter: rouge + +== Scope +Hashing, bit set, byte access, and lock primitives; includes off-heap friendly code paths. + +== Threat Considerations +- Bounds safety: validate indices and lengths for on/off-heap accesses to avoid memory corruption. +- Input handling: hashing APIs accept untrusted data; ensure size checks and avoid integer overflows. +- Concurrency: lock and bit set operations must not expose torn state or races when used as documented. +- Cryptography: only non-cryptographic hashes are included; do not use for confidentiality or integrity. + +== Current Posture +- No network or IO entry points in this module. +- No embedded secrets or key material. +- Static analysis (Checkstyle/SpotBugs) reports clean; rerun in CI on changes. + +== Follow-Ups +- Document any additional fuzz/security testing for hashing and bounds checks. +- Record any deviations or suppressions alongside rationale in future reviews. diff --git a/src/main/docs/testing-strategy.adoc b/src/main/docs/testing-strategy.adoc new file mode 100644 index 00000000..39489bcb --- /dev/null +++ b/src/main/docs/testing-strategy.adoc @@ -0,0 +1,30 @@ += Chronicle-Algorithms Testing Strategy +:toc: +:sectnums: +:lang: en-GB +:source-highlighter: rouge + +== Scope +Testing guidance for hashing, bit set, byte access, and lock primitives in Chronicle-Algorithms. + +== Unit and Property Testing +- Hashing: verify avalanche/distribution properties with randomised inputs and seeded property tests. +- Bit sets: cover empty, dense, and sparse cases; test boundary indices and concurrency assumptions where applicable. +- Bytes accessors: validate bounds checks, slice/offset handling, and behaviour with on-heap vs direct vs Chronicle Bytes backings. +- Locks: assert state transitions and contention paths without relying on `java.util.concurrent` locks. + +== Fuzz and Negative Testing +- Feed random and malformed inputs through hashing and bounds-sensitive paths to catch overflows and index errors. +- Include adversarial cases (large lengths, near-overflow sizes) for off-heap friendly accessors. + +== Performance Regression +- Maintain microbenchmarks (e.g., JMH) for hot paths: hash computation on typical payload sizes, bit set set/get/scan operations. +- Track baseline metrics; flag regressions when latency/throughput deviates beyond agreed thresholds. + +== Static Analysis and Checks +- Keep Checkstyle and SpotBugs clean; document any suppression rationale inline. +- Prefer deterministic tests with fixed seeds; log seeds on failure when randomness is involved. + +== Observability Expectations +- No hidden threads or background tasks in tests; keep measurements isolated. +- Fail fast on misuse (bounds violations) rather than silently truncating or wrapping inputs. diff --git a/src/main/java/net/openhft/chronicle/algo/MemoryUnit.java b/src/main/java/net/openhft/chronicle/algo/MemoryUnit.java index aa3ba4d9..717f91a2 100644 --- a/src/main/java/net/openhft/chronicle/algo/MemoryUnit.java +++ b/src/main/java/net/openhft/chronicle/algo/MemoryUnit.java @@ -1,7 +1,6 @@ /* * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 */ - /* * Based on java.util.concurrent.TimeUnit, which is * Written by Doug Lea with assistance from members of JCP JSR-166 @@ -13,20 +12,11 @@ import java.util.concurrent.TimeUnit; /** - * A {@code MemoryUnit} represents memory amounts at a given unit of - * granularity and provides utility methods to convert across units. A - * {@code MemoryUnit} does not maintain memory information, but only - * helps organize and use memory amounts representations that may be maintained - * separately across various contexts. - * - *

Note than in this class kilo-, mega- and giga- prefixes means 2^10 = 1024 multiplexing, - * that is more common in low-level programming, CPU and operation system contexts, - * not 1000 as defined by International System of Units (SI). - * - *

A {@code MemoryUnit} is mainly used to inform memory amount-based methods - * how a given memory amount parameter should be interpreted. - * - *

API of {@code MemoryUnit} is copied from {@link TimeUnit} enum. + * Memory unit conversion enum modelled after {@link TimeUnit}. + *

+ * Encapsulates the conversions between bits, bytes, longs, cache lines and larger units using + * binary prefixes (Ki/Mi/Gi). Alignment helpers round values up to the nearest boundary for the + * target unit. */ public enum MemoryUnit { @@ -805,7 +795,7 @@ static long y(long amount, long align) { static long ise(MemoryUnit unitToAlign, MemoryUnit alignmentUnit) { throw new IllegalStateException("Couldn't align " + unitToAlign + " by " + alignmentUnit); } -// To maintain full signature compatibility with 1.5, and to improve the + // To maintain full signature compatibility with 1.5, and to improve the // clarity of the generated javadoc (see 6287639: Abstract methods in // enum classes should not be listed as abstract), method convert // etc. are not declared abstract but otherwise act as abstract methods. diff --git a/src/main/java/net/openhft/chronicle/algo/bitset/BitSetAlgorithm.java b/src/main/java/net/openhft/chronicle/algo/bitset/BitSetAlgorithm.java index 58253e58..55dc9142 100644 --- a/src/main/java/net/openhft/chronicle/algo/bitset/BitSetAlgorithm.java +++ b/src/main/java/net/openhft/chronicle/algo/bitset/BitSetAlgorithm.java @@ -4,10 +4,10 @@ package net.openhft.chronicle.algo.bitset; /** - * The {@code BitSetAlgorithm} interface defines the contract for algorithms - * that handle operations related to bit sets. Implementations of this interface - * provide methods to calculate the size in bytes required for a given logical size in bits - * and to determine the maximum logical size that fits within the same size in bytes. + * Strategy interface describing how logical bitset sizes map to physical storage requirements. + *

+ * Algorithms can account for padding or metadata and can also report the largest logical size that + * still fits into a previously allocated storage block. */ public interface BitSetAlgorithm { diff --git a/src/main/java/net/openhft/chronicle/algo/bitset/BitSetFrame.java b/src/main/java/net/openhft/chronicle/algo/bitset/BitSetFrame.java index 6b0d347b..01d59def 100644 --- a/src/main/java/net/openhft/chronicle/algo/bitset/BitSetFrame.java +++ b/src/main/java/net/openhft/chronicle/algo/bitset/BitSetFrame.java @@ -6,9 +6,12 @@ import net.openhft.chronicle.algo.bytes.Access; /** - * The {@code BitSetFrame} interface defines a set of operations for manipulating bits within a bit set. - * It provides methods to set, clear, flip, and check the state of bits at specified indices. - * The operations are parameterized with an {@code Access} object, a handle, and an offset for flexibility. + * Low-level API for working with a bit set stored in an arbitrary memory container. + *

+ * Implementations encapsulate the bit layout and arithmetic, while callers supply an + * {@link Access} strategy, an opaque handle to the underlying storage and an offset into it. This + * separation allows the same bitset logic to be reused across on-heap arrays, {@link + * net.openhft.chronicle.bytes.BytesStore BytesStore} or raw native memory. */ public interface BitSetFrame { /** diff --git a/src/main/java/net/openhft/chronicle/algo/bitset/ConcurrentFlatBitSetFrame.java b/src/main/java/net/openhft/chronicle/algo/bitset/ConcurrentFlatBitSetFrame.java index dd032797..87cc824f 100644 --- a/src/main/java/net/openhft/chronicle/algo/bitset/ConcurrentFlatBitSetFrame.java +++ b/src/main/java/net/openhft/chronicle/algo/bitset/ConcurrentFlatBitSetFrame.java @@ -13,8 +13,11 @@ import static net.openhft.chronicle.algo.bitset.SingleThreadedFlatBitSetFrame.*; /** - * DirectBitSet with input validations and thread-safe memory access. - * This class provides a concurrent implementation of a BitSet frame. + * Direct bit set frame that mirrors {@link SingleThreadedFlatBitSetFrame} operations but performs + * all mutations with CAS, making it safe to share across threads. + *

+ * Bounds checks mirror the single threaded implementation, while read/modify/write loops use + * volatile reads and compare-and-swap to protect against concurrent updates. */ public final class ConcurrentFlatBitSetFrame implements BitSetFrame { private final long longLength; diff --git a/src/main/java/net/openhft/chronicle/algo/bitset/FlatBitSetAlgorithm.java b/src/main/java/net/openhft/chronicle/algo/bitset/FlatBitSetAlgorithm.java index 79f67837..75c12f12 100644 --- a/src/main/java/net/openhft/chronicle/algo/bitset/FlatBitSetAlgorithm.java +++ b/src/main/java/net/openhft/chronicle/algo/bitset/FlatBitSetAlgorithm.java @@ -6,9 +6,9 @@ import static net.openhft.chronicle.algo.MemoryUnit.BITS; /** - * The {@code FlatBitSetAlgorithm} enum implements the {@link BitSetAlgorithm} interface - * providing concrete implementations for the methods defined in the interface. - * This enum represents a singleton instance of the algorithm used for BitSet operations. + * Basic {@link BitSetAlgorithm} backed by a flat array of 64-bit words. Byte sizing is a straight + * bits-to-bytes conversion, and the maximum logical size that fits the same byte length is the + * logical size itself because no headers or metadata are stored. */ enum FlatBitSetAlgorithm implements BitSetAlgorithm { INSTANCE; diff --git a/src/main/java/net/openhft/chronicle/algo/bitset/ReusableBitSet.java b/src/main/java/net/openhft/chronicle/algo/bitset/ReusableBitSet.java index 4ae834a4..ced02dfc 100644 --- a/src/main/java/net/openhft/chronicle/algo/bitset/ReusableBitSet.java +++ b/src/main/java/net/openhft/chronicle/algo/bitset/ReusableBitSet.java @@ -30,7 +30,7 @@ public ReusableBitSet( } /** - * Reuses the current ReusableBitSet with the specified frame, access, handle, and offset. + * Point this instance at a new backing store without allocating a fresh wrapper. * * @param frame the bit set frame to use * @param access the access interface for reading/writing bits @@ -206,7 +206,7 @@ public Bits setBits() { * for iterating over set bits in the bit set. */ protected class Bits implements BitSet.Bits { - protected BitSetFrame.Bits frameBits; + protected final BitSetFrame.Bits frameBits; /** * Constructs a new Bits instance with the specified frame bits. diff --git a/src/main/java/net/openhft/chronicle/algo/bitset/SingleThreadedFlatBitSetFrame.java b/src/main/java/net/openhft/chronicle/algo/bitset/SingleThreadedFlatBitSetFrame.java index 1bfb7dc8..411cd071 100644 --- a/src/main/java/net/openhft/chronicle/algo/bitset/SingleThreadedFlatBitSetFrame.java +++ b/src/main/java/net/openhft/chronicle/algo/bitset/SingleThreadedFlatBitSetFrame.java @@ -11,9 +11,10 @@ import static net.openhft.chronicle.algo.MemoryUnit.LONGS; /** - * This is the SingleThreadedFlatBitSetFrame class implementing BitSetFrame. - * It provides methods for bit manipulation with input validations. - * This class is not thread-safe. + * Flat bit set frame that performs unchecked memory access via {@link Access} for a single thread. + *

+ * All bounds validation is performed up front, but operations themselves assume exclusive access to + * the underlying storage and therefore avoid CAS or volatile reads for speed. */ public final class SingleThreadedFlatBitSetFrame implements BitSetFrame { @@ -54,8 +55,8 @@ static long higherBitsIncludingThis(long bitIndex) { static long lowerBitsIncludingThis(long bitIndex) { return ALL_ONES >>> ~bitIndex; } -// conversions + // conversions static long higherBitsExcludingThis(long bitIndex) { return ~(ALL_ONES >>> ~bitIndex); } @@ -84,8 +85,8 @@ static void checkNumberOfBits(int numberOfBits) { if (numberOfBits <= 0 || numberOfBits > 64) throw new IllegalArgumentException("Illegal number of bits: " + numberOfBits); } -// checks + // checks static boolean checkNotFoundIndex(long fromIndex) { if (fromIndex < 0) { if (fromIndex == NOT_FOUND) @@ -1451,7 +1452,7 @@ public long next(Access access, T handle, long offset) { currentWord = (l >>> trailingZeros) >>> 1; return bitIndex += trailingZeros + 1; } - for (long i = byteIndex, lim = byteLength; (i += 8) < lim; ) { + for (long i = byteIndex; (i += 8) < byteLength; ) { if ((l = access.readLong(handle, i)) != 0) { byteIndex = i; int trailingZeros = numberOfTrailingZeros(l); diff --git a/src/main/java/net/openhft/chronicle/algo/bitset/package-info.java b/src/main/java/net/openhft/chronicle/algo/bitset/package-info.java new file mode 100644 index 00000000..79029183 --- /dev/null +++ b/src/main/java/net/openhft/chronicle/algo/bitset/package-info.java @@ -0,0 +1,14 @@ +/** + * High performance bit set implementations and algorithms. + * + *

Classes in this package provide single threaded and concurrent bit set + * abstractions backed by flat arrays of machine words. They are designed for + * low latency, cache friendly operations in Chronicle components that work + * with large sparse sets of indices or flags. + * + *

This package is part of the public Chronicle Algorithms API. The overall + * bit set model and key operations are intended to remain stable, although + * concrete implementations and internal layout details may change between + * releases. + */ +package net.openhft.chronicle.algo.bitset; diff --git a/src/main/java/net/openhft/chronicle/algo/bytes/Access.java b/src/main/java/net/openhft/chronicle/algo/bytes/Access.java index 62836a50..cde1d392 100644 --- a/src/main/java/net/openhft/chronicle/algo/bytes/Access.java +++ b/src/main/java/net/openhft/chronicle/algo/bytes/Access.java @@ -9,9 +9,11 @@ import java.nio.ByteBuffer; /** - * The Access interface combines read and write access capabilities for a given type {@code T}. - * It provides various utility methods for native access, byte buffer access, and bytes store access, - * as well as methods for copying and checking equivalence between different access types. + * Combines {@link ReadAccess} and {@link WriteAccess} for a given handle type. + *

+ * Provides factory methods for common access strategies (native memory, {@link ByteBuffer}, + * {@link net.openhft.chronicle.bytes.BytesStore}) and utility helpers for copying or comparing + * regions using arbitrary access implementations. * * @param the type of the object to be accessed */ @@ -58,17 +60,8 @@ static ReadAccess checkedRandomDataInputAccess() { } /** - * Copies data from the source to the target using the provided access interfaces. - * - * @param sourceAccess the source access interface - * @param source the source handle - * @param sourceOffset the source offset - * @param targetAccess the target access interface - * @param target the target handle - * @param targetOffset the target offset - * @param len the length of data to copy - * @param the source type - * @param the target type + * Copy bytes between two addressable regions using their respective access strategies. + * Performs minimal work by moving data in 8/4/2/1 byte chunks. */ static void copy(final ReadAccess sourceAccess, final S source, @@ -99,18 +92,9 @@ static void copy(final ReadAccess sourceAccess, } /** - * Checks if the data in two different access types are equivalent. + * Compare bytes between two regions, using the provided {@link ReadAccess} strategies. * - * @param access1 the first access interface - * @param handle1 the first handle - * @param offset1 the first offset - * @param access2 the second access interface - * @param handle2 the second handle - * @param offset2 the second offset - * @param len the length of data to compare - * @param the type of the first handle - * @param the type of the second handle - * @return true if the data is equivalent, false otherwise + * @return true if all bytes in the range match */ static boolean equivalent(final ReadAccess access1, final T handle1, diff --git a/src/main/java/net/openhft/chronicle/algo/bytes/AccessCommon.java b/src/main/java/net/openhft/chronicle/algo/bytes/AccessCommon.java index 9260b9e6..acee8a08 100644 --- a/src/main/java/net/openhft/chronicle/algo/bytes/AccessCommon.java +++ b/src/main/java/net/openhft/chronicle/algo/bytes/AccessCommon.java @@ -6,7 +6,7 @@ import java.nio.ByteOrder; /** - * A functional interface that defines a common access method for determining the byte order of a given handle. + * Common contract for determining the byte order of a readable/writable handle. * * @param the type of the handle */ diff --git a/src/main/java/net/openhft/chronicle/algo/bytes/ArrayAccessors.java b/src/main/java/net/openhft/chronicle/algo/bytes/ArrayAccessors.java index 854bfc94..e5228530 100644 --- a/src/main/java/net/openhft/chronicle/algo/bytes/ArrayAccessors.java +++ b/src/main/java/net/openhft/chronicle/algo/bytes/ArrayAccessors.java @@ -6,9 +6,10 @@ import static net.openhft.chronicle.core.UnsafeMemory.MEMORY; /** - * Utility class for providing array accessors for various primitive array types. - * This class includes enums that implement {@link Accessor.Full} for different primitive types, - * facilitating access to elements of arrays. + * Unsafe-backed {@link Accessor} implementations for primitive arrays. + *

+ * Each nested enum captures the base offset for its array type and reuses {@link NativeAccess} + * to provide fast indexed access without intermediate bounds checks. */ final class ArrayAccessors { @@ -40,7 +41,7 @@ private ArrayAccessors() { } /** - * Enum providing full Accessor implementation for boolean arrays. + * Accessor for {@code boolean[]} using native memory offsets. */ enum Boolean implements Accessor.Full { INSTANCE; @@ -80,7 +81,7 @@ public long offset(boolean[] source, long index) { } /** - * Enum providing full Accessor implementation for byte arrays. + * Accessor for {@code byte[]} using native memory offsets. */ enum Byte implements Accessor.Full { INSTANCE; @@ -120,7 +121,7 @@ public long offset(byte[] source, long index) { } /** - * Enum providing full Accessor implementation for char arrays. + * Accessor for {@code char[]} using native memory offsets. */ enum Char implements Accessor.Full { INSTANCE; @@ -171,7 +172,7 @@ public long size(long size) { } /** - * Enum providing full Accessor implementation for short arrays. + * Accessor for {@code short[]} using native memory offsets. */ enum Short implements Accessor.Full { INSTANCE; diff --git a/src/main/java/net/openhft/chronicle/algo/bytes/ByteBufferAccess.java b/src/main/java/net/openhft/chronicle/algo/bytes/ByteBufferAccess.java index a962af82..f4aee83b 100644 --- a/src/main/java/net/openhft/chronicle/algo/bytes/ByteBufferAccess.java +++ b/src/main/java/net/openhft/chronicle/algo/bytes/ByteBufferAccess.java @@ -7,8 +7,9 @@ import java.nio.ByteOrder; /** - * Provides an implementation of the {@link Access} interface for {@link ByteBuffer} instances. - * This class provides methods to read and write various data types to and from a {@link ByteBuffer}. + * {@link Access} implementation that reads and writes directly against a {@link ByteBuffer}. + *

+ * Offsets are treated as absolute positions; callers should configure buffer order as required. */ final class ByteBufferAccess implements Access { diff --git a/src/main/java/net/openhft/chronicle/algo/bytes/BytesAccessors.java b/src/main/java/net/openhft/chronicle/algo/bytes/BytesAccessors.java index dbd13605..7da4a89a 100644 --- a/src/main/java/net/openhft/chronicle/algo/bytes/BytesAccessors.java +++ b/src/main/java/net/openhft/chronicle/algo/bytes/BytesAccessors.java @@ -6,7 +6,7 @@ import net.openhft.chronicle.bytes.BytesStore; /** - * Utility class for providing accessor implementations for {@link BytesStore}. + * Accessor helpers for bridging {@link BytesStore} into the Chronicle algorithms access model. */ final class BytesAccessors { @@ -15,7 +15,7 @@ private BytesAccessors() { } /** - * Generic accessor implementation for {@link BytesStore}. + * Generic accessor implementation for {@link BytesStore} instances. * * @param the type of BytesStore */ @@ -25,8 +25,6 @@ static class Generic> implements Accessor.Full /** * Returns the access implementation for the BytesStore. - * - * @return the access implementation for the BytesStore */ @SuppressWarnings("unchecked") @Override @@ -47,10 +45,6 @@ public S handle(S source) { /** * Converts the index in the source domain to an access offset. - * - * @param source the source BytesStore - * @param index the index in the source type domain - * @return the offset for access corresponding to the given index */ @Override public long offset(S source, long index) { diff --git a/src/main/java/net/openhft/chronicle/algo/bytes/HotSpotStringAccessor.java b/src/main/java/net/openhft/chronicle/algo/bytes/HotSpotStringAccessor.java index 67147e5b..579dfeab 100644 --- a/src/main/java/net/openhft/chronicle/algo/bytes/HotSpotStringAccessor.java +++ b/src/main/java/net/openhft/chronicle/algo/bytes/HotSpotStringAccessor.java @@ -57,7 +57,7 @@ public ReadAccess access() { @SuppressWarnings("unchecked") @Override public T handle(String source) { - return (T) MEMORY.getObject(source, valueOffset); + return MEMORY.getObject(source, valueOffset); } /** diff --git a/src/main/java/net/openhft/chronicle/algo/bytes/RandomDataInputAccess.java b/src/main/java/net/openhft/chronicle/algo/bytes/RandomDataInputAccess.java index ad075345..604089a6 100644 --- a/src/main/java/net/openhft/chronicle/algo/bytes/RandomDataInputAccess.java +++ b/src/main/java/net/openhft/chronicle/algo/bytes/RandomDataInputAccess.java @@ -8,8 +8,8 @@ import java.nio.ByteOrder; /** - * Provides a default implementation for reading various primitive types and - * volatile values from a {@link RandomDataInput} handle at a specified offset. + * {@link ReadAccess} adapter for {@link RandomDataInput} so Chronicle algorithms can treat data + * sources uniformly. * * @param the type of the object being accessed, extending {@link RandomDataInput} */ diff --git a/src/main/java/net/openhft/chronicle/algo/bytes/RandomDataOutputAccess.java b/src/main/java/net/openhft/chronicle/algo/bytes/RandomDataOutputAccess.java index 3446277b..580693f9 100644 --- a/src/main/java/net/openhft/chronicle/algo/bytes/RandomDataOutputAccess.java +++ b/src/main/java/net/openhft/chronicle/algo/bytes/RandomDataOutputAccess.java @@ -8,8 +8,10 @@ import java.nio.ByteOrder; /** - * Provides a default implementation for writing various primitive types - * and volatile values to a {@link RandomDataOutput} handle at a specified offset. + * Default {@link WriteAccess} adapter for {@link RandomDataOutput} implementations. + *

+ * Bridges Chronicle Bytes write operations to the {@link WriteAccess} contract so the same bitset + * and hashing utilities can operate over {@link RandomDataOutput} without bespoke code. * * @param the type of the object being accessed, extending {@link RandomDataOutput} */ diff --git a/src/main/java/net/openhft/chronicle/algo/bytes/ZeroAccess.java b/src/main/java/net/openhft/chronicle/algo/bytes/ZeroAccess.java index 778f59ee..26410643 100644 --- a/src/main/java/net/openhft/chronicle/algo/bytes/ZeroAccess.java +++ b/src/main/java/net/openhft/chronicle/algo/bytes/ZeroAccess.java @@ -6,8 +6,10 @@ import java.nio.ByteOrder; /** - * A {@link ReadAccess} implementation that always returns zero or false for read operations. - * This is a singleton implementation, accessed via the {@code INSTANCE} enum constant. + * A {@link ReadAccess} implementation that always returns zero-equivalent values. + *

+ * Useful in tests or as a safe default when a handle is absent but callers still expect a fully + * defined {@link ReadAccess} contract. */ enum ZeroAccess implements ReadAccess { INSTANCE; diff --git a/src/main/java/net/openhft/chronicle/algo/bytes/package-info.java b/src/main/java/net/openhft/chronicle/algo/bytes/package-info.java new file mode 100644 index 00000000..29d930d5 --- /dev/null +++ b/src/main/java/net/openhft/chronicle/algo/bytes/package-info.java @@ -0,0 +1,14 @@ +/** + * Abstractions for zero copy access to bytes like data structures. + * + *

The types in this package model readable and writable views over a range + * of backing stores, including on heap arrays, direct {@code ByteBuffer} + * instances, and Chronicle Bytes. They provide a common interface for hash + * functions and other algorithms that need uniform, low overhead access to + * raw bytes. + * + *

Callers are expected to respect the documented bounds and lifetime of + * the underlying storage. Implementations are tuned for minimal allocation + * and are suitable for use in hot paths across Chronicle libraries. + */ +package net.openhft.chronicle.algo.bytes; diff --git a/src/main/java/net/openhft/chronicle/algo/hashing/CityHash_1_1.java b/src/main/java/net/openhft/chronicle/algo/hashing/CityHash_1_1.java index a0e5976b..41e7fa05 100644 --- a/src/main/java/net/openhft/chronicle/algo/hashing/CityHash_1_1.java +++ b/src/main/java/net/openhft/chronicle/algo/hashing/CityHash_1_1.java @@ -11,18 +11,17 @@ import static net.openhft.chronicle.algo.hashing.LongHashFunction.NATIVE_LITTLE_ENDIAN; /** - * Adapted from the C++ CityHash implementation from Google at - * http://code.google.com/p/cityhash/source/browse/trunk/src/city.cc. + * Endian-independent CityHash64 v1.1 implementation adapted from Google's reference. + *

+ * Exposes hash functions via {@link LongHashFunction} and consumes data through {@link ReadAccess} + * so any addressable source can be hashed without copying. On big-endian platforms values are + * byte-swapped to maintain consistent output. */ class CityHash_1_1 { // Singleton instance of CityHash_1_1 private static final CityHash_1_1 INSTANCE = new CityHash_1_1(); - // Singleton instance with native byte order - private static final CityHash_1_1 NATIVE_CITY = NATIVE_LITTLE_ENDIAN ? - CityHash_1_1.INSTANCE : BigEndian.INSTANCE; - // Constants used in the hashing algorithm private static final long K0 = 0xc3a5c85c97cb3127L; private static final long K1 = 0xb492b66fbe98f273L; @@ -33,22 +32,19 @@ class CityHash_1_1 { private CityHash_1_1() { } + private static CityHash_1_1 nativeCity() { + return NATIVE_LITTLE_ENDIAN ? INSTANCE : BigEndian.INSTANCE; + } + /** - * Applies a bitwise shift and mix operation to the given value. - * - * @param val the value to be shifted and mixed - * @return the result of the shift and mix operation + * Applies the CityHash shift/mix primitive. */ private static long shiftMix(long val) { return val ^ (val >>> 47); } /** - * Hashes two long values using a default multiplier. - * - * @param u the first value - * @param v the second value - * @return the hashed result + * Hashes two long values using the default multiplier. */ private static long hashLen16(long u, long v) { return hashLen16(u, v, K_MUL); @@ -56,11 +52,6 @@ private static long hashLen16(long u, long v) { /** * Hashes two long values using the specified multiplier. - * - * @param u the first value - * @param v the second value - * @param mul the multiplier - * @return the hashed result */ private static long hashLen16(long u, long v, long mul) { long a = shiftMix((u ^ v) * mul); @@ -68,23 +59,14 @@ private static long hashLen16(long u, long v, long mul) { } /** - * Computes the multiplier based on the length. - * - * @param len the length - * @return the multiplier + * Compute the mixing multiplier based on input length. */ private static long mul(long len) { return K2 + (len << 1); } /** - * Hashes a length of 1 to 3 bytes. - * - * @param len the length - * @param firstByte the first byte - * @param midOrLastByte the middle or last byte - * @param lastByte the last byte - * @return the hashed result + * Hash for inputs of 1-3 bytes. */ private static long hash1To3Bytes(int len, int firstByte, int midOrLastByte, int lastByte) { int y = firstByte + (midOrLastByte << 8); @@ -93,12 +75,7 @@ private static long hash1To3Bytes(int len, int firstByte, int midOrLastByte, int } /** - * Hashes a length of 4 to 7 bytes. - * - * @param len the length - * @param first4Bytes the first 4 bytes - * @param last4Bytes the last 4 bytes - * @return the hashed result + * Hash for inputs of 4-7 bytes. */ private static long hash4To7Bytes(long len, long first4Bytes, long last4Bytes) { long mul = mul(len); @@ -106,12 +83,7 @@ private static long hash4To7Bytes(long len, long first4Bytes, long last4Bytes) { } /** - * Hashes a length of 8 to 16 bytes. - * - * @param len the length - * @param first8Bytes the first 8 bytes - * @param last8Bytes the last 8 bytes - * @return the hashed result + * Hash for inputs of 8-16 bytes. */ private static long hash8To16Bytes(long len, long first8Bytes, long last8Bytes) { long mul = mul(len); @@ -122,30 +94,21 @@ private static long hash8To16Bytes(long len, long first8Bytes, long last8Bytes) } /** - * Provides an instance of LongHashFunction without a seed. - * - * @return an instance of LongHashFunction without a seed + * Seedless CityHash64 {@link LongHashFunction}. */ public static LongHashFunction asLongHashFunctionWithoutSeed() { return AsLongHashFunction.INSTANCE; } /** - * Provides an instance of LongHashFunction with a seed. - * - * @param seed the seed - * @return an instance of LongHashFunction with the seed + * Seeded CityHash64 {@link LongHashFunction}. */ public static LongHashFunction asLongHashFunctionWithSeed(long seed) { return new AsLongHashFunctionSeeded(K2, seed); } /** - * Provides an instance of LongHashFunction with two seeds. - * - * @param seed0 the first seed - * @param seed1 the second seed - * @return an instance of LongHashFunction with the seeds + * CityHash64 {@link LongHashFunction} seeded with two values. */ public static LongHashFunction asLongHashFunctionWithTwoSeeds(long seed0, long seed1) { return new AsLongHashFunctionSeeded(seed0, seed1); @@ -296,13 +259,9 @@ long cityHash64(ReadAccess access, T in, long off, long len) { } else if (len <= 64L) { return hashLen33To64(access, in, off, len); } - long x = fetch64(access, in, off + len - 40L); - long y = fetch64(access, in, off + len - 16L) + fetch64(access, in, off + len - 56L); long z = hashLen16(fetch64(access, in, off + len - 48L) + len, fetch64(access, in, off + len - 24L)); - long vFirst, vSecond, wFirst, wSecond; - // This and following 3 blocks are produced by a single-click inline-function refactoring. // IntelliJ IDEA ftw // WeakHashLen32WithSeeds @@ -314,12 +273,12 @@ long cityHash64(ReadAccess access, T in, long off, long len) { long z4 = fetch64(access, in, off + len - 64L + 24L); a3 += w4; b3 = rotateRight(b3 + a3 + z4, 21); - long c3 = a3; + final long c3 = a3; a3 += x4 + y4; b3 += rotateRight(a3, 44); - vFirst = a3 + z4; - vSecond = b3 + c3; + long x = fetch64(access, in, off + len - 40L); + long y = fetch64(access, in, off + len - 16L) + fetch64(access, in, off + len - 56L); // WeakHashLen32WithSeeds long a2 = y + K1; long b2 = x; @@ -332,8 +291,10 @@ long cityHash64(ReadAccess access, T in, long off, long len) { long c2 = a2; a2 += x3 + y3; b2 += rotateRight(a2, 44); - wFirst = a2 + z3; - wSecond = b2 + c2; + long wSecond = b2 + c2; + long wFirst = a2 + z3; + long vSecond = b3 + c3; + long vFirst = a3 + z4; x = x * K1 + fetch64(access, in, off); @@ -357,8 +318,8 @@ long cityHash64(ReadAccess access, T in, long off, long len) { long c1 = a1; a1 += x2 + y2; b1 += rotateRight(a1, 44); - vFirst = a1 + z2; vSecond = b1 + c1; + vFirst = a1 + z2; // WeakHashLen32WithSeeds long a = z + wSecond; @@ -372,8 +333,8 @@ long cityHash64(ReadAccess access, T in, long off, long len) { long c = a; a += x1 + y1; b += rotateRight(a, 44); - wFirst = a + z1; wSecond = b + c; + wFirst = a + z1; long tmp = x; x = z; @@ -434,14 +395,14 @@ private Object readResolve() { @Override public long hashLong(long input) { - input = NATIVE_CITY.toLittleEndian(input); + input = nativeCity().toLittleEndian(input); long hash = hash8To16Bytes(8L, input, input); return finalizeHash(hash); } @Override public long hashInt(int input) { - input = NATIVE_CITY.toLittleEndian(input); + input = nativeCity().toLittleEndian(input); long unsignedInt = Primitives.unsignedInt(input); long hash = hash4To7Bytes(4L, unsignedInt, unsignedInt); return finalizeHash(hash); @@ -454,9 +415,8 @@ public long hashShort(short input) { @Override public long hashChar(char input) { - int unsignedInput = input; - int firstByte = (unsignedInput >> FIRST_SHORT_BYTE_SHIFT) & FIRST_SHORT_BYTE_MASK; - int secondByte = (unsignedInput >> SECOND_SHORT_BYTE_SHIFT) & SECOND_SHORT_BYTE_MASK; + int firstByte = ((int) input >> FIRST_SHORT_BYTE_SHIFT) & FIRST_SHORT_BYTE_MASK; + int secondByte = ((int) input >> SECOND_SHORT_BYTE_SHIFT) & SECOND_SHORT_BYTE_MASK; long hash = hash1To3Bytes(2, firstByte, secondByte, secondByte); return finalizeHash(hash); } @@ -496,7 +456,7 @@ private static class AsLongHashFunctionSeeded extends AsLongHashFunction { private static final long serialVersionUID = 0L; private final long seed0, seed1; - private final transient long voidHash; + private final long voidHash; private AsLongHashFunctionSeeded(long seed0, long seed1) { this.seed0 = seed0; diff --git a/src/main/java/net/openhft/chronicle/algo/hashing/LongHashFunction.java b/src/main/java/net/openhft/chronicle/algo/hashing/LongHashFunction.java index d96ccfb1..d75ceb28 100644 --- a/src/main/java/net/openhft/chronicle/algo/hashing/LongHashFunction.java +++ b/src/main/java/net/openhft/chronicle/algo/hashing/LongHashFunction.java @@ -262,7 +262,7 @@ public long hashBoolean(boolean input) { /** * Shortcut for {@link #hashBooleans(boolean[], int, int) hashBooleans(input, 0, input.length)}. */ - public long hashBooleans(@NotNull boolean[] input) { + public long hashBooleans(boolean @NotNull [] input) { return hashBooleans(input, 0, input.length); } @@ -276,7 +276,7 @@ public long hashBooleans(@NotNull boolean[] input) { * @throws IndexOutOfBoundsException if {@code off < 0} or {@code off + len > input.length} * or {@code len < 0} */ - public long hashBooleans(@NotNull boolean[] input, int off, int len) { + public long hashBooleans(boolean @NotNull [] input, int off, int len) { checkArrayOffs(input.length, off, len); return hash(booleanArrayAccessor(), input, off, len); } @@ -284,7 +284,7 @@ public long hashBooleans(@NotNull boolean[] input, int off, int len) { /** * Shortcut for {@link #hashBytes(byte[], int, int) hashBytes(input, 0, input.length)}. */ - public long hashBytes(@NotNull byte[] input) { + public long hashBytes(byte @NotNull [] input) { return hashBytes(input, 0, input.length); } @@ -298,7 +298,7 @@ public long hashBytes(@NotNull byte[] input) { * @throws IndexOutOfBoundsException if {@code off < 0} or {@code off + len > input.length} * or {@code len < 0} */ - public long hashBytes(@NotNull byte[] input, int off, int len) { + public long hashBytes(byte @NotNull [] input, int off, int len) { checkArrayOffs(input.length, off, len); return hash(byteArrayAccessor(), input, off, len); } @@ -343,7 +343,7 @@ public long hashMemory(long address, long len) { /** * Shortcut for {@link #hashChars(char[], int, int) hashChars(input, 0, input.length)}. */ - public long hashChars(@NotNull char[] input) { + public long hashChars(char @NotNull [] input) { return hashChars(input, 0, input.length); } @@ -359,7 +359,7 @@ public long hashChars(@NotNull char[] input) { * @throws IndexOutOfBoundsException if {@code off < 0} or {@code off + len > input.length} * or {@code len < 0} */ - public long hashChars(@NotNull char[] input, int off, int len) { + public long hashChars(char @NotNull [] input, int off, int len) { checkArrayOffs(input.length, off, len); return hash(charArrayAccessor(), input, off, len); } @@ -423,7 +423,7 @@ long hashNativeChars(CharSequence input, int off, int len) { /** * Shortcut for {@link #hashShorts(short[], int, int) hashShorts(input, 0, input.length)}. */ - public long hashShorts(@NotNull short[] input) { + public long hashShorts(short @NotNull [] input) { return hashShorts(input, 0, input.length); } @@ -439,7 +439,7 @@ public long hashShorts(@NotNull short[] input) { * @throws IndexOutOfBoundsException if {@code off < 0} or {@code off + len > input.length} * or {@code len < 0} */ - public long hashShorts(@NotNull short[] input, int off, int len) { + public long hashShorts(short @NotNull [] input, int off, int len) { checkArrayOffs(input.length, off, len); return hash(shortArrayAccessor(), input, off, len); } @@ -447,7 +447,7 @@ public long hashShorts(@NotNull short[] input, int off, int len) { /** * Shortcut for {@link #hashInts(int[], int, int) hashInts(input, 0, input.length)}. */ - public long hashInts(@NotNull int[] input) { + public long hashInts(int @NotNull [] input) { return hashInts(input, 0, input.length); } @@ -463,7 +463,7 @@ public long hashInts(@NotNull int[] input) { * @throws IndexOutOfBoundsException if {@code off < 0} or {@code off + len > input.length} * or {@code len < 0} */ - public long hashInts(@NotNull int[] input, int off, int len) { + public long hashInts(int @NotNull [] input, int off, int len) { checkArrayOffs(input.length, off, len); return hash(intArrayAccessor(), input, off, len); } @@ -471,7 +471,7 @@ public long hashInts(@NotNull int[] input, int off, int len) { /** * Shortcut for {@link #hashLongs(long[], int, int) hashLongs(input, 0, input.length)}. */ - public long hashLongs(@NotNull long[] input) { + public long hashLongs(long @NotNull [] input) { return hashLongs(input, 0, input.length); } @@ -487,7 +487,7 @@ public long hashLongs(@NotNull long[] input) { * @throws IndexOutOfBoundsException if {@code off < 0} or {@code off + len > input.length} * or {@code len < 0} */ - public long hashLongs(@NotNull long[] input, int off, int len) { + public long hashLongs(long @NotNull [] input, int off, int len) { checkArrayOffs(input.length, off, len); return hash(longArrayAccessor(), input, off, len); } diff --git a/src/main/java/net/openhft/chronicle/algo/hashing/MurmurHash_3.java b/src/main/java/net/openhft/chronicle/algo/hashing/MurmurHash_3.java index 9ac47b15..39741f1a 100644 --- a/src/main/java/net/openhft/chronicle/algo/hashing/MurmurHash_3.java +++ b/src/main/java/net/openhft/chronicle/algo/hashing/MurmurHash_3.java @@ -13,14 +13,11 @@ * Derived from https://github.com/google/guava/blob/fa95e381e665d8ee9639543b99ed38020c8de5ef * /guava/src/com/google/common/hash/Murmur3_128HashFunction.java */ +@SuppressWarnings("fallthrough") class MurmurHash_3 { // Singleton instance of MurmurHash_3 private static final MurmurHash_3 INSTANCE = new MurmurHash_3(); - // Singleton instance of MurmurHash_3 for native byte order - private static final MurmurHash_3 NATIVE_MURMUR = NATIVE_LITTLE_ENDIAN ? - MurmurHash_3.INSTANCE : BigEndian.INSTANCE; - // Constants used in the hash function private static final long C1 = 0x87c37b91114253d5L; private static final long C2 = 0x4cf5ad432745937fL; @@ -29,6 +26,10 @@ class MurmurHash_3 { private MurmurHash_3() { } + private static MurmurHash_3 nativeMurmur() { + return NATIVE_LITTLE_ENDIAN ? INSTANCE : BigEndian.INSTANCE; + } + /** * Finalizes the hash computation by mixing the hash values. * @@ -184,9 +185,9 @@ public long hash(long seed, T input, ReadAccess access, long offset, long long h2 = seed; long remaining = length; while (remaining >= 16L) { - long k1 = fetch64(access, input, offset); - long k2 = fetch64(access, input, offset + 8L); - offset += 16L; + long blockOffset = offset; + long k1 = fetch64(access, input, blockOffset); + offset = blockOffset + 16L; remaining -= 16L; h1 ^= mixK1(k1); @@ -194,6 +195,7 @@ public long hash(long seed, T input, ReadAccess access, long offset, long h1 += h2; h1 = h1 * 5L + 0x52dce729L; + long k2 = fetch64(access, input, blockOffset + 8L); h2 ^= mixK2(k2); h2 = Long.rotateLeft(h2, 31); @@ -201,122 +203,70 @@ public long hash(long seed, T input, ReadAccess access, long offset, long h2 = h2 * 5L + 0x38495ab5L; } if (remaining > 0L) { - long k1 = 0L; - long k2 = 0L; - switch ((int) remaining) { - case 15: - k2 ^= ((long) access.readUnsignedByte(input, offset + 14L)) << 48; // fall through - case 14: - k2 ^= ((long) access.readUnsignedByte(input, offset + 13L)) << 40; // fall through - case 13: - k2 ^= ((long) access.readUnsignedByte(input, offset + 12L)) << 32; // fall through - case 12: - k2 ^= ((long) access.readUnsignedByte(input, offset + 11L)) << 24; // fall through - case 11: - k2 ^= ((long) access.readUnsignedByte(input, offset + 10L)) << 16; // fall through - case 10: - k2 ^= ((long) access.readUnsignedByte(input, offset + 9L)) << 8; // fall through - case 9: - k2 ^= access.readUnsignedByte(input, offset + 8L); // fall through - case 8: - k1 ^= fetch64(access, input, offset); - break; - case 7: - k1 ^= ((long) access.readUnsignedByte(input, offset + 6L)) << 48; // fall through - case 6: - k1 ^= ((long) access.readUnsignedByte(input, offset + 5L)) << 40; // fall through - case 5: - k1 ^= ((long) access.readUnsignedByte(input, offset + 4L)) << 32; // fall through - case 4: - k1 ^= Primitives.unsignedInt(fetch32(access, input, offset)); - break; - case 3: - k1 ^= ((long) access.readUnsignedByte(input, offset + 2L)) << 16; // fall through - case 2: - k1 ^= ((long) access.readUnsignedByte(input, offset + 1L)) << 8; // fall through - case 1: - k1 ^= access.readUnsignedByte(input, offset); - case 0: - break; - default: - throw new AssertionError("Should never get here."); - } + int tailLength = (int) remaining; + long k1 = tailK1(access, input, offset, tailLength); + long k2 = tailK2(access, input, offset, tailLength); h1 ^= mixK1(k1); h2 ^= mixK2(k2); } -// This version appears to be working slower - -// if (remaining > 0L) { -// long k1 = 0L; -// long k2 = 0L; -// megaSwitch: -// { -// fetch0_7: -// { -// fetch8_11: -// { -// fetch0_3: -// { -// switch ((int) remaining) { -// case 15: -// k2 ^= ((long) access.readUnsignedByte(input, offset + 14L)) << 48; -// case 14: -// k2 ^= ((long) toLittleEndianShort( -// access.getUnsignedShort(input, offset + 12L))) << 32; -// break fetch8_11; -// case 13: -// k2 ^= ((long) access.readUnsignedByte(input, offset + 12L)) << 32; -// case 12: -// break fetch8_11; -// case 11: -// k2 ^= ((long) access.readUnsignedByte(input, offset + 10L)) << 16; -// case 10: -// k2 ^= (long) toLittleEndianShort( -// access.getUnsignedShort(input, offset + 8L)); -// break fetch0_7; -// case 9: -// k2 ^= ((long) access.readUnsignedByte(input, offset + 8L)); -// case 8: -// break fetch0_7; -// case 7: -// k1 ^= ((long) access.readUnsignedByte(input, offset + 6L)) << 48; -// case 6: -// k1 ^= ((long) toLittleEndianShort( -// access.getUnsignedShort(input, offset + 4L))) << 32; -// break fetch0_3; -// case 5: -// k1 ^= ((long) access.readUnsignedByte(input, offset + 4L)) << 32; -// case 4: -// break fetch0_3; -// case 3: -// k1 ^= ((long) access.readUnsignedByte(input, offset + 2L)) << 16; -// case 2: -// k1 ^= (long) toLittleEndianShort( -// access.getUnsignedShort(input, offset)); -// break megaSwitch; -// case 1: -// k1 ^= ((long) access.readUnsignedByte(input, offset)); -// break megaSwitch; -// default: -// throw new AssertionError(); -// } -// } // fetch0_3 -// k1 ^= unsignedInt(fetch32(access, input, offset)); -// break megaSwitch; -// } // fetch8_11 -// k2 ^= unsignedInt(fetch32(access, input, offset + 8L)); -// } // fetch0_7 -// k1 ^= fetch64(access, input, offset); -// } // megaSwitch -// -// h1 ^= mixK1(k1); -// h2 ^= mixK2(k2); -// } return finalize(length, h1, h2); } + private long tailK1(ReadAccess access, T input, long offset, int remaining) { + if (remaining >= 8) { + return fetch64(access, input, offset); + } + long k1 = 0L; + switch (remaining) { + case 7: + k1 ^= ((long) access.readUnsignedByte(input, offset + 6L)) << 48; // fall through + case 6: + k1 ^= ((long) access.readUnsignedByte(input, offset + 5L)) << 40; // fall through + case 5: + k1 ^= ((long) access.readUnsignedByte(input, offset + 4L)) << 32; // fall through + case 4: + k1 ^= Primitives.unsignedInt(fetch32(access, input, offset)); + break; + case 3: + k1 ^= ((long) access.readUnsignedByte(input, offset + 2L)) << 16; // fall through + case 2: + k1 ^= ((long) access.readUnsignedByte(input, offset + 1L)) << 8; // fall through + case 1: + k1 ^= access.readUnsignedByte(input, offset); + default: + break; + } + return k1; + } + + private long tailK2(ReadAccess access, T input, long offset, int remaining) { + if (remaining <= 8) { + return 0L; + } + long k2 = 0L; + switch (remaining) { + case 15: + k2 ^= ((long) access.readUnsignedByte(input, offset + 14L)) << 48; // fall through + case 14: + k2 ^= ((long) access.readUnsignedByte(input, offset + 13L)) << 40; // fall through + case 13: + k2 ^= ((long) access.readUnsignedByte(input, offset + 12L)) << 32; // fall through + case 12: + k2 ^= ((long) access.readUnsignedByte(input, offset + 11L)) << 24; // fall through + case 11: + k2 ^= ((long) access.readUnsignedByte(input, offset + 10L)) << 16; // fall through + case 10: + k2 ^= ((long) access.readUnsignedByte(input, offset + 9L)) << 8; // fall through + case 9: + k2 ^= access.readUnsignedByte(input, offset + 8L); + default: + break; + } + return k2; + } + /** - * Big-endian implementation of MurmurHash_3. + * Big-endian implementation of MurmurHash3. */ private static class BigEndian extends MurmurHash_3 { // Singleton instance of BigEndian @@ -353,7 +303,7 @@ int toLittleEndianShort(int unsignedShort) { } /** - * Implementation of LongHashFunction using MurmurHash_3. + * Implementation of LongHashFunction using MurmurHash3. */ private static class AsLongHashFunction extends LongHashFunction { // Singleton instance of AsLongHashFunction @@ -389,23 +339,23 @@ long hashNativeLong(long nativeLong, long len) { @Override public long hashLong(long input) { - return hashNativeLong(NATIVE_MURMUR.toLittleEndian(input), 8L); + return hashNativeLong(nativeMurmur().toLittleEndian(input), 8L); } @Override public long hashInt(int input) { - return hashNativeLong(Primitives.unsignedInt(NATIVE_MURMUR.toLittleEndian(input)), 4L); + return hashNativeLong(Primitives.unsignedInt(nativeMurmur().toLittleEndian(input)), 4L); } @Override public long hashShort(short input) { return hashNativeLong( - NATIVE_MURMUR.toLittleEndianShort(Primitives.unsignedShort(input)), 2L); + nativeMurmur().toLittleEndianShort(Primitives.unsignedShort(input)), 2L); } @Override public long hashChar(char input) { - return hashNativeLong(NATIVE_MURMUR.toLittleEndianShort(input), 2L); + return hashNativeLong(nativeMurmur().toLittleEndianShort(input), 2L); } @Override @@ -430,7 +380,7 @@ public long hash(T input, ReadAccess access, long off, long len) { } /** - * Implementation of LongHashFunction using MurmurHash_3 with a seed value. + * Implementation of LongHashFunction using MurmurHash3 with a seed value. */ private static class AsLongHashFunctionSeeded extends AsLongHashFunction { private static final long serialVersionUID = 0L; @@ -438,7 +388,7 @@ private static class AsLongHashFunctionSeeded extends AsLongHashFunction { // The seed value private final long seed; // The precomputed hash value for an empty input - private final transient long voidHash; + private final long voidHash; /** * Constructs an instance with the given seed. @@ -459,8 +409,7 @@ long seed() { long hashNativeLong(long nativeLong, long len) { long seed = this.seed; long h1 = seed ^ mixK1(nativeLong); - long h2 = seed; - return MurmurHash_3.finalize(len, h1, h2); + return MurmurHash_3.finalize(len, h1, seed); } @Override diff --git a/src/main/java/net/openhft/chronicle/algo/hashing/XxHash_r39.java b/src/main/java/net/openhft/chronicle/algo/hashing/XxHash_r39.java index 45ec8175..4b6a86c6 100644 --- a/src/main/java/net/openhft/chronicle/algo/hashing/XxHash_r39.java +++ b/src/main/java/net/openhft/chronicle/algo/hashing/XxHash_r39.java @@ -9,15 +9,13 @@ import static net.openhft.chronicle.algo.hashing.LongHashFunction.NATIVE_LITTLE_ENDIAN; /** - * Adapted version of xxHash implementation from - * https://github.com/Cyan4973/xxHash/releases/tag/r39, which is fully compatible with r40 though. - * This implementation provides endian-independant hash values, - * but it's slower on big-endian platforms. + * Endian-independent xxHash64 implementation based on r39 (compatible with r40). + *

+ * Converts inputs via {@link ReadAccess} so hashing can be applied to any addressable source. + * Uses little-endian mixing internally; big-endian platforms pay a small penalty. */ class XxHash_r39 { private static final XxHash_r39 INSTANCE = new XxHash_r39(); - private static final XxHash_r39 NATIVE_XX = NATIVE_LITTLE_ENDIAN ? - XxHash_r39.INSTANCE : BigEndian.INSTANCE; // Primes if treated as unsigned private static final long P1 = -7046029288634856825L; @@ -30,11 +28,12 @@ class XxHash_r39 { private XxHash_r39() { } + private static XxHash_r39 nativeXx() { + return NATIVE_LITTLE_ENDIAN ? INSTANCE : BigEndian.INSTANCE; + } + /** - * Finalizes the hash value with additional mixing of bits. - * - * @param hash The initial hash value to finalize - * @return The finalized hash value + * Final mixing step used by xxHash64. */ private static long finalize(long hash) { hash ^= hash >>> 33; @@ -46,19 +45,14 @@ private static long finalize(long hash) { } /** - * Returns a LongHashFunction instance implementing xxHash without a seed. - * - * @return A LongHashFunction instance + * Returns a seedless xxHash64 {@link LongHashFunction}. */ public static LongHashFunction asLongHashFunctionWithoutSeed() { return AsLongHashFunction.SEEDLESS_INSTANCE; } /** - * Returns a LongHashFunction instance implementing xxHash with the given seed. - * - * @param seed The seed value for the hash function - * @return A LongHashFunction instance + * Returns a seeded xxHash64 {@link LongHashFunction}. */ public static LongHashFunction asLongHashFunctionWithSeed(long seed) { return new AsLongHashFunctionSeeded(seed); @@ -262,7 +256,8 @@ long fetch32(ReadAccess access, T in, long off) { // Reverse bytes for big-endian compatibility return Integer.reverseBytes(access.readInt(in, off)) & 0xFFFFFFFFL; } -// fetch8 is not overloaded, because endianness doesn't matter for single byte + + // fetch8 is not overloaded, because endianness doesn't matter for single byte @Override long toLittleEndian(long v) { @@ -307,11 +302,11 @@ public long seed() { @Override public long hashLong(long input) { // Convert input to little-endian and compute hash - input = NATIVE_XX.toLittleEndian(input); - long hash = seed() + P5 + 8; + input = nativeXx().toLittleEndian(input); input *= P2; input = Long.rotateLeft(input, 31); input *= P1; + long hash = seed() + P5 + 8; hash ^= input; hash = Long.rotateLeft(hash, 27) * P1 + P4; return XxHash_r39.finalize(hash); @@ -320,7 +315,7 @@ public long hashLong(long input) { @Override public long hashInt(int input) { // Convert input to little-endian and compute hash - input = NATIVE_XX.toLittleEndian(input); + input = nativeXx().toLittleEndian(input); long hash = seed() + P5 + 4; hash ^= Primitives.unsignedInt(input) * P1; hash = Long.rotateLeft(hash, 23) * P2 + P3; @@ -330,7 +325,7 @@ public long hashInt(int input) { @Override public long hashShort(short input) { // Convert input to little-endian and compute hash - input = NATIVE_XX.toLittleEndian(input); + input = nativeXx().toLittleEndian(input); long hash = seed() + P5 + 2; hash ^= Primitives.unsignedByte(input) * P5; hash = Long.rotateLeft(hash, 11) * P1; diff --git a/src/main/java/net/openhft/chronicle/algo/hashing/package-info.java b/src/main/java/net/openhft/chronicle/algo/hashing/package-info.java new file mode 100644 index 00000000..7eb85fe5 --- /dev/null +++ b/src/main/java/net/openhft/chronicle/algo/hashing/package-info.java @@ -0,0 +1,13 @@ +/** + * Non cryptographic hash functions and helpers. + * + *

This package provides a collection of 64 bit hash implementations such + * as Murmur3, CityHash, and xxHash, together with convenience utilities for + * hashing primitive values, byte sequences, and composite keys. + * + *

The focus is on high throughput, high quality hashing suitable for use + * in off heap data structures and Chronicle components. Algorithm classes + * are part of the public API, but their internal constants and helper + * methods are considered implementation details. + */ +package net.openhft.chronicle.algo.hashing; diff --git a/src/main/java/net/openhft/chronicle/algo/locks/AbstractReadWriteLockState.java b/src/main/java/net/openhft/chronicle/algo/locks/AbstractReadWriteLockState.java index 27d225f1..b8d0b230 100644 --- a/src/main/java/net/openhft/chronicle/algo/locks/AbstractReadWriteLockState.java +++ b/src/main/java/net/openhft/chronicle/algo/locks/AbstractReadWriteLockState.java @@ -4,8 +4,8 @@ package net.openhft.chronicle.algo.locks; /** - * Abstract base class for managing read-write lock state. - * Implements common behavior for acquiring and releasing write locks. + * Base implementation for {@link ReadWriteLockState} that routes generic lock/unlock to write + * semantics. Concrete subclasses supply the read/write state handling. */ public abstract class AbstractReadWriteLockState implements ReadWriteLockState { diff --git a/src/main/java/net/openhft/chronicle/algo/locks/AcquisitionStrategies.java b/src/main/java/net/openhft/chronicle/algo/locks/AcquisitionStrategies.java index cc3fa555..07ddec96 100644 --- a/src/main/java/net/openhft/chronicle/algo/locks/AcquisitionStrategies.java +++ b/src/main/java/net/openhft/chronicle/algo/locks/AcquisitionStrategies.java @@ -9,7 +9,8 @@ import java.util.concurrent.TimeUnit; /** - * Provides various acquisition strategies for locking mechanisms. + * Factory for common lock acquisition strategies including spin loops and wait-registration + * helpers. Designed to be combined with {@link LockingStrategy} implementations. */ public final class AcquisitionStrategies { diff --git a/src/main/java/net/openhft/chronicle/algo/locks/AcquisitionStrategy.java b/src/main/java/net/openhft/chronicle/algo/locks/AcquisitionStrategy.java index 2ea2666d..6eece8fd 100644 --- a/src/main/java/net/openhft/chronicle/algo/locks/AcquisitionStrategy.java +++ b/src/main/java/net/openhft/chronicle/algo/locks/AcquisitionStrategy.java @@ -6,7 +6,7 @@ import net.openhft.chronicle.algo.bytes.Access; /** - * Interface representing an acquisition strategy for locking mechanisms. + * Pluggable strategy for acquiring locks using a {@link LockingStrategy} and {@link Access}. * * @param the type of the locking strategy * @param the type of exception that might be thrown during the acquisition process diff --git a/src/main/java/net/openhft/chronicle/algo/locks/LockState.java b/src/main/java/net/openhft/chronicle/algo/locks/LockState.java index 3a56f83f..be51d4cf 100644 --- a/src/main/java/net/openhft/chronicle/algo/locks/LockState.java +++ b/src/main/java/net/openhft/chronicle/algo/locks/LockState.java @@ -4,8 +4,10 @@ package net.openhft.chronicle.algo.locks; /** - * Interface representing the state of a lock. - * Provides methods for attempting to acquire the lock, releasing the lock, and resetting the lock state. + * Abstraction over a lock's backing state that can be stored and manipulated via {@link LockingStrategy}. + *

+ * Implementations hide whether the state lives in memory, on-heap structures or elsewhere; the + * strategy knows how to interpret {@link #getState()}. */ public interface LockState { diff --git a/src/main/java/net/openhft/chronicle/algo/locks/LockingStrategy.java b/src/main/java/net/openhft/chronicle/algo/locks/LockingStrategy.java index 15d75def..1d742b30 100644 --- a/src/main/java/net/openhft/chronicle/algo/locks/LockingStrategy.java +++ b/src/main/java/net/openhft/chronicle/algo/locks/LockingStrategy.java @@ -7,7 +7,10 @@ import net.openhft.chronicle.algo.bytes.ReadAccess; /** - * Interface representing a locking strategy for managing locks on resources. + * Strategy for managing lock state stored in arbitrary addressable resources. + *

+ * Provides low-level operations that are composed by higher-level acquisition strategies to + * implement spin locks, read/write locks and other primitives. */ public interface LockingStrategy { diff --git a/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteLockState.java b/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteLockState.java index 8e63f8ca..e2f27dba 100644 --- a/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteLockState.java +++ b/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteLockState.java @@ -4,9 +4,10 @@ package net.openhft.chronicle.algo.locks; /** - * Interface representing the state of a read-write lock. - * Provides methods for acquiring and releasing read and write locks, - * as well as upgrading and downgrading lock states. + * Abstraction over the mutable state of a read-write lock. + *

+ * Exposes operations to acquire/release read and write ownership, perform upgrades/downgrades and + * exposes the associated {@link ReadWriteLockingStrategy}. */ public interface ReadWriteLockState extends LockState { diff --git a/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteLockingStrategy.java b/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteLockingStrategy.java index 36d94051..49074b55 100644 --- a/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteLockingStrategy.java +++ b/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteLockingStrategy.java @@ -6,9 +6,10 @@ import net.openhft.chronicle.algo.bytes.Access; /** - * Interface representing a read-write locking strategy. - * Provides methods for acquiring and releasing read and write locks, - * as well as upgrading and downgrading lock states. + * Strategy for manipulating read/write lock state stored in an addressable resource. + *

+ * Supplies primitives for read/write acquisition, upgrades, downgrades, and introspection of the + * current state; higher-level code composes these to implement lock protocols. */ public interface ReadWriteLockingStrategy extends LockingStrategy { diff --git a/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteUpdateLockState.java b/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteUpdateLockState.java index fbeb4498..3bcbb836 100644 --- a/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteUpdateLockState.java +++ b/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteUpdateLockState.java @@ -4,11 +4,11 @@ package net.openhft.chronicle.algo.locks; /** - * Interface representing the state and operations of a read-write-update lock. + * Mutable view of a read/write/update lock's state. *

- * A read lock allows multiple concurrent reads. - * An update lock allows concurrent reads but not multiple update locks. - * A write lock is exclusive. + * Supports acquiring and releasing the intermediate update state, upgrading from read to update, + * then to write, and downgrading in the opposite direction. The associated strategy handles the + * low-level storage representation. */ public interface ReadWriteUpdateLockState extends ReadWriteLockState { diff --git a/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteUpdateLockingStrategy.java b/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteUpdateLockingStrategy.java index a5672eca..962bb474 100644 --- a/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteUpdateLockingStrategy.java +++ b/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteUpdateLockingStrategy.java @@ -6,11 +6,10 @@ import net.openhft.chronicle.algo.bytes.Access; /** - * Interface defining the logic of read-write-update lock state transitions. + * Strategy covering the additional "update" state layered on a read/write lock. *

- * A read lock allows multiple concurrent reads. - * An update lock allows concurrent reads but not multiple update locks. - * A write lock is exclusive. + * Update locks block other updaters but still allow readers, providing a staging point before + * upgrading to an exclusive write lock. */ public interface ReadWriteUpdateLockingStrategy extends ReadWriteLockingStrategy { diff --git a/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteUpdateWithWaitsLockState.java b/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteUpdateWithWaitsLockState.java index 59f79935..502d927c 100644 --- a/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteUpdateWithWaitsLockState.java +++ b/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteUpdateWithWaitsLockState.java @@ -4,10 +4,9 @@ package net.openhft.chronicle.algo.locks; /** - * Interface representing a read-write-update lock state with wait registration capabilities. + * Read/write/update lock state that also tracks registered waiters. *

- * This interface extends both {@link ReadWriteUpdateLockState} and {@link ReadWriteWithWaitsLockState}, - * adding the capability to upgrade an update lock to a write lock while deregistering the wait state. + * Adds an operation to upgrade from update to write while removing the wait registration. */ public interface ReadWriteUpdateWithWaitsLockState extends ReadWriteUpdateLockState, ReadWriteWithWaitsLockState { diff --git a/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteUpdateWithWaitsLockingStrategy.java b/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteUpdateWithWaitsLockingStrategy.java index 451872a6..a61ae256 100644 --- a/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteUpdateWithWaitsLockingStrategy.java +++ b/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteUpdateWithWaitsLockingStrategy.java @@ -6,10 +6,9 @@ import net.openhft.chronicle.algo.bytes.Access; /** - * Interface representing a read-write-update lock with wait registration capabilities. + * Read/write/update locking strategy that also tracks wait registrations. *

- * This interface extends both {@link ReadWriteUpdateLockingStrategy} and {@link ReadWriteWithWaitsLockingStrategy}, - * adding the capability to upgrade an update lock to a write lock while deregistering the wait state. + * Adds a helper to upgrade an update lock to a write lock while deregistering an outstanding wait. */ public interface ReadWriteUpdateWithWaitsLockingStrategy extends ReadWriteUpdateLockingStrategy, ReadWriteWithWaitsLockingStrategy { diff --git a/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteWithWaitsLockState.java b/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteWithWaitsLockState.java index e454f93f..505da5f7 100644 --- a/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteWithWaitsLockState.java +++ b/src/main/java/net/openhft/chronicle/algo/locks/ReadWriteWithWaitsLockState.java @@ -4,10 +4,9 @@ package net.openhft.chronicle.algo.locks; /** - * Interface representing a read-write lock state with wait registration capabilities. + * Read/write lock state that also tracks waiting threads for coordination purposes. *

- * This interface extends {@link ReadWriteLockState}, adding methods to register and - * deregister waits, and to manage write locks with wait deregistration. + * Adds wait registration, wait-aware acquisition helpers, and a specialised strategy link. */ public interface ReadWriteWithWaitsLockState extends ReadWriteLockState { diff --git a/src/main/java/net/openhft/chronicle/algo/locks/TryAcquireOperation.java b/src/main/java/net/openhft/chronicle/algo/locks/TryAcquireOperation.java index c2db7dae..6a62b774 100644 --- a/src/main/java/net/openhft/chronicle/algo/locks/TryAcquireOperation.java +++ b/src/main/java/net/openhft/chronicle/algo/locks/TryAcquireOperation.java @@ -6,7 +6,7 @@ import net.openhft.chronicle.algo.bytes.Access; /** - * Represents an operation that attempts to acquire a lock using a given locking strategy. + * Callback invoked by {@link AcquisitionStrategy} implementations to attempt lock acquisition. * * @param the type of the locking strategy */ diff --git a/src/main/java/net/openhft/chronicle/algo/locks/TryAcquireOperations.java b/src/main/java/net/openhft/chronicle/algo/locks/TryAcquireOperations.java index 8d7fbb8a..b9d9c133 100644 --- a/src/main/java/net/openhft/chronicle/algo/locks/TryAcquireOperations.java +++ b/src/main/java/net/openhft/chronicle/algo/locks/TryAcquireOperations.java @@ -3,8 +3,6 @@ */ package net.openhft.chronicle.algo.locks; -import net.openhft.chronicle.algo.bytes.Access; - /** * Utility class providing various {@link TryAcquireOperation} implementations * for different locking strategies. @@ -13,109 +11,48 @@ public final class TryAcquireOperations { // TryAcquireOperation for LockingStrategy private static final TryAcquireOperation LOCK = - new TryAcquireOperation() { - @Override - public boolean tryAcquire(LockingStrategy strategy, - Access access, T obj, long offset) { - return strategy.tryLock(access, obj, offset); - } - }; + LockingStrategy::tryLock; // TryAcquireOperation for ReadWriteLockingStrategy - Read Lock private static final TryAcquireOperation READ_LOCK = - new TryAcquireOperation() { - @Override - public boolean tryAcquire(ReadWriteLockingStrategy strategy, - Access access, T obj, long offset) { - return strategy.tryReadLock(access, obj, offset); - } - }; + ReadWriteLockingStrategy::tryReadLock; // TryAcquireOperation for ReadWriteLockingStrategy - Upgrade Read to Write Lock private static final TryAcquireOperation UPGRADE_READ_TO_WRITE_LOCK = - new TryAcquireOperation() { - @Override - public boolean tryAcquire(ReadWriteLockingStrategy strategy, - Access access, T obj, long offset) { - return strategy.tryUpgradeReadToWriteLock(access, obj, offset); - } - }; + ReadWriteLockingStrategy::tryUpgradeReadToWriteLock; // TryAcquireOperation for ReadWriteLockingStrategy - Write Lock private static final TryAcquireOperation WRITE_LOCK = - new TryAcquireOperation() { - @Override - public boolean tryAcquire(ReadWriteLockingStrategy strategy, - Access access, T obj, long offset) { - return strategy.tryWriteLock(access, obj, offset); - } - }; + ReadWriteLockingStrategy::tryWriteLock; // TryAcquireOperation for ReadWriteWithWaitsLockingStrategy - Upgrade Read to Write Lock and Deregister Wait private static final TryAcquireOperation UPGRADE_READ_TO_WRITE_LOCK_AND_DEREGISTER_WAIT = - new TryAcquireOperation() { - @Override - public boolean tryAcquire(ReadWriteWithWaitsLockingStrategy strategy, - Access access, T obj, long offset) { - return strategy.tryUpgradeReadToWriteLockAndDeregisterWait(access, obj, offset); - } - }; + ReadWriteWithWaitsLockingStrategy::tryUpgradeReadToWriteLockAndDeregisterWait; // TryAcquireOperation for ReadWriteWithWaitsLockingStrategy - Write Lock and Deregister Wait private static final TryAcquireOperation WRITE_LOCK_AND_DEREGISTER_WAIT = - new TryAcquireOperation() { - @Override - public boolean tryAcquire(ReadWriteWithWaitsLockingStrategy strategy, - Access access, T obj, long offset) { - return strategy.tryWriteLockAndDeregisterWait(access, obj, offset); - } - }; + ReadWriteWithWaitsLockingStrategy::tryWriteLockAndDeregisterWait; // TryAcquireOperation for ReadWriteUpdateLockingStrategy - Update Lock private static final TryAcquireOperation UPDATE_LOCK = - new TryAcquireOperation() { - @Override - public boolean tryAcquire(ReadWriteUpdateLockingStrategy strategy, - Access access, T obj, long offset) { - return strategy.tryUpdateLock(access, obj, offset); - } - }; + ReadWriteUpdateLockingStrategy::tryUpdateLock; // TryAcquireOperation for ReadWriteUpdateLockingStrategy - Upgrade Read to Update Lock private static final TryAcquireOperation UPGRADE_READ_TO_UPDATE_LOCK = - new TryAcquireOperation() { - @Override - public boolean tryAcquire(ReadWriteUpdateLockingStrategy strategy, - Access access, T obj, long offset) { - return strategy.tryUpgradeReadToUpdateLock(access, obj, offset); - } - }; + ReadWriteUpdateLockingStrategy::tryUpgradeReadToUpdateLock; // TryAcquireOperation for ReadWriteUpdateLockingStrategy - Upgrade Update to Write Lock private static final TryAcquireOperation UPGRADE_UPDATE_TO_WRITE_LOCK = - new TryAcquireOperation() { - @Override - public boolean tryAcquire(ReadWriteUpdateLockingStrategy strategy, - Access access, T obj, long offset) { - return strategy.tryUpgradeUpdateToWriteLock(access, obj, offset); - } - }; + ReadWriteUpdateLockingStrategy::tryUpgradeUpdateToWriteLock; // TryAcquireOperation for ReadWriteUpdateWithWaitsLockingStrategy - Upgrade Update to Write Lock and Deregister Wait private static final TryAcquireOperation UPGRADE_UPDATE_TO_WRITE_LOCK_AND_DEREGISTER_WAIT = - new TryAcquireOperation() { - @Override - public boolean tryAcquire(ReadWriteUpdateWithWaitsLockingStrategy strategy, - Access access, T obj, long offset) { - return strategy.tryUpgradeUpdateToWriteLockAndDeregisterWait( - access, obj, offset); - } - }; + ReadWriteUpdateWithWaitsLockingStrategy::tryUpgradeUpdateToWriteLockAndDeregisterWait; // Private constructor to prevent instantiation private TryAcquireOperations() { diff --git a/src/main/java/net/openhft/chronicle/algo/locks/VanillaReadWriteUpdateWithWaitsLockingStrategy.java b/src/main/java/net/openhft/chronicle/algo/locks/VanillaReadWriteUpdateWithWaitsLockingStrategy.java index b3445039..5eb7eacb 100644 --- a/src/main/java/net/openhft/chronicle/algo/locks/VanillaReadWriteUpdateWithWaitsLockingStrategy.java +++ b/src/main/java/net/openhft/chronicle/algo/locks/VanillaReadWriteUpdateWithWaitsLockingStrategy.java @@ -10,8 +10,10 @@ import static java.nio.ByteOrder.nativeOrder; /** - * Vanilla implementation of a read-write-update lock with waits. - * This class provides the locking mechanism to handle read, write, and update operations with wait strategies. + * Vanilla implementation of a read/write/update lock that also tracks waiters. + *

+ * Encodes counts, update and write ownership, and wait flags into two words and exposes CAS helpers + * so callers can embed the lock state in arbitrary addressable memory. */ public final class VanillaReadWriteUpdateWithWaitsLockingStrategy extends AbstractReadWriteLockingStrategy @@ -48,13 +50,7 @@ public static ReadWriteUpdateWithWaitsLockingStrategy instance() { } /** - * Retrieves the lock word from the given ReadAccess. - * - * @param access The ReadAccess instance - * @param t The input handle - * @param offset The offset within the input - * @param The type of the input handle - * @return The lock word read from the input + * Retrieves the volatile lock word (count + wait packed). */ private static long getLockWord(ReadAccess access, T t, long offset) { // Reads the lock word from the specified offset @@ -62,15 +58,7 @@ private static long getLockWord(ReadAccess access, T t, long offset) { } /** - * Performs a compare-and-swap operation on the lock word. - * - * @param access The Access instance - * @param t The input handle - * @param offset The offset within the input - * @param expected The expected value - * @param x The new value - * @param The type of the input handle - * @return True if the operation was successful, false otherwise + * Compare-and-swap the combined lock word. */ public static boolean casLockWord( Access access, T t, long offset, long expected, long x) { @@ -79,10 +67,7 @@ public static boolean casLockWord( } /** - * Extracts the count word from the given lock word. - * - * @param lockWord The lock word - * @return The count word + * Extracts the count word (reads/update/write) from the packed lock word. */ private static int countWord(long lockWord) { // Extracts the count word from the lock word @@ -90,10 +75,7 @@ private static int countWord(long lockWord) { } /** - * Extracts the wait word from the given lock word. - * - * @param lockWord The lock word - * @return The wait word + * Extracts the wait word from the packed lock word. */ private static int waitWord(long lockWord) { // Extracts the wait word from the lock word @@ -101,11 +83,7 @@ private static int waitWord(long lockWord) { } /** - * Constructs a lock word from the given count and wait words. - * - * @param countWord The count word - * @param waitWord The wait word - * @return The constructed lock word + * Pack count and wait words into a single long. */ public static long lockWord(int countWord, int waitWord) { // Combines the count and wait words into a single lock word @@ -114,13 +92,7 @@ public static long lockWord(int countWord, int waitWord) { } /** - * Retrieves the count word from the given Access instance. - * - * @param access The Access instance - * @param t The input handle - * @param offset The offset within the input - * @param The type of the input handle - * @return The count word read from the input + * Read the volatile count word component. */ private static int getCountWord(Access access, T t, long offset) { // Reads the count word from the specified offset diff --git a/src/main/java/net/openhft/chronicle/algo/locks/package-info.java b/src/main/java/net/openhft/chronicle/algo/locks/package-info.java new file mode 100644 index 00000000..0481e88c --- /dev/null +++ b/src/main/java/net/openhft/chronicle/algo/locks/package-info.java @@ -0,0 +1,15 @@ +/** + * Locking strategies and state machines for low latency code. + * + *

Classes in this package model read write and update locks together with + * the associated acquisition strategies and lock states. They are intended + * for use by Chronicle data structures that need fine grained control over + * contention behaviour without depending directly on {@code java.util.concurrent} + * locks. + * + *

The abstractions here describe lock semantics and usage patterns rather + * than specific synchronisation primitives. They are part of the public + * Chronicle Algorithms API, but callers should not rely on the internal + * representation of lock states. + */ +package net.openhft.chronicle.algo.locks; diff --git a/src/main/java/net/openhft/chronicle/algo/package-info.java b/src/main/java/net/openhft/chronicle/algo/package-info.java new file mode 100644 index 00000000..e879fd14 --- /dev/null +++ b/src/main/java/net/openhft/chronicle/algo/package-info.java @@ -0,0 +1,13 @@ +/** + * Core algorithm utilities shared across Chronicle libraries. + * + *

This root package provides general purpose low level primitives such + * as {@code MemoryUnit} together with access to sub-packages that implement + * bit set operations, hashing functions, byte access abstractions, and lock + * strategies. + * + *

This package forms part of the public Chronicle Algorithms API. We aim + * to keep the exposed types stable within a major version, while allowing + * individual algorithms and internal implementations to evolve over time. + */ +package net.openhft.chronicle.algo; diff --git a/src/test/java/net/openhft/chronicle/algo/MemoryUnitTest.java b/src/test/java/net/openhft/chronicle/algo/MemoryUnitTest.java index a5e2bfb4..ce225b47 100644 --- a/src/test/java/net/openhft/chronicle/algo/MemoryUnitTest.java +++ b/src/test/java/net/openhft/chronicle/algo/MemoryUnitTest.java @@ -46,8 +46,7 @@ static Stream alignmentPairs() { @DisplayName("align throws for invalid granularity combinations") void alignRejectsFinerOrEqualUnits() { for (MemoryUnit unit : MemoryUnit.values()) { - MemoryUnit finalUnit = unit; - assertThrows(IllegalStateException.class, () -> finalUnit.align(1, finalUnit)); + assertThrows(IllegalStateException.class, () -> unit.align(1, unit)); for (int coarser = unit.ordinal() + 1; coarser < MemoryUnit.values().length; coarser++) { MemoryUnit coarserUnit = MemoryUnit.values()[coarser]; assertThrows(IllegalStateException.class, () -> unit.align(1, coarserUnit)); diff --git a/src/test/java/net/openhft/chronicle/algo/bitset/BitSetTest.java b/src/test/java/net/openhft/chronicle/algo/bitset/BitSetTest.java index 73c02d43..b45cdf11 100644 --- a/src/test/java/net/openhft/chronicle/algo/bitset/BitSetTest.java +++ b/src/test/java/net/openhft/chronicle/algo/bitset/BitSetTest.java @@ -3,13 +3,14 @@ */ package net.openhft.chronicle.algo.bitset; -import junit.framework.TestCase; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.*; -public class BitSetTest extends TestCase { +public class BitSetTest { private BitSet bitSet; @BeforeEach diff --git a/src/test/java/net/openhft/chronicle/algo/bitset/ConcurrentFlatBitSetFrameTest.java b/src/test/java/net/openhft/chronicle/algo/bitset/ConcurrentFlatBitSetFrameTest.java index 504bd197..72542848 100644 --- a/src/test/java/net/openhft/chronicle/algo/bitset/ConcurrentFlatBitSetFrameTest.java +++ b/src/test/java/net/openhft/chronicle/algo/bitset/ConcurrentFlatBitSetFrameTest.java @@ -3,15 +3,15 @@ */ package net.openhft.chronicle.algo.bitset; -import junit.framework.TestCase; import net.openhft.chronicle.algo.bytes.Access; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.*; @SuppressWarnings("unchecked") -public class ConcurrentFlatBitSetFrameTest extends TestCase { +public class ConcurrentFlatBitSetFrameTest { private ConcurrentFlatBitSetFrame bitSetFrame; private Access access; private Object handle; diff --git a/src/test/java/net/openhft/chronicle/algo/bitset/DirectBitSetTest.java b/src/test/java/net/openhft/chronicle/algo/bitset/DirectBitSetTest.java index 60b238f0..b037b3cf 100644 --- a/src/test/java/net/openhft/chronicle/algo/bitset/DirectBitSetTest.java +++ b/src/test/java/net/openhft/chronicle/algo/bitset/DirectBitSetTest.java @@ -125,12 +125,12 @@ public void testGetSetClearAndCardinality() { assertTrue("At index " + i, bs.isClear(i)); } for (int i : INDICES) { - assertEquals("At index " + i, true, bs.setIfClear(i)); - assertEquals("At index " + i, false, bs.setIfClear(i)); + assertTrue("At index " + i, bs.setIfClear(i)); + assertFalse("At index " + i, bs.setIfClear(i)); } for (int i : INDICES) { - assertEquals("At index " + i, true, bs.clearIfSet(i)); - assertEquals("At index " + i, false, bs.clearIfSet(i)); + assertTrue("At index " + i, bs.clearIfSet(i)); + assertFalse("At index " + i, bs.clearIfSet(i)); } } @@ -138,11 +138,11 @@ public void testGetSetClearAndCardinality() { public void testFlip() { bs.clearAll(); for (int i : INDICES) { - assertEquals("At index " + i, false, bs.get(i)); + assertFalse("At index " + i, bs.get(i)); bs.flip(i); - assertEquals("At index " + i, true, bs.get(i)); + assertTrue("At index " + i, bs.get(i)); bs.flip(i); - assertEquals("At index " + i, false, bs.get(i)); + assertFalse("At index " + i, bs.get(i)); } } @@ -387,10 +387,10 @@ public void testRangeOpsWithinLongCase() { assertTrue(bs.isRangeSet(63, 63)); } bs.flipRange(0, 0); - assertEquals(false, bs.get(0)); + assertFalse(bs.get(0)); assertEquals(0, bs.cardinality()); bs.flipRange(0, 1); - assertEquals(true, bs.get(0)); + assertTrue(bs.get(0)); assertEquals(1, bs.cardinality()); if (singleThreaded) { assertTrue(bs.isRangeSet(0, 1)); @@ -398,17 +398,17 @@ public void testRangeOpsWithinLongCase() { assertFalse(bs.isRangeClear(0, 1)); } bs.clearRange(0, 0); - assertEquals(true, bs.get(0)); + assertTrue(bs.get(0)); assertEquals(1, bs.cardinality()); bs.clearRange(0, 1); - assertEquals(false, bs.get(0)); + assertFalse(bs.get(0)); assertEquals(0, bs.cardinality()); bs.setRange(0, 0); - assertEquals(false, bs.get(0)); + assertFalse(bs.get(0)); assertEquals(0, bs.cardinality()); bs.setRange(0, 1); - assertEquals(true, bs.get(0)); + assertTrue(bs.get(0)); assertEquals(1, bs.cardinality()); } @@ -417,16 +417,16 @@ public void testRangeOpsCrossLongCase() { bs.clearAll(); bs.flipRange(63, 64); - assertEquals(true, bs.get(63)); - assertEquals(false, bs.get(64)); + assertTrue(bs.get(63)); + assertFalse(bs.get(64)); assertEquals(1, bs.cardinality()); if (singleThreaded) { assertFalse(bs.isRangeSet(63, 65)); assertFalse(bs.isRangeClear(63, 65)); } bs.flipRange(63, 65); - assertEquals(false, bs.get(63)); - assertEquals(true, bs.get(64)); + assertFalse(bs.get(63)); + assertTrue(bs.get(64)); assertEquals(1, bs.cardinality()); if (singleThreaded) { assertFalse(bs.isRangeSet(63, 65)); @@ -434,28 +434,28 @@ public void testRangeOpsCrossLongCase() { } bs.clear(64); bs.setRange(63, 64); - assertEquals(true, bs.get(63)); - assertEquals(false, bs.get(64)); + assertTrue(bs.get(63)); + assertFalse(bs.get(64)); assertEquals(1, bs.cardinality()); bs.set(64); bs.clearRange(63, 64); - assertEquals(false, bs.get(63)); - assertEquals(true, bs.get(64)); + assertFalse(bs.get(63)); + assertTrue(bs.get(64)); assertEquals(1, bs.cardinality()); bs.clear(64); bs.setRange(63, 65); - assertEquals(true, bs.get(63)); - assertEquals(true, bs.get(64)); + assertTrue(bs.get(63)); + assertTrue(bs.get(64)); assertEquals(2, bs.cardinality()); if (singleThreaded) { assertTrue(bs.isRangeSet(63, 65)); assertFalse(bs.isRangeClear(63, 65)); } bs.clearRange(63, 65); - assertEquals(false, bs.get(63)); - assertEquals(false, bs.get(64)); + assertFalse(bs.get(63)); + assertFalse(bs.get(64)); assertEquals(0, bs.cardinality()); if (singleThreaded) { assertFalse(bs.isRangeSet(63, 65)); diff --git a/src/test/java/net/openhft/chronicle/algo/bitset/FlatBitSetAlgorithmTest.java b/src/test/java/net/openhft/chronicle/algo/bitset/FlatBitSetAlgorithmTest.java index a88a2dbf..970d7990 100644 --- a/src/test/java/net/openhft/chronicle/algo/bitset/FlatBitSetAlgorithmTest.java +++ b/src/test/java/net/openhft/chronicle/algo/bitset/FlatBitSetAlgorithmTest.java @@ -3,10 +3,11 @@ */ package net.openhft.chronicle.algo.bitset; -import junit.framework.TestCase; import org.junit.jupiter.api.Test; -public class FlatBitSetAlgorithmTest extends TestCase { +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class FlatBitSetAlgorithmTest { @Test public void testSizeInBytes() { long logicalSize = 64L; diff --git a/src/test/java/net/openhft/chronicle/algo/bitset/ReusableBitSetTest.java b/src/test/java/net/openhft/chronicle/algo/bitset/ReusableBitSetTest.java index 19630f8a..cd5769f8 100644 --- a/src/test/java/net/openhft/chronicle/algo/bitset/ReusableBitSetTest.java +++ b/src/test/java/net/openhft/chronicle/algo/bitset/ReusableBitSetTest.java @@ -114,9 +114,11 @@ void basicMutationsCoverAllOperations(String name, Supplier facto assertRangeClear(bs, clearedPrevStart, clearedPrevStart + 4); BitSet.Bits bits = bs.setBits().reset(); + int visited = 0; while (bits.next() >= 0) { - // iterate to exercise iterator implementation + visited++; } + assertEquals(bs.cardinality(), visited); bs.setAll(); assertEquals(LOGICAL_SIZE, bs.cardinality()); @@ -130,14 +132,12 @@ private static final class BitSetFixture implements AutoCloseable { private final Access access; private final Object handle; private final BytesStore bytesStore; - private final long offset; - private BitSetFixture(ReusableBitSet bitSet, Access access, Object handle, BytesStore bytesStore, long offset) { + private BitSetFixture(ReusableBitSet bitSet, Access access, Object handle, BytesStore bytesStore) { this.bitSet = bitSet; this.access = access; this.handle = handle; this.bytesStore = bytesStore; - this.offset = offset; } static BitSetFixture singleThreaded(ByteBuffer buffer) { @@ -146,7 +146,7 @@ static BitSetFixture singleThreaded(ByteBuffer buffer) { SingleThreadedFlatBitSetFrame frame = new SingleThreadedFlatBitSetFrame(LOGICAL_SIZE); Access bbAccess = Access.checkedByteBufferAccess(); ReusableBitSet bitSet = new ReusableBitSet(frame, bbAccess, buffer, offset); - return new BitSetFixture(bitSet, bbAccess, buffer, null, offset); + return new BitSetFixture(bitSet, bbAccess, buffer, null); } @SuppressWarnings("unchecked") @@ -157,7 +157,7 @@ static BitSetFixture concurrentStore() { Access storeAccess = Access.checkedBytesStoreAccess(); @SuppressWarnings("rawtypes") ReusableBitSet bitSet = new ReusableBitSet(frame, (Access) storeAccess, store, offset); - return new BitSetFixture(bitSet, storeAccess, store, store, offset); + return new BitSetFixture(bitSet, storeAccess, store, store); } ReusableBitSet bitSet() { diff --git a/src/test/java/net/openhft/chronicle/algo/bytes/AccessTest.java b/src/test/java/net/openhft/chronicle/algo/bytes/AccessTest.java index 4da998bf..31e4ef2e 100644 --- a/src/test/java/net/openhft/chronicle/algo/bytes/AccessTest.java +++ b/src/test/java/net/openhft/chronicle/algo/bytes/AccessTest.java @@ -3,34 +3,26 @@ */ package net.openhft.chronicle.algo.bytes; -import junit.framework.TestCase; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.*; @SuppressWarnings("unchecked") -public class AccessTest extends TestCase { +class AccessTest { private Access access; private Object handle; - private Access sourceAccess; - private Access targetAccess; - private Object source; - private Object target; @BeforeEach - public void setUp() { + void setUp() { access = mock(Access.class); handle = new Object(); - sourceAccess = mock(Access.class); - targetAccess = mock(Access.class); - source = new Object(); - target = new Object(); } @Test - public void testCompareAndSwapInt() { + void testCompareAndSwapInt() { long offset = 0L; int expected = 10; int value = 20; @@ -42,7 +34,7 @@ public void testCompareAndSwapInt() { } @Test - public void testCompareAndSwapLong() { + void testCompareAndSwapLong() { long offset = 0L; long expected = 10L; long value = 20L; diff --git a/src/test/java/net/openhft/chronicle/algo/bytes/AccessUtilitiesTest.java b/src/test/java/net/openhft/chronicle/algo/bytes/AccessUtilitiesTest.java index 6eef9d27..31d3c233 100644 --- a/src/test/java/net/openhft/chronicle/algo/bytes/AccessUtilitiesTest.java +++ b/src/test/java/net/openhft/chronicle/algo/bytes/AccessUtilitiesTest.java @@ -114,12 +114,12 @@ void bytesAccessesFullDelegatesToBytesStore() { BytesStore store = BytesStore.nativeStoreWithFixedCapacity(32); try { @SuppressWarnings("rawtypes") - Full access = (Full) Full.INSTANCE; - assertTrue(access.compareAndSwapInt((BytesStore) store, 0, 0, 42)); + Full access = Full.INSTANCE; + assertTrue(access.compareAndSwapInt(store, 0, 0, 42)); assertEquals(42, store.readInt(0)); - assertTrue(access.compareAndSwapLong((BytesStore) store, 8, 0L, 123L)); + assertTrue(access.compareAndSwapLong(store, 8, 0L, 123L)); assertEquals(123L, store.readLong(8)); - assertEquals(store.byteOrder(), access.byteOrder((BytesStore) store)); + assertEquals(store.byteOrder(), access.byteOrder(store)); } finally { store.releaseLast(); } @@ -132,10 +132,9 @@ void randomDataInputAccessReadsPrimitiveValues() { store.writeLong(0, 0x0102030405060708L); store.writeInt(16, 0x11223344); RandomDataInputAccess access = BytesAccesses.RandomDataInputReadAccessEnum.INSTANCE; - RandomDataInput handle = store; - assertEquals(0x11223344, access.readInt(handle, 16)); - assertEquals(0x0102030405060708L, access.readLong(handle, 0)); - assertEquals(handle.byteOrder(), access.byteOrder(handle)); + assertEquals(0x11223344, access.readInt(store, 16)); + assertEquals(0x0102030405060708L, access.readLong(store, 0)); + assertEquals(store.byteOrder(), access.byteOrder(store)); } finally { store.releaseLast(); } @@ -151,8 +150,8 @@ void arrayAccessorOffsetsScalePerElement() { byte[] bytes = new byte[8]; assertEquals( - ArrayAccessors.Byte.INSTANCE.offset(bytes, 5) - ArrayAccessors.Byte.INSTANCE.offset(bytes, 0), - 5 + 5, + ArrayAccessors.Byte.INSTANCE.offset(bytes, 5) - ArrayAccessors.Byte.INSTANCE.offset(bytes, 0) ); } @@ -161,11 +160,11 @@ void hotSpotStringAccessorExposesBackingStorage() { String sample = "Cafe"; Object handle = CharSequenceAccessor.stringAccessor.handle(sample); if (Jvm.isJava9Plus()) { - assertTrue(handle instanceof byte[]); + assertInstanceOf(byte[].class, handle); byte[] asBytes = (byte[]) handle; assertTrue(asBytes.length >= sample.length()); } else { - assertTrue(handle instanceof char[]); + assertInstanceOf(char[].class, handle); char[] asChars = (char[]) handle; assertEquals(sample.length(), asChars.length); } diff --git a/src/test/java/net/openhft/chronicle/algo/bytes/ByteBufferAccessTest.java b/src/test/java/net/openhft/chronicle/algo/bytes/ByteBufferAccessTest.java index 2e41c9a8..3cc14ba0 100644 --- a/src/test/java/net/openhft/chronicle/algo/bytes/ByteBufferAccessTest.java +++ b/src/test/java/net/openhft/chronicle/algo/bytes/ByteBufferAccessTest.java @@ -3,14 +3,15 @@ */ package net.openhft.chronicle.algo.bytes; -import junit.framework.TestCase; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.nio.ByteBuffer; import java.nio.ByteOrder; -public class ByteBufferAccessTest extends TestCase { +import static org.junit.jupiter.api.Assertions.*; + +public class ByteBufferAccessTest { private ByteBufferAccess access; private ByteBuffer buffer; diff --git a/src/test/java/net/openhft/chronicle/algo/bytes/CharSequenceAccessTest.java b/src/test/java/net/openhft/chronicle/algo/bytes/CharSequenceAccessTest.java index 883dd513..762529f8 100644 --- a/src/test/java/net/openhft/chronicle/algo/bytes/CharSequenceAccessTest.java +++ b/src/test/java/net/openhft/chronicle/algo/bytes/CharSequenceAccessTest.java @@ -3,12 +3,13 @@ */ package net.openhft.chronicle.algo.bytes; -import junit.framework.TestCase; import org.junit.jupiter.api.Test; import java.nio.ByteOrder; -public class CharSequenceAccessTest extends TestCase { +import static org.junit.jupiter.api.Assertions.*; + +public class CharSequenceAccessTest { private static final CharSequence TEST_SEQUENCE = "0123456789ABCDEF"; @Test diff --git a/src/test/java/net/openhft/chronicle/algo/bytes/RandomDataInputAccessTest.java b/src/test/java/net/openhft/chronicle/algo/bytes/RandomDataInputAccessTest.java index f3cff26f..8821496c 100644 --- a/src/test/java/net/openhft/chronicle/algo/bytes/RandomDataInputAccessTest.java +++ b/src/test/java/net/openhft/chronicle/algo/bytes/RandomDataInputAccessTest.java @@ -3,16 +3,16 @@ */ package net.openhft.chronicle.algo.bytes; -import junit.framework.TestCase; import net.openhft.chronicle.bytes.RandomDataInput; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.nio.ByteOrder; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; -public class RandomDataInputAccessTest extends TestCase { +public class RandomDataInputAccessTest { private RandomDataInput mockInput; private RandomDataInputAccess access; diff --git a/src/test/java/net/openhft/chronicle/algo/bytes/RandomDataOutputAccessTest.java b/src/test/java/net/openhft/chronicle/algo/bytes/RandomDataOutputAccessTest.java index 06edcc79..3d0ce6a5 100644 --- a/src/test/java/net/openhft/chronicle/algo/bytes/RandomDataOutputAccessTest.java +++ b/src/test/java/net/openhft/chronicle/algo/bytes/RandomDataOutputAccessTest.java @@ -3,16 +3,16 @@ */ package net.openhft.chronicle.algo.bytes; -import junit.framework.TestCase; import net.openhft.chronicle.bytes.RandomDataOutput; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.nio.ByteOrder; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.*; -public class RandomDataOutputAccessTest extends TestCase { +public class RandomDataOutputAccessTest { private RandomDataOutputImpl mockOutput; private RandomDataOutputAccess access; @@ -110,6 +110,6 @@ public void testByteOrder() { } // Mock class extending RandomDataOutput with self-referential generic type - abstract class RandomDataOutputImpl implements RandomDataOutput { + abstract static class RandomDataOutputImpl implements RandomDataOutput { } -} \ No newline at end of file +} diff --git a/src/test/java/net/openhft/chronicle/algo/bytes/WriteAccessTest.java b/src/test/java/net/openhft/chronicle/algo/bytes/WriteAccessTest.java index 70093fe3..3d18cdf6 100644 --- a/src/test/java/net/openhft/chronicle/algo/bytes/WriteAccessTest.java +++ b/src/test/java/net/openhft/chronicle/algo/bytes/WriteAccessTest.java @@ -9,8 +9,8 @@ import org.junit.jupiter.api.Test; import org.mockito.Mockito; -import static org.junit.Assume.assumeFalse; import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assumptions.assumeFalse; import static org.mockito.Mockito.*; @SuppressWarnings("unchecked") diff --git a/src/test/java/net/openhft/chronicle/algo/hashing/City64MoreTest.java b/src/test/java/net/openhft/chronicle/algo/hashing/City64MoreTest.java index 644658a2..f11b0fcc 100644 --- a/src/test/java/net/openhft/chronicle/algo/hashing/City64MoreTest.java +++ b/src/test/java/net/openhft/chronicle/algo/hashing/City64MoreTest.java @@ -8,7 +8,7 @@ import org.junit.Ignore; import org.junit.Test; -import java.security.SecureRandom; +import java.util.concurrent.ThreadLocalRandom; /** * Created by peter on 28/06/15. @@ -46,8 +46,8 @@ public void testSmallRandomness() { if (t % 50 == 0) System.out.println(t + " - Score: " + score); } - System.out.println("Average score: " + scoreSum / 500); - System.out.printf("Average time %.3f us%n", time / timeCount / 1e3); + System.out.println("Average score: " + (scoreSum / 500.0)); + System.out.printf("Average time %.3f us%n", (time / (double) timeCount) / 1e3); } @Ignore("Long running, avg score = 6852") @@ -59,7 +59,7 @@ public void testRandomness() { long[] hashs = new long[8192]; NativeBytes b = NativeBytes.nativeBytes(hashs.length / 64); byte[] init = new byte[hashs.length / 64]; - new SecureRandom().nextBytes(init); + ThreadLocalRandom.current().nextBytes(init); for (int i = 0; i < hashs.length; i++) { b.clear(); b.write(init); @@ -85,7 +85,7 @@ public void testRandomness() { if (t % 50 == 0) System.out.println(t + " - Score: " + score); } - System.out.println("Average score: " + scoreSum / 500); - System.out.printf("Average time %.3f us%n", time / timeCount / 1e3); + System.out.println("Average score: " + (scoreSum / 500.0)); + System.out.printf("Average time %.3f us%n", (time / (double) timeCount) / 1e3); } } diff --git a/src/test/java/net/openhft/chronicle/algo/hashing/City64_1_1_Test.java b/src/test/java/net/openhft/chronicle/algo/hashing/City64_1_1_Test.java index 7286d400..b379d18d 100644 --- a/src/test/java/net/openhft/chronicle/algo/hashing/City64_1_1_Test.java +++ b/src/test/java/net/openhft/chronicle/algo/hashing/City64_1_1_Test.java @@ -2088,26 +2088,26 @@ public void testCityWithoutSeeds() { } // The following numbers is the result of compiling & running this program -// with city-1.1.1, reference impl: -// -// #include -// #include -// #include -// -// main() { -// char* src = (char*) malloc(1024); -// for (int i = 0; i < 1024; i++) { -// src[i] = (char) i; -// } -// printf("without seeds\n"); -// for (int i = 0; i <= 1024; i++) { -// printf("%lldL,\n", (long long)CityHash64(src, i)); -// } -// printf("with seeds 0, 0\n"); -// for (int i = 0; i <= 1024; i++) { -// printf("%lldL,\n", (long long)CityHash64WithSeeds(src, i, 0, 0)); -// } -// } + // with city-1.1.1, reference impl: + // + // #include + // #include + // #include + // + // main() { + // char* src = (char*) malloc(1024); + // for (int i = 0; i < 1024; i++) { + // src[i] = (char) i; + // } + // printf("without seeds\n"); + // for (int i = 0; i <= 1024; i++) { + // printf("%lldL,\n", (long long)CityHash64(src, i)); + // } + // printf("with seeds 0, 0\n"); + // for (int i = 0; i <= 1024; i++) { + // printf("%lldL,\n", (long long)CityHash64WithSeeds(src, i, 0, 0)); + // } + // } @Test public void testCityWithOneSeed() { test(LongHashFunction.city_1_1(0L, 0L), HASHES_OF_LOOPING_BYTES_WITH_SEEDS_0_0); diff --git a/src/test/java/net/openhft/chronicle/algo/hashing/HashTestSupport.java b/src/test/java/net/openhft/chronicle/algo/hashing/HashTestSupport.java index 782d5a61..c9f53881 100644 --- a/src/test/java/net/openhft/chronicle/algo/hashing/HashTestSupport.java +++ b/src/test/java/net/openhft/chronicle/algo/hashing/HashTestSupport.java @@ -148,8 +148,8 @@ private static void exerciseNegativePrimitiveHashes(LongHashFunction function) { Arrays.fill(bytes, (byte) -1); long byteHash = function.hashBytes(bytes, 0, 1); long shortHash = function.hashBytes(bytes, 0, 2); - long intHash = function.hashBytes(bytes, 0, 4); - long longHash = function.hashBytes(bytes, 0, 8); + final long intHash = function.hashBytes(bytes, 0, 4); + final long longHash = function.hashBytes(bytes, 0, 8); assertEquals("hashByte(-1)", byteHash, function.hashByte((byte) -1)); assertEquals("hashShort(-1)", shortHash, function.hashShort((short) -1)); @@ -227,5 +227,4 @@ private static long[] toLongArray(ByteBuffer buffer, int len) { buffer.duplicate().order(nativeOrder()).asLongBuffer().get(longs); return longs; } - } diff --git a/src/test/java/net/openhft/chronicle/algo/hashing/MurmurHash3MoreTest.java b/src/test/java/net/openhft/chronicle/algo/hashing/MurmurHash3MoreTest.java index 80e433aa..d256e9ed 100644 --- a/src/test/java/net/openhft/chronicle/algo/hashing/MurmurHash3MoreTest.java +++ b/src/test/java/net/openhft/chronicle/algo/hashing/MurmurHash3MoreTest.java @@ -8,7 +8,7 @@ import org.junit.Ignore; import org.junit.Test; -import java.security.SecureRandom; +import java.util.concurrent.ThreadLocalRandom; /** * Created by peter on 28/06/15. @@ -46,8 +46,8 @@ public void testSmallRandomness() { if (t % 50 == 0) System.out.println(t + " - Score: " + score); } - System.out.println("Average score: " + scoreSum / 500); - System.out.printf("Average time %.3f us%n", time / timeCount / 1e3); + System.out.println("Average score: " + (scoreSum / 500.0)); + System.out.printf("Average time %.3f us%n", (time / (double) timeCount) / 1e3); } @Ignore("Long running, avg score = 6836") @@ -59,7 +59,7 @@ public void testRandomness() { long[] hashs = new long[8192]; NativeBytes b = NativeBytes.nativeBytes(hashs.length / 64); byte[] init = new byte[hashs.length / 64]; - new SecureRandom().nextBytes(init); + ThreadLocalRandom.current().nextBytes(init); for (int i = 0; i < hashs.length; i++) { b.clear(); b.write(init); @@ -85,7 +85,7 @@ public void testRandomness() { if (t % 50 == 0) System.out.println(t + " - Score: " + score); } - System.out.println("Average score: " + scoreSum / 500); - System.out.printf("Average time %.3f us%n", time / timeCount / 1e3); + System.out.println("Average score: " + (scoreSum / 500.0)); + System.out.printf("Average time %.3f us%n", (time / (double) timeCount) / 1e3); } } diff --git a/src/test/java/net/openhft/chronicle/algo/hashing/MurmurHash3Test.java b/src/test/java/net/openhft/chronicle/algo/hashing/MurmurHash3Test.java index cb24421c..fe7e8263 100644 --- a/src/test/java/net/openhft/chronicle/algo/hashing/MurmurHash3Test.java +++ b/src/test/java/net/openhft/chronicle/algo/hashing/MurmurHash3Test.java @@ -8,7 +8,7 @@ import org.junit.Test; import java.util.Arrays; -import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; public class MurmurHash3Test { @@ -24,7 +24,7 @@ public void testMurmurWithSeed() { private void testMurmur(LongHashFunction tested, HashFunction referenceFromGuava) { byte[] testData = new byte[1024]; - new Random().nextBytes(testData); + ThreadLocalRandom.current().nextBytes(testData); for (int i = 0; i < testData.length; i++) { byte[] data = Arrays.copyOf(testData, i); LongHashFunctionTest.test(tested, data, referenceFromGuava.hashBytes(data).asLong()); diff --git a/src/test/java/net/openhft/chronicle/algo/hashing/XxHash_r39_Test.java b/src/test/java/net/openhft/chronicle/algo/hashing/XxHash_r39_Test.java index 448e6a29..a48d784b 100644 --- a/src/test/java/net/openhft/chronicle/algo/hashing/XxHash_r39_Test.java +++ b/src/test/java/net/openhft/chronicle/algo/hashing/XxHash_r39_Test.java @@ -9,6 +9,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.List; @RunWith(Parameterized.class) public class XxHash_r39_Test { @@ -18,8 +19,8 @@ public class XxHash_r39_Test { * from https://code.google.com/p/xxhash/ *

* #include "xxhash.c" - * #include - * #include + * #include <stdlib.h> + * #include <stdio.h> * int main() * { * char* src = (char*) malloc(1024); @@ -2098,7 +2099,7 @@ public class XxHash_r39_Test { @Parameterized.Parameters public static Collection data() { - ArrayList data = new ArrayList(); + List data = new ArrayList<>(); for (int len = 0; len < 1025; len++) { data.add(new Object[]{len}); } diff --git a/src/test/java/net/openhft/chronicle/algo/locks/LockingStrategyTest.java b/src/test/java/net/openhft/chronicle/algo/locks/LockingStrategyTest.java index 47497750..ccd137ff 100644 --- a/src/test/java/net/openhft/chronicle/algo/locks/LockingStrategyTest.java +++ b/src/test/java/net/openhft/chronicle/algo/locks/LockingStrategyTest.java @@ -179,7 +179,7 @@ public void testUpdateLockUpgradeToWriteLock() throws ExecutionException, Interr assertTrue(e1.submit(() -> rwuls().tryUpgradeUpdateToWriteLock()).get()); // Release the write lock in thread 1... - e1.submit(() -> rwuls().downgradeWriteToUpdateLock()); + e1.submit(() -> rwuls().downgradeWriteToUpdateLock()).get(); // Release the update lock in thread 1... e1.submit(updateUnlockTask).get(); @@ -211,7 +211,7 @@ public void testReadWriteLockTransitions() { rwls().readUnlock(); assertTrue(rwls().tryWriteLock()); } -// write lock is held + // write lock is held readUnlockForbidden(); upgradeReadToWriteLockForbidden(); diff --git a/src/test/java/net/openhft/chronicle/algo/locks/VanillaReadWriteUpdateWithWaitsLockingStrategyTest.java b/src/test/java/net/openhft/chronicle/algo/locks/VanillaReadWriteUpdateWithWaitsLockingStrategyTest.java index 4cbaaeac..4eb9e126 100644 --- a/src/test/java/net/openhft/chronicle/algo/locks/VanillaReadWriteUpdateWithWaitsLockingStrategyTest.java +++ b/src/test/java/net/openhft/chronicle/algo/locks/VanillaReadWriteUpdateWithWaitsLockingStrategyTest.java @@ -95,8 +95,7 @@ void testCheckWaitWordForIncrement() { int waitWord = MAX_WAIT - 1; assertDoesNotThrow(() -> checkWaitWordForIncrement(waitWord)); - int maxWaitWord = MAX_WAIT; - assertThrows(IllegalMonitorStateException.class, () -> checkWaitWordForIncrement(maxWaitWord)); + assertThrows(IllegalMonitorStateException.class, () -> checkWaitWordForIncrement(MAX_WAIT)); } @Test @@ -122,8 +121,7 @@ void testTryWriteLockAndDeregisterWait0() { @Test void testCheckExclusiveUpdateLocked() { - int countWord = UPDATE_PARTY; - assertTrue(checkExclusiveUpdateLocked(countWord)); + assertTrue(checkExclusiveUpdateLocked(UPDATE_PARTY)); int nonExclusiveUpdateCountWord = UPDATE_PARTY + 1; assertFalse(checkExclusiveUpdateLocked(nonExclusiveUpdateCountWord)); @@ -225,5 +223,4 @@ void testSizeInBytes() { int expectedSize = 8; assertEquals(expectedSize, strategy.sizeInBytes()); } - } diff --git a/src/test/java/net/openhft/chronicle/algo/locks/VanillaReadWriteWithWaitsLockingStrategyTest.java b/src/test/java/net/openhft/chronicle/algo/locks/VanillaReadWriteWithWaitsLockingStrategyTest.java index 9fed8e5b..a9d9ca1f 100644 --- a/src/test/java/net/openhft/chronicle/algo/locks/VanillaReadWriteWithWaitsLockingStrategyTest.java +++ b/src/test/java/net/openhft/chronicle/algo/locks/VanillaReadWriteWithWaitsLockingStrategyTest.java @@ -4,7 +4,6 @@ package net.openhft.chronicle.algo.locks; import net.openhft.chronicle.algo.bytes.Access; -import net.openhft.chronicle.algo.bytes.ReadAccess; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -15,14 +14,12 @@ class VanillaReadWriteWithWaitsLockingStrategyTest { private Access access; - private ReadAccess readAccess; private Object handle; private ReadWriteWithWaitsLockingStrategy strategy; @BeforeEach void setUp() { access = mock(Access.class); - readAccess = mock(ReadAccess.class); handle = new Object(); strategy = VanillaReadWriteWithWaitsLockingStrategy.instance(); } diff --git a/src/test/java/net/openhft/chronicle/map/locks/ChronicleStampedLockTest.java b/src/test/java/net/openhft/chronicle/map/locks/ChronicleStampedLockTest.java index 764b673b..30a2c11b 100644 --- a/src/test/java/net/openhft/chronicle/map/locks/ChronicleStampedLockTest.java +++ b/src/test/java/net/openhft/chronicle/map/locks/ChronicleStampedLockTest.java @@ -6,8 +6,6 @@ import org.junit.Assert; import org.junit.Test; -//import static org.junit.jupiter.api.Assertions.*; - public class ChronicleStampedLockTest { @Test diff --git a/src/test/resources/net/openhft/chronicle/algo/hashing/reference/City64_1_1_Test.java b/src/test/resources/net/openhft/chronicle/algo/hashing/reference/City64_1_1_Test.java new file mode 100644 index 00000000..73654f38 --- /dev/null +++ b/src/test/resources/net/openhft/chronicle/algo/hashing/reference/City64_1_1_Test.java @@ -0,0 +1,2126 @@ +/* + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 + */ +package net.openhft.hashing; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.util.ArrayList; +import java.util.Collection; + +import static org.junit.runners.Parameterized.Parameter; +import static org.junit.runners.Parameterized.Parameters; + +@RunWith(Parameterized.class) +public class City64_1_1_Test { + + @Parameters + public static Collection data() { + ArrayList data = new ArrayList(); + for (int len = 0; len < 1025; len++) { + data.add(new Object[] {len}); + } + return data; + } + + @Parameter + public int len; + + @Test + public void testCityWithoutSeeds() { + test(LongHashFunction.city_1_1(), HASHES_OF_LOOPING_BYTES_WITHOUT_SEEDS); + } + + @Test + public void testCityWithOneSeed() { + test(LongHashFunction.city_1_1(0L, 0L), HASHES_OF_LOOPING_BYTES_WITH_SEEDS_0_0); + } + + private void test(LongHashFunction city, long[] hashesOfLoopingBytes) { + byte[] data = new byte[len]; + for (int j = 0; j < data.length; j++) { + data[j] = (byte) j; + } + LongHashFunctionTest.test(city, data, hashesOfLoopingBytes[len]); + } + +// The following numbers is the result of compiling & running this program +// with city-1.1.1, reference impl: +// +// #include +// #include +// #include +// +// main() { +// char* src = (char*) malloc(1024); +// for (int i = 0; i < 1024; i++) { +// src[i] = (char) i; +// } +// printf("without seeds\n"); +// for (int i = 0; i <= 1024; i++) { +// printf("%lldL,\n", (long long)CityHash64(src, i)); +// } +// printf("with seeds 0, 0\n"); +// for (int i = 0; i <= 1024; i++) { +// printf("%lldL,\n", (long long)CityHash64WithSeeds(src, i, 0, 0)); +// } +// } + + private static final long[] HASHES_OF_LOOPING_BYTES_WITHOUT_SEEDS = { + -7286425919675154353L, + -4728684028706075820L, + -4422457430495752843L, + -7736835464683084646L, + -9025216361070533312L, + -5422428610433466039L, + -7854914535251369165L, + -6710152398449367391L, + -5955425696247891048L, + -9135800243314829233L, + -7246206370539175958L, + -927412511068636451L, + -6929387038567547523L, + -4483949857698136942L, + 5465584872023869041L, + -8779115096593678947L, + 1080060857502750420L, + -4920561954712641764L, + 8788987475711186918L, + -7811586469569372367L, + -8225851168889855767L, + -1446326939218740700L, + 2947276334089957408L, + 460179928224693724L, + 4556289589497654983L, + -5431404645194118082L, + 1374684061788708333L, + 4791352535680686582L, + -6530211739313377370L, + -7635818062080712801L, + 5236473510478810791L, + -299119187023926975L, + 1917831512995979081L, + 5107424530006203066L, + -5351750064093194974L, + 2946934858665984768L, + 5031111514403073L, + 3910662880520648515L, + 7104787927248062489L, + -6487722535395806461L, + 3960877915061173532L, + -4579031603096916569L, + -3869369943781850205L, + 5545493761745899838L, + -7059462733818922495L, + 6807020698875987225L, + -404529411533207610L, + -5190881841756839606L, + -4104575122654935515L, + 6967381383547484689L, + 8297988497614279881L, + 8680592459788761385L, + -3059691078085565528L, + -6315132929596828281L, + -4334276152181959987L, + -535710436645363679L, + -7591547014909512897L, + -6322657031286798644L, + 7490021577199580942L, + -8877856250499437898L, + -1633403071681209495L, + -5579376360386761981L, + 3395840816824425443L, + -5822993263498516753L, + -1613775140304724827L, + -6027895920215728850L, + -5805352503949881486L, + 1532677441468290047L, + -8648407032749049966L, + -2939164377159033571L, + -4702680364495832252L, + 105631500981943270L, + -7893756812661322999L, + 5760642662739372587L, + -6215695861042047454L, + 1238201813735746316L, + -4809334409104512081L, + 2347957779168721077L, + 9062861991168352058L, + 6741188021946160720L, + 5759783405795756054L, + -7404571833801891275L, + 5236586458250640726L, + -6440402695065204540L, + 7127501107294950542L, + -8740931757300170334L, + 5534676620576843972L, + -4574941845361945294L, + -9883751627416689L, + 7607362424232991178L, + -3354796234778573261L, + -3645150900513625504L, + -6488903739323758581L, + 6012082827380234497L, + -5054558154612698247L, + 3912192630192643044L, + -2020201547348302146L, + -5668877223161468438L, + 8268442247828559279L, + -5794570113714942465L, + -6593295974839137082L, + -3017674363433867291L, + 9132819821668885553L, + 4741264366937614131L, + 830814054897026754L, + -2034640718262093716L, + 8943931193848644945L, + -8152524248109219563L, + -6859491045979443967L, + 5989638100417143996L, + -3267834036936991810L, + -7636942225548479235L, + -4414857242429251885L, + -2291796691719558349L, + -443263958430047225L, + 7365713933907296010L, + -3873163659277696512L, + 3210434025964027265L, + 4488179162024237572L, + -4930451962295763338L, + 7001793786790109268L, + 2260583935679101347L, + 6302158474829298170L, + -2419988900997440242L, + -8014717202309677597L, + -8235679274201152527L, + -5412354269470908685L, + -1164721218407162475L, + 1202834260335129493L, + 5097669210588415856L, + 5123804704029457567L, + -6598196598389898964L, + -6869069910041547416L, + -928355525786123860L, + -966564912375064896L, + 4636972776252349972L, + -2242946385954433108L, + -2308096272056919881L, + -6298993315544438985L, + -3151578775439575412L, + -2981346332242477399L, + 6868228731909122983L, + -6986102546523057772L, + 3966488015587306733L, + -7964296030132213922L, + -5968054086424703428L, + -5682984903553203201L, + 1262045945453884357L, + -8506021221334832979L, + 7003579340962719964L, + 7942843347128085593L, + 3274150487722006282L, + 4427242625667076769L, + -5558614835558052533L, + 8189732125765662222L, + -2778584257768737506L, + -6226635033105800171L, + 7651720467242209474L, + 9181931113760444130L, + 2531900585268751432L, + 5021256001343290469L, + -5934384589108485717L, + -1862924803786167203L, + 1489099108801110675L, + 7297283605813218793L, + -8415280978394092215L, + -4126156388588540951L, + -3706737886726786804L, + -2710208030451980715L, + -8047451206915723423L, + -1218572947384892459L, + 8297865478600584233L, + 8165902466320925460L, + 5554419482037121102L, + 4417403317404803986L, + -6616982450866646170L, + -7959099281697237016L, + -3114405717510473052L, + -1857505830677138154L, + -1018685550688766348L, + 5207428187340024429L, + 5300227297807876147L, + -2390037343420204123L, + -448127685853213712L, + -6225388303620718856L, + 2389000856964185630L, + -2067625213238325040L, + -241429434055336511L, + -8970491894816477388L, + -6897203400744644612L, + -4604959413085934526L, + 2400135546673933001L, + -3045961230403678092L, + -1917277105023051478L, + 8197811581050490133L, + 3786786968548875789L, + 4625663088087573665L, + -2168704627193825976L, + 7192692656796588680L, + 2481695319570886548L, + -805495018187668520L, + 5671304642231997436L, + -4228301512035074347L, + -7701083686405511339L, + -1427738904980858657L, + 8356642386295377804L, + -353719534132831289L, + 706229336943583572L, + -9168064130899442751L, + 8265029971140615336L, + -2707147319767299550L, + 7353033265757382049L, + 8397636325397273152L, + -6517736165712294631L, + 6949546038097145245L, + 1648771344345529694L, + 6558709565158356186L, + 1808377088858220390L, + 2838565433860722913L, + 1308279908036033190L, + 8824692270735996388L, + 4066525655875567756L, + 5152272828145679687L, + -3469524600427842330L, + 188800643931297464L, + 7173304178017026190L, + -5347641926849324594L, + -8829553366459830305L, + 8778291414581187896L, + 593871733331593377L, + 2192404833132388154L, + -3564506003420601160L, + 2859700462125450624L, + -7123068915788342214L, + -9199725509076335326L, + 4749263509373213952L, + -3638383731952186227L, + -6283092296877861618L, + -2825268767310280965L, + 7643742019486170884L, + 7034401305567905177L, + -31827767771004462L, + -3569709783922447606L, + 1011781009512126791L, + -5982832679535324039L, + 2402494289382923228L, + 5378572830995800063L, + -4978012351095471455L, + -3034756850229693434L, + -6743229956355567041L, + -1028117510121450274L, + -1267497062066519287L, + -5053670629173080711L, + -460732196015338926L, + -6371275689446166637L, + 6288834997689259448L, + 894299094737143437L, + -6014774806034970825L, + -3271595897687689742L, + -7449732170732070004L, + 506523418677247916L, + -687365991489907728L, + 8228603339396783688L, + 7211450665110285461L, + -3009830902792319569L, + -5417937957852652579L, + 6051039017008413932L, + -5925978207158526805L, + -2615140071349844608L, + -8654933370440320601L, + -6342253313262031587L, + 4461643906497668150L, + -819522441838551231L, + -1359425915347178296L, + 1075135447892840058L, + 7643058122247322338L, + -4070529264423045602L, + 6335201156325848872L, + 4776486447069195757L, + -4254562051076226566L, + 5766929006988848669L, + -884034037937901831L, + 1766456663364676290L, + -4311719146183820266L, + 7666581505151857266L, + 671421170492658629L, + -1964099404051832475L, + 1732360456059290553L, + -297869400412879955L, + -9030316701971057409L, + -9075660047343779046L, + 3583673289738670454L, + -9182941546024088613L, + 1136735461790749536L, + 8366765554392407195L, + -5540891596657836355L, + -7821100180551973617L, + -1977279128251662041L, + -2356171669808568513L, + -2015573691705664756L, + 4488487306883615842L, + 4851354791727756109L, + -3251092166327359481L, + -601646434326145067L, + 776101951221215280L, + -6668237828878985553L, + 7844860178588967334L, + 64341060285013340L, + 7036395122924142569L, + -7724784063616999535L, + 2914805329168628994L, + 7621906733182421570L, + 2118815299569935033L, + -8611860394051996699L, + -2517166550051884828L, + -6993083065762083347L, + 2404060287424189503L, + -8081836069740145167L, + -6067471269374793929L, + 3439258482592575547L, + -6466818119401182672L, + 1855293097271252452L, + -6761456087842467624L, + 6656763620585181420L, + -4645642491601388295L, + -8829570488301084514L, + -6279091021271619556L, + -1913500423661250093L, + -8293385927741834686L, + -808977409753631920L, + -2730813255791690623L, + 760899304567634337L, + 3447062143237006129L, + -8842923486609316688L, + -1505518261280441404L, + -8952792346352363916L, + -3654437654855386526L, + -8894745855055459645L, + 253433424322101103L, + 9087982386284623409L, + 5229689677888986164L, + 7591231218923024443L, + -6553455979736582189L, + -6817900072998950224L, + 1012237197570815938L, + -1041501749233381438L, + 6870652863042402620L, + 7290269702536111943L, + -2011669460814939543L, + -4739132450972235476L, + 6066906978691731285L, + 1546459970278232517L, + 7264475946711979454L, + -6827279988316999463L, + 6948666464698968123L, + 5066099854277588391L, + 3617923505625432817L, + 1470423865947425164L, + -2407848614631507329L, + -2721518777381923816L, + -8523365410901703222L, + 4677154254765168702L, + -3770388132335360433L, + 2921549272211529780L, + -675990637368864946L, + 851813270104783927L, + 1645312556841013286L, + 7927523946826503527L, + 2802530705554935060L, + 4420122776914984561L, + 5168061431322460870L, + -3637982376709290280L, + -4792218222117838791L, + -1594804027447799011L, + 7019536217023665362L, + 5718841507582027847L, + 1100038721024625254L, + 4344644567377313784L, + 8200393826966791959L, + 8894425291364977602L, + 2359988989741956746L, + 33375660597707981L, + 3669152498936403685L, + -2718673953441374568L, + 92663594252170279L, + -4255839685607808051L, + -712976418504655651L, + 4188336312392147780L, + 2678387573955385138L, + 5321904963044271153L, + -6249628719291181094L, + -8876650223107687355L, + 8352423161613591273L, + -2028799093461825949L, + 9011909818387084247L, + -5940434430375305675L, + 3490020360211624506L, + 8424335559697179192L, + 3222699924556192045L, + 7964158943145881894L, + 330499497334085755L, + 8764983981643618893L, + -1653480401860466428L, + -1353880172593700164L, + -6469256613830029852L, + -4893038789738483635L, + 8164190368596497481L, + 5278453078131476326L, + 910888251237419688L, + 3697943209022914547L, + 5449624560010431329L, + -3584621013753301872L, + 654189080535454533L, + -7562028051554401340L, + 8924718183483314324L, + -1485127518392421693L, + 3918745837987619627L, + -4539406462388765487L, + 5483323815514497307L, + 6306137176139938292L, + -807721373860280201L, + -9165053290624784358L, + 2697602178198341027L, + 4348395670472375164L, + -400178961926803853L, + -7689451542459549880L, + 4509866787834747782L, + 9185710136408363969L, + 7923865403849230565L, + -5869104529577485293L, + 4854955700697037319L, + 9191216701481807090L, + -679449825281621614L, + -3189846996545570031L, + -8083169535868277187L, + -9174257325298378624L, + -4552176765196275L, + 1628631992923682209L, + 8319654855481955340L, + 8861739932800214810L, + -993117140134665724L, + -7815627532394322917L, + -5524260825536443502L, + 6983369624720592264L, + 2975165537865741602L, + 1451865941470664872L, + 8661262499023857011L, + 9204748273209932460L, + -5006258975566865529L, + -1964973191525498109L, + -6345850612890808987L, + 6330350968582806446L, + -4566626859227178484L, + 4080473761572400112L, + -6346529945189783184L, + 7055723585952818695L, + 7811169230131832954L, + -7306057383456388215L, + 5652715072883610701L, + -2250631360270905098L, + 8948341566778589071L, + -7814352745627737399L, + -2083093040021743435L, + -4144374577642832518L, + 4554659244267885692L, + -4805527992091411974L, + 3879386590110957199L, + -7095733810311131713L, + 4218157720399299286L, + -3959329580238802474L, + 1731201417108224317L, + -8732695545326287246L, + -8127721874141088173L, + 2847953048942004818L, + -2848770956679986940L, + 1154351656441528122L, + 4106410957236720378L, + 477496151948916105L, + 8872899165245904476L, + 3834365941712504069L, + 8233875208097499501L, + 6544005900573385217L, + 371511961864400977L, + 5302630743605424838L, + 7619059416641067912L, + 938163523491488924L, + -2193498991179441780L, + -4381948476662408917L, + 2437161357208041044L, + -1853214813114072629L, + 4032256607594450812L, + -4569645391300269034L, + 996805768016039863L, + -5352653220786799159L, + -4072867815316954984L, + 5829678081429819442L, + 5854970045203806958L, + 7196705546676684298L, + 8855821442059151758L, + 1691257326941530873L, + 516443419472701223L, + -189326359229885042L, + -7069256705822756785L, + 8484184957260042276L, + 4751495376086537417L, + -3538622506527375158L, + -1130604628135516641L, + -662884267626379918L, + -1626547571415880505L, + 4362310446718468471L, + -4692137164995780722L, + -1878686192989058772L, + -1262801893323802033L, + 316850896103923056L, + -8337266500312820398L, + -7607930981261565972L, + -7606942324380249703L, + -1863279537410737853L, + 515589381621691011L, + 1963273998306328480L, + 3626876516104382454L, + -4734613701579936168L, + 1268078677159514015L, + -7562820495728610458L, + -5881301520585529952L, + 7263589689395116216L, + 3332748335049164596L, + -928492619425385303L, + -8439668591687876707L, + 6057690584855876482L, + 7709510645357107021L, + 688216636303161488L, + 191126336719796113L, + 4222857931985709754L, + 5163370007345445271L, + -6942747002185630386L, + -2732326623400822979L, + 41325922645173190L, + 4083911336538913161L, + 3094117323938386883L, + 3557206941692843782L, + -2802805090114871259L, + -396752131642527880L, + -3107705530439472535L, + 8070257791496704758L, + 5555978803158201323L, + 4409520550497292548L, + 6336286888800178635L, + 3317356027694838288L, + 2401575734406277533L, + -7762952901621766636L, + -8495556902666486415L, + -6098553262029734092L, + 364791930541331805L, + -3034434066885855765L, + 7941447497229394663L, + -6311456469393535820L, + -3224469377911062967L, + 8110978943348454528L, + 7644406205313833523L, + 8931656291415416874L, + 4830016430262424325L, + -8438474386071045565L, + 6477831547342095051L, + 3795147179128460013L, + 2753065962007277619L, + 6069828580914843210L, + -5070382024314025872L, + 1576707579300544287L, + 5453704031214058740L, + -1035262976071773160L, + 3387395655425490542L, + -4848984716268304731L, + 8616838443866781524L, + -3948140786885003158L, + 3962330984502924344L, + -3394110440125760919L, + 8437322113039475260L, + -4462275713722410457L, + -9105148434050568503L, + -5788212949545869877L, + 4557608001681875598L, + -621234956095881342L, + 1797543657423762991L, + 6130226975770239840L, + -6937918406956986622L, + 4193803048882394276L, + 4324662453655033332L, + 3904929732026970589L, + -5512830190293331704L, + -5238129213566557209L, + 540373761178912749L, + 3337453168137959715L, + 8356242320057396388L, + -4507786512266822044L, + -698048955859231008L, + 1181416669291835619L, + 3643161574413908044L, + -4297980572116458092L, + -2910009689167799889L, + -9219400384203405648L, + 2837257119074162583L, + -8143475796343843303L, + -6701262784428931798L, + -3566846192190811525L, + -5826064075185101904L, + 7314616728107169430L, + -7237382661205518959L, + 6614127174385956622L, + 4579105225630387051L, + -4031772022249101869L, + -3620132425485383754L, + -6583523957977840094L, + 6091510613049819644L, + -6657436664451253776L, + 8818554346883882723L, + 1172158546676437076L, + 2582843905454312864L, + -875396097026320083L, + -8848203911887421254L, + 6216447546397552656L, + 5663680539561409764L, + 209883782871623112L, + 6956397065493936061L, + -5822486364606447659L, + -2376186988282686016L, + -6524574392506270574L, + -5270703630108479361L, + 5121019866792000912L, + 945935884404515280L, + -3784584736823369966L, + -2986471018582996853L, + -3856234881587215840L, + 6305579424806652269L, + -4601892864817094249L, + -4715544044948588160L, + -1178634098444085344L, + -4565928887270776879L, + 3733099898005319061L, + 6069592779991791222L, + 9107963518416746035L, + 6039316923758014718L, + 8297782059544644167L, + -2184105415491254451L, + 2001634139595818848L, + 9198267247175603385L, + -971507504085650973L, + 1529684592715776773L, + -6499571738329764748L, + 2692794621907637848L, + 3620078955080706311L, + -3810905539411016286L, + -4315538097904969971L, + 238288165777703356L, + 3801607999515704624L, + -8796282819004971627L, + -7143692292464130110L, + -2163491158557034519L, + -9011885533150911632L, + 9155112387717094928L, + 9088915215752483036L, + -1237520018892636128L, + -6753599194173607835L, + 336577035174699985L, + 4747700477808735060L, + 931844140272524176L, + -4257344590201194145L, + -670422981995636407L, + 2500401999619637609L, + 7406487034015272912L, + -384292968442149342L, + -7987787036136248263L, + -2653231840350927715L, + 4488358012056331513L, + 4132004061554806745L, + 2000006126034333275L, + 2367660688967266790L, + -4085353431072751340L, + -6333747719369049272L, + -4139886406965236122L, + -5592180402897144267L, + 5629551944241090329L, + 2272991263231641145L, + -5168344584178448710L, + 5982172003825524793L, + -4097896509839310227L, + -2173000713225115918L, + 7108547918299652551L, + -8878799355822473463L, + -6248630805665498946L, + 5163839098786800196L, + 5795734275921137263L, + -7245153276785179186L, + -7094809303783005595L, + -1803470859826091831L, + 4874431305017870420L, + -8839194352522271777L, + 4701999825563368375L, + -3679426707168942163L, + 4734328664805795607L, + -768556148270379847L, + 3947269125893368179L, + 4714950126806030589L, + -5247268458767477724L, + -1879729542263864540L, + 1641255074942093290L, + -9116204329902429525L, + -364742432814767105L, + -69357515456246742L, + 8333855547662608034L, + 1864002674034900754L, + 6403905632971416781L, + -7065616950334616275L, + -8174670288470068397L, + -1788643243994894927L, + 2040528535819048731L, + -7614591261684631428L, + -8476219755505693753L, + 3296595282811904830L, + -4038686171536252708L, + -173444937930635352L, + 4379378816273396403L, + -1083617946856135532L, + 2829396743633429008L, + 7647167960435994992L, + -6693126224881188257L, + 3108807460115157477L, + 8562491110202112769L, + -7424963641864880746L, + 2081921398431501385L, + 5209400744054399273L, + 5112090417850934870L, + 1524655582665697947L, + -5843275962356379462L, + -6334239724025378211L, + -7268154201988435641L, + 1659668141032724392L, + 7389323132785440806L, + 5590854007476007348L, + 5302894709895800109L, + 8939357616797202357L, + 8822514621675961012L, + -5171376528302818295L, + 1884135603723970677L, + 1618024292298833293L, + -1237011265202015266L, + -8040883111734337726L, + -5506883502078400727L, + -5535461054765222007L, + 6987425158845534706L, + -5917819605734669552L, + -128823547864917643L, + 2306699256825946343L, + 6578043582810501418L, + 1333071240688068841L, + -844978627973023134L, + 1165513423049959936L, + -3821092351522083096L, + 4178119893083594287L, + -7966305568215876834L, + -3090958372925773111L, + 6379864721688110803L, + 8454365886776707192L, + 7642874047594127629L, + -657318587403536924L, + 3801960633076006868L, + 1417228866369858393L, + -6177293427545629057L, + -4532758952191612784L, + 7264967871106174537L, + -4377935371893251778L, + -5733943093645858937L, + -6680841553969427023L, + -7726067291839077718L, + 8383662776008964734L, + -1112744575338004890L, + 6374190320986843773L, + -8999217966784745583L, + -7597176706996915696L, + -1016011267603323245L, + -8855672237269976658L, + 1866081428501204101L, + -5633137211449093941L, + -3633923734370033552L, + 6356569017217682507L, + 5058160257775482340L, + -7437707824467063063L, + 7650351067322618291L, + -7870694419219039600L, + 1007692631473636679L, + -6154343863836713521L, + 2504745592130278975L, + 88486550721415362L, + -7438916213215366445L, + 2983976134777543021L, + -4146088135092960461L, + 6999580209156770608L, + -7009740189170395954L, + 4126839178241879770L, + 5225682274323639211L, + 4660353570181491047L, + -3242111597353447920L, + 1803242034579090657L, + 8094113187590542457L, + 7111382607287164209L, + 3662908704051040727L, + -3379205925121269346L, + 6747462450220404315L, + 65992546736538642L, + 8188714708026451259L, + 7059032778575684879L, + -4375005614825264977L, + -6109413170920934528L, + 4325812979374770173L, + 6190341203443080272L, + 3806377003483660789L, + 7584471990548161252L, + -3767546025951476771L, + 5011498119849592471L, + 4585280751135869910L, + -2774285440269761924L, + -2219523968621249741L, + -6788014939853324942L, + -6760697001786001699L, + -1907834706280913583L, + 2768880461784823049L, + -629361951557696226L, + -5050911681363224361L, + -9166005476966639742L, + 31804289095347444L, + 639074948574684643L, + 6010055855691161228L, + -6702617244872776165L, + 4147599647636813218L, + 7651401543024655900L, + 4739867532288311604L, + -7311026522201000188L, + -2481600927193112363L, + -4295248724569156530L, + 5040986942772410406L, + 8763074685442978007L, + -7780650549244157320L, + 4727619369834180192L, + 8711570616947608575L, + 2722322146515041536L, + 5060226879657446005L, + -6544404061220128813L, + 6434919141259253970L, + -5427874400580062812L, + -7156085410253767250L, + -6601841961191942213L, + -9147266855024119868L, + -354433397501853706L, + -6814497327235846905L, + -8982035476653972472L, + 8930700532836854232L, + -1726278544235169634L, + 1951478969618711815L, + 851982242210611420L, + -6990203687021297279L, + 1368571238713408667L, + 2986039481571029352L, + -626535432523998987L, + 4415114859836957989L, + -8678134461890671357L, + -6061358215352047476L, + 7915140762335918295L, + -8378664661437708973L, + -3058127489434967617L, + 6225893737093916241L, + -1787758126471351031L, + -393755980982643891L, + -5268722683029966701L, + 4156689635576901740L, + 7365991146882099857L, + 8946946338475364603L, + 7319960897807520998L, + -2393576873586390100L, + 8152201155239646390L, + 115383870797338026L, + -7773145637941940242L, + -318186749599182520L, + 3089445632531235737L, + 7372359700832992279L, + -684419690766751897L, + 8663412456358708908L, + -8423162022518559117L, + -8645640258213218521L, + 3755512748576611566L, + -3913197578066841395L, + 5316673743969283163L, + 6831695766395531003L, + -8386643932900364475L, + 2245144203632789924L, + 5811854679522258384L, + -3767061474776765896L, + 5961692927981326209L, + -8247190832034282434L, + -2778260837579024711L, + -5629023501990762250L, + 8537394932332054145L, + -6062925171595331986L, + 6840408648564451314L, + 6831505181423122970L, + 6050924032963061444L, + 97002770831342714L, + -5440958264654316884L, + -8531281358297662856L, + -5585494473146494361L, + -8316232109598521210L, + -5015449123380194340L, + 546734480177265602L, + 4311680116951854912L, + -5000334068336613611L, + 5095429433761178592L, + -8984703830265496675L, + -1796164578353805109L, + -7862084290604723254L, + -3341202509537190675L, + -2120175014098274861L, + 6962378115816372563L, + 8337372275175376334L, + 2619274369511557562L, + -6859437991409806193L, + -6934562751052811686L, + -361162941396148816L, + 3477913128345375098L, + 6500092632270742214L, + -7787173285733693207L, + 1702735166445523176L, + 1447314647588646838L, + -6166213076072914876L, + 8250474851845160242L, + 3877968303074149070L, + 72258823402464273L, + -7794958806496084829L, + 582313431235093783L, + 5654370140388242557L, + 2361322084587394780L, + 7098843402525243411L, + 3090863845420947690L, + 9095251832683567577L, + 7351973108085879975L, + -5523854289062931886L, + 1385990973911762672L, + -1056696196230341112L, + -4777822501121417674L, + 7453925677222043959L, + 4245544569709356516L, + 4912957528661637311L, + -7303723525646889588L, + 8383839844005204972L, + 2636108895426426864L, + 7446083165659408850L, + -1230331481495042331L, + 2165552178018697300L, + 8589713469255323753L, + -104035337559208181L, + 9109517341871300972L, + -5557606019056305482L, + -2082770932342226712L, + -7664170423633849264L, + -6739763730657282594L, + 4217727556012572028L, + -4230549046719159326L, + -7870215613010795436L, + -1573598371112622115L, + 8374003956860023067L, + -4162778827118794697L, + -4999879893029494430L, + -5470698342693924491L, + -524838860730151022L, + 2056390379798965398L, + -7635140489953799830L, + -4895934908017276310L, + -8494320702432460395L, + 4375244527171869608L, + 5749214457757073666L, + 4541994463651552366L, + 4448135749491527723L, + 3252319268873763159L, + -4937698705299440219L, + -1443238972529269463L, + 5690643651433470600L, + -9020999177617872107L, + 5216703363076035920L, + 8692072066293807690L, + -2202944082561610978L, + -3202058202844418274L, + 9199667660131659024L, + -7208718625219556439L, + -8188854117697466457L, + 6229032659379082713L, + 6056662700481738610L, + -2741651824312128388L, + -5770752964459016300L, + -6200251094809993544L, + -8462183157391465625L, + 1991684432526984227L, + 7539287820084627776L, + 2339478854158321950L, + 6202507390678485586L, + 7743951748128383694L, + 4168070312184911657L, + 8672082835392561991L, + 6896073963991207358L, + 1101380276289164762L, + 6605809935833891247L, + -438522298677572710L, + 3905054981608874906L, + -1747754391336276367L, + 1032773222913269798L, + 6843327699919057660L, + -8003124643992369023L, + -631503341286938581L, + 4129740207606678749L, + -1702072036006461106L, + 7744011005333910111L, + -6885964098355695662L, + 6294542643192709825L, + -7426983010848522334L, + -2954466992510897276L, + -7979800600032271131L, + -8655210458445057123L, + -7169091905545403953L, + }; + + private static final long[] HASHES_OF_LOOPING_BYTES_WITH_SEEDS_0_0 = new long[]{ + 6665653827947065942L, + -5789604048565922719L, + -3544073118936500090L, + -2677072096376561857L, + 8974148226120660824L, + -4749991284220333463L, + 8297039314422555359L, + -8088911438875509914L, + 3424528861645039236L, + -421993933668452455L, + -3091699041169951528L, + 1163501013095869222L, + -1554311774836581326L, + 4121966646419608524L, + -5821497637003820218L, + -4128235463417739287L, + 1634251901919194052L, + -9040019856632616077L, + 1183275435239077349L, + -6101391766615068007L, + -3755326226698648655L, + 1818343754347462935L, + -6462354084044314322L, + -814980520133498484L, + 1615579219767298748L, + -6066678408453320652L, + -5834994416669600405L, + 6932484884661269235L, + -7738687275954138493L, + -445315170800868989L, + 6203156606326072466L, + -8944279252978819749L, + 5060297072545920013L, + -3956343463993130235L, + -9180490411183400199L, + -4817718227656051657L, + 785979865396935574L, + -7689259778972129265L, + 6878639307143602827L, + -1707085302887161029L, + -1565439692045367513L, + 145188358359952638L, + 5950830465561353178L, + -5798478302038700751L, + -2226708668641330939L, + 6469448358736909862L, + 8664958527704152036L, + 5535349946889143487L, + -5492973006601933162L, + 1056630503881604364L, + 309692344193328064L, + -1325766938638327983L, + -7482929830970430416L, + -4408424302596019484L, + -480574950088335999L, + -3307863187790378596L, + 3477765577142638670L, + -2331230081208486379L, + 3911594671769223260L, + -6780531386208631646L, + -8510677449436680990L, + -626520326023685130L, + 6361450738099140926L, + 2394752145895650387L, + -1428144106153991705L, + -8083151844911747669L, + -7436004472807581894L, + 5782046067893733552L, + -5292026140423046307L, + 5533934070794082284L, + -7662366745440754477L, + 2985568173297445164L, + 6966476425189845713L, + -7703121456776836315L, + -1510987927978493047L, + 7303134625337334164L, + -8202990867786288428L, + 1319339862757959960L, + -3077790914603251977L, + -8454808621776160478L, + -2753146122957105748L, + 3373398064125255264L, + 8346019299144821571L, + -8486870268569731271L, + -2336559059056769901L, + 4511628550243589470L, + 6951149477250785149L, + 5417720661433288424L, + 8309421963807893058L, + 5112522658470376561L, + 8234176485072859240L, + 7799608401388908342L, + 4378449040504281742L, + -7989739383215628611L, + -4732084855234830012L, + 3167384580555501185L, + -3643215394046503577L, + -7349901699683782836L, + -5349550264170666110L, + 756076486099874176L, + 4174502207370688508L, + -1151758869353979658L, + 8848338984622513194L, + 6395913475161294746L, + 1469705818420514455L, + -6295758011496721124L, + 5241715235088273374L, + -6511478119514275748L, + 8758910874313508247L, + -1699706016752355418L, + -690362402544790978L, + 2941321643463612597L, + -4293872409356543041L, + -8869301228299428567L, + 1141068614246669386L, + 647542286173136771L, + -5081241094287956867L, + 7611746854774550166L, + 8286824316663843591L, + 5293297384504364695L, + -5982798360475369212L, + -6572523711787919267L, + 4407085069020124145L, + 4613619958838436303L, + 7684164341448790302L, + 6756516403404278842L, + 2473985321567407573L, + -1849052731267467607L, + -560354543015577264L, + -373043150459477314L, + 6995361206199059042L, + -4868650397665721927L, + -7208287292799671945L, + -3899683041439439017L, + 1521234411290838670L, + 5267471567701155516L, + 6474031661344396260L, + 4283176820990066383L, + -774826789342914073L, + 4335739136054102737L, + 200896861914240508L, + -4316420436327989620L, + -5088641514239825154L, + 5164519541776509316L, + 2219746828642761402L, + 3587472414755725088L, + -3488503791590966004L, + -1652046437211338111L, + -5535426239533412177L, + -3602265696983958223L, + -4567427711302233998L, + 8184240716274055400L, + -5266269477414042060L, + -7324103519668272668L, + 229999798703974345L, + 7096405761766463580L, + -6255709187415618861L, + 852735384705532175L, + -8938214114308238198L, + 8963621340924508593L, + 9112541540378925595L, + -4616697869335781648L, + -1233934456967866939L, + -4077001463173053748L, + -6419528926392839608L, + 1929390749779564956L, + -7253316895888692088L, + 3527041640449918221L, + -7080491663870455048L, + -7454823183023009856L, + -6713602407554956640L, + -5298856948360600322L, + -1501770146154973327L, + -3425534612569530048L, + 8395223338644809391L, + -4742678068980964529L, + 1652567688904060596L, + 5564504478001751639L, + -8517554112392241558L, + 3786868227755834874L, + -5719304763773211634L, + 3763970332575479507L, + 2649812513621696558L, + -4445024488002933964L, + -8450466196049720316L, + 5754528146566703292L, + 4852625517416018587L, + 7311959397744128586L, + -327622418271024417L, + -5089985239000418204L, + -4480294659534985688L, + -1294989405694625777L, + -615947055237665163L, + -4568269373826433084L, + -6647170598113447270L, + -2205400148055461188L, + -2960875377488314259L, + -7802864814797980125L, + -4662829720569086630L, + 2546408082472556554L, + 890804262993354031L, + -8226401715675614014L, + -8917275821815880727L, + 2477618749365003865L, + 8418269367864851601L, + 4662094108308307351L, + -8118793192420184206L, + 6846264423372553523L, + -7942173008166231500L, + -4108512744107291799L, + -7904090155421027898L, + 5523466200613751305L, + -2953379233731225425L, + -1197095549386947091L, + 6045846757134608180L, + -3707869269183903522L, + 2779236905743216135L, + -361676587843055307L, + -2635261306415357726L, + -6509798004878518435L, + 1863587909403013988L, + -7520580316527163576L, + -6379291317211929448L, + -7620905891725098001L, + -2465551527582106307L, + 7241964578148990184L, + -6311322781101340202L, + -3020667296869548603L, + 8216782627512460387L, + -2692182243233829563L, + 1747175548503678565L, + -8885656099747617845L, + 522291218856276218L, + 6283744457032450774L, + 916230451834982654L, + -4089965662770677423L, + -8903058414982940070L, + -3738198241317312383L, + 1445085914657575113L, + -2012273464670594509L, + 6404077030013937454L, + 1329465815301186919L, + 4635873553023090471L, + -5377753772517225420L, + 1015019521353160404L, + -1665992354319528315L, + 9012340776556375011L, + 5778123565462793861L, + 8530605005049046593L, + -4591714514116980507L, + -4494594919048493483L, + 1893166869054693141L, + -9061649457570254120L, + 2914267276964910135L, + -6284492017246979138L, + -7055505827569739765L, + -889475583938310148L, + -8187613934134840238L, + -3308687460189573629L, + -897141441007718763L, + -6710963242654816172L, + -5341924825235386471L, + 4347432584948358099L, + 8927713241297101393L, + 2180557435070426802L, + 4579020122958742093L, + -5534158339970490803L, + 2185492605512194012L, + -327633447467916153L, + 9215998522891732804L, + -7912803364675245541L, + -1806233245666346644L, + -9038630050176177334L, + -2192019490984975973L, + -6479398744604567096L, + 6995952040088368841L, + -4309518653977861918L, + 6102791465247431297L, + -5104457163765865537L, + 7861681047136438901L, + -5076301891857452794L, + 1819637793566329678L, + -5361659997421131017L, + -2091157752616506018L, + -3248867894565820843L, + 8380590357118949537L, + -5390027978162823802L, + 4679766642994167265L, + 1808649257049920713L, + 1521853533084038975L, + -3254885160393954675L, + 4676349884210895679L, + 7152105176348873586L, + 4019498085477893861L, + -7688826658849547105L, + 7725487018181678237L, + 2843148296909797321L, + -2111458518911373960L, + -5930988189464757132L, + 2999836080082916584L, + 5258645044061481873L, + -4374901417507719180L, + 5968988542990945295L, + 7063865688418250092L, + -3082390282994194982L, + -1769924709834072774L, + 5156154634139202143L, + -5042052718766755463L, + -3999291805788718223L, + -1650492645962554370L, + -2788399451859036047L, + 7757384865629391019L, + 6764067541394908728L, + -2964620754340212099L, + -8835812450211244550L, + -4330613157254549476L, + 5382312720775017309L, + -8912238112613037874L, + 6729362625991860149L, + 5040339868437664129L, + 1986442221150817249L, + 2833965222715421174L, + 4454879067173589066L, + 4214179707119429897L, + 7969471537580882301L, + 4707712647580178131L, + -6276384029844312381L, + 5003823498704182200L, + -7159224012504849677L, + -6732468713847601045L, + -451150815967949945L, + -3304945333512306051L, + 8721127390513069488L, + -6257492216267905806L, + 6994701391892471561L, + 7369521965253705159L, + -1942957112123842402L, + -1274643128018116059L, + -1580125162564136735L, + 9136185408214755747L, + -2914537383120971740L, + 9209644639937450115L, + 487124280788007393L, + -8177344317197823195L, + 2738707339044517752L, + 8095872149006863063L, + -545157444532302601L, + -936698329718580485L, + -4901388582496778106L, + -1399963386439197980L, + 1690941657066922406L, + -6188898220632922030L, + 182177611176833150L, + -5235331291371493590L, + -7215173511743087678L, + -2940930949094457090L, + -3554616762777959507L, + -1227566774803650594L, + 126409523184734199L, + -5552904319120555059L, + 7352012128947000025L, + 175845163851021692L, + 7689535477863431441L, + 1688817097916176071L, + -8309357218398085711L, + 1143303078449829434L, + 4988650444510350305L, + 989390459273330745L, + -4404786474907964461L, + -6013357091088560707L, + -3369486357840647176L, + -5617919047910994332L, + 7862597641680704753L, + 6153533607628655113L, + -5935817060689825006L, + -4638742470542759160L, + -5170200139486489942L, + -3797462862816231632L, + -7523250579546769374L, + 3432885051112683135L, + -594962147648253627L, + -1635875643285631379L, + 6231350693553808879L, + 7408417052020966543L, + 2762871106861808563L, + -5173631699220114637L, + 5713727412733125037L, + -3899822138441414888L, + 2531424564706126868L, + 2668705972796311220L, + -8505630464979201291L, + 5232417711683756420L, + -6193480636951185723L, + 3997557899298166160L, + -499329436764373579L, + -4168998692140880977L, + -1278702168248437939L, + -4205714015212589720L, + -6075452672774566057L, + 5316851879595668811L, + -856263686801815946L, + 249453684176791550L, + 8631795819413273172L, + -6359854298613460820L, + -4880284840543237455L, + -8505753341883846372L, + 2210511848333928251L, + 7866118606324100230L, + -6686723182606252640L, + -8022317142606681640L, + 2872846752948911332L, + 1462486761827744910L, + -2333698582625662536L, + 2351971687147951698L, + 8780992513024852527L, + -1055703511181057423L, + -5129838204285009330L, + 6019857852521847817L, + 3474804733922603440L, + -3438026173701472540L, + -5014200821131413864L, + 3722183079515657580L, + 4595459098697613986L, + -7273302362390554577L, + -1183243147173106410L, + 1250316480703787335L, + -4036417308378739551L, + -8171241684564025199L, + -1444817278101452987L, + -5149004456737721464L, + -9151361129918396129L, + -3397841654363889387L, + 5939018758065831959L, + -4618833968900085099L, + -4804710050485360752L, + -986147323305919153L, + 8433402046252694868L, + 3402472387886333079L, + 6648721581812913642L, + 7545001534469525767L, + -2159558352983318523L, + -527918061511557161L, + -9097842819427090448L, + 5490764520636435462L, + 8940907420974044282L, + 8065885367294761717L, + 9126781255864608166L, + -7038128550034808274L, + 2129349033611316048L, + 6122145305083854433L, + -3131698705914526997L, + 8513873847555997838L, + 2641185331298884484L, + -3933359261337583276L, + 4455822931565268868L, + 6210597485361343375L, + 48275763469138112L, + -4040150889516064080L, + -380969185514364438L, + 4241813299302917418L, + -1595624218715483276L, + -4776935416378672245L, + -4376925234762941627L, + 4047867035099872744L, + -1360084872964546187L, + 622387020347388700L, + -5131645918980513847L, + 408338571741801931L, + 7363750087346687688L, + 6737473532720012277L, + 2318019708548967324L, + 8771768074500179526L, + 8857646919759472215L, + 2522573097657493641L, + -2423326328890116522L, + 1989746966925038863L, + 7672722008502212941L, + 2140362728746429911L, + -2673802457555972488L, + -1773151482900640326L, + -313068483478418644L, + 5013158890396496539L, + 5482660465451132885L, + 3258472208968020185L, + 4767670779359132511L, + 7693552999338372999L, + -901680228690526025L, + 1089180371118481814L, + 4293375244035886346L, + -1962629080279766201L, + 2222330065043425897L, + 3369405500095244802L, + 2658789151545528727L, + -7774565807858620379L, + 1084326140869671947L, + -5434432268705031901L, + 2180520833581215938L, + 632866827282395242L, + 7401769093998420929L, + -1501945418691678209L, + -6519039992723163516L, + -3237878798648121431L, + 1445316291631581042L, + 9067784747908349955L, + 6720511821996419101L, + -4604090926074340083L, + -1703427890781067435L, + -2332449337351599134L, + -7134581291331345557L, + -100619425730545485L, + -8928331454614465558L, + -5414664566994091947L, + -250253323907790747L, + -4125120859704104205L, + 5265608675113327534L, + -1106440358316798986L, + -3132948339320524042L, + -1769360217727663390L, + -6148228432119684450L, + 5051735026708131735L, + -3084188413564311460L, + 8759728664177720433L, + -4859095946336685737L, + -1886889459731067640L, + -1378480539638315159L, + -9049809243416485286L, + -2000107983033711361L, + 4157120773731364487L, + -1808265212831445402L, + -2196498993493480264L, + -8386935930399696667L, + 4759938096703369345L, + -4118521846188308313L, + 7157295486858813240L, + 4945752308016651452L, + -4173785935384824363L, + 1788529025053697021L, + 3993842499528395149L, + 9171317917249731442L, + -634141534904935122L, + -2072087936990361526L, + -7526214993566150005L, + 6612748581543768045L, + -3336262380081111460L, + 4976550170355560820L, + 8588219279211966004L, + -4599952352051238782L, + -3077807470649213797L, + 3519048410419239281L, + -1269625857054326672L, + -1981810369066884456L, + 3215154362269493852L, + -1785458974914263946L, + -7685571788755122241L, + -842157214814107044L, + -5897864338134155533L, + -6208498518724029718L, + 1499049555982089916L, + -7395915256615735849L, + 2984391195155257274L, + 5877953066484841227L, + 6846689224681680487L, + 3262845941307632598L, + 5343873341106550578L, + 8674160231567510634L, + -8964078304780361510L, + 8508234887302759010L, + 177823134353084724L, + -6206673588147938556L, + -5743358946993952513L, + -4303394514558459612L, + 3274927803723806123L, + -4798523778581238548L, + -570481748089052408L, + -3841292296997736004L, + 6731855287357772628L, + -7228244941482034575L, + -2491894868983308234L, + 151002941274804308L, + 6365761415219096791L, + 6910374953287400988L, + -8244739115056188084L, + 7312238168197737958L, + 7043896837953553432L, + -105689371098164936L, + -3281826222318725416L, + -5392584437397907545L, + -1244502770939334171L, + 1422952733642352893L, + -781084903411999364L, + 1396690387514113203L, + -8234418537024402963L, + 933069852671849324L, + 3458378457074859210L, + -432385914044143895L, + -333866867497008084L, + -5703273811341863097L, + -2034540751574753942L, + -2369557092226975438L, + -815026134899265013L, + -7959365582485730906L, + -7197967434421910831L, + 4747509881653331798L, + 653308083545458473L, + 5930493565363152735L, + 4681031764662240390L, + 6800487255255275529L, + 2997868047200386085L, + -4012551584799863895L, + -2732276893078481698L, + -6020710793223976880L, + -4359477391069411647L, + -9021880775816161346L, + 6353329025823001408L, + 2805319525008521714L, + 5679548538811076916L, + -6219297722635931220L, + -8841573986244661336L, + 8963781793551427953L, + 2688506298906176650L, + 6141741081705776696L, + 2510363714831351328L, + -2730397005289452736L, + 7708495123904590946L, + -632248182436338500L, + -5234821280863028627L, + 1321223421208197172L, + 5864841446223183074L, + -5988460782579658037L, + -8225052281044207214L, + -897540494473733225L, + 8590474636782421992L, + 7220132770424705042L, + -9106622746426894075L, + -3585709112504182555L, + 7808697748897822522L, + -4089854074839215479L, + 6016223108476798945L, + -6597172736630482691L, + -2193801513557418184L, + 5825159972581893620L, + 4631846790359335398L, + -5532611793901955549L, + -5243152382106090709L, + -127459936222352081L, + 6091495647920317970L, + 6462841941099889780L, + -4575635345767708116L, + -2542164493227712148L, + -305478661809303004L, + -4059150405046622549L, + -5381054086283578893L, + 7191490357105815377L, + 3276929466127581069L, + 2009085051555744551L, + 3249445681007134225L, + -8121229117439800671L, + 3440037568412847743L, + 3280179938427916363L, + 1442329761432187844L, + -1693017785953323849L, + -3408752277115922281L, + -3038837448636151594L, + -3070429694929466029L, + -7559544014133244350L, + 2583256147707906484L, + 8809049921046234748L, + 8707285529402118928L, + 680585173321551184L, + 2835422586302063689L, + -2367902852764733088L, + 4311754893046855300L, + -7420248434161482753L, + -115331812692054874L, + 932066338714068818L, + -8023806876384453665L, + 3566420863959396435L, + 4981613369266357307L, + -3434457476282205941L, + 4903586440989717216L, + 3268581766723018296L, + -6679520660856856176L, + -5331329368963679157L, + -2266666248595158753L, + -8523119193122881242L, + -55424956038138295L, + -9070536805481137606L, + 5417874584175861223L, + -9170990702439119877L, + -2874187966968250082L, + -2946382889610762149L, + 4460563949925001083L, + 208629763415621209L, + -2006752850050214804L, + 4078329933745202367L, + -6003178253606500673L, + -1901357459835262850L, + -8628316773608528907L, + -2367045297086306897L, + 5181249700081074386L, + -4589928625788551233L, + -2552920600683065276L, + 3839074001010260393L, + 6062571583983586246L, + 3105281105213899486L, + -8099385440700840978L, + 4787643747225137633L, + -8984875174291612426L, + 4913083880029400303L, + 6268216711282604489L, + -9161084900657602886L, + 4091506170626504784L, + -6137301573374744154L, + 862946098808666372L, + -6257228414093693534L, + 846885534512613336L, + -8079328287598987503L, + -6720900737415180224L, + 1285878208148563529L, + 7631267414265336249L, + -2101551039318119517L, + 5109001452480742834L, + 3045563723015329655L, + -2678263607699919634L, + -6111470810863893821L, + -62607678110828373L, + 2055784805590000566L, + 1529635868940897778L, + 7944938393711537630L, + -8622354108627238341L, + 400616186093007467L, + -3365668985765229920L, + 520796926667976058L, + 102953245028782442L, + -2887814565519713483L, + 1134845382723719106L, + 9165308674806362050L, + -6744097273442400118L, + 6792112760482467418L, + -2608343247634721333L, + -4300634750668796357L, + 9114849223412999163L, + 3292520868553201409L, + 8990457701612625656L, + -8604807838878366041L, + 6771571915702855913L, + -2596622766084861700L, + -1646084290072088508L, + 1986205531231129502L, + -7397245895787143030L, + 1322416902629630467L, + 8798541050009010963L, + -2603841395104921386L, + -543569387127414242L, + 984277979951833313L, + -3660009424046808871L, + -8594713258206394011L, + 8481462325069318424L, + -7693778854396921111L, + -3466292502757840479L, + -2782730956760988243L, + 2144829447800020843L, + 1822306312783027271L, + -6176295933444085182L, + 622474367537194108L, + -4672048499304291212L, + -4264273507669187343L, + 6547219371359541315L, + 307228520032121068L, + -6000079446917495846L, + 1421275154031788543L, + -5016167630802770982L, + -8153331626666077741L, + 4942105349496831629L, + 3433248069013654310L, + -2222196715022867294L, + 1813002790841082845L, + -3166716117255484472L, + -9054518662678110779L, + -7366837763863382746L, + 1821322667002800477L, + -6699279961062916425L, + 5275413951856993906L, + -1764403036698451877L, + -6814217963826368587L, + 7436121024271456880L, + 8020503156016080684L, + 4790388985973217959L, + 1217850670627339453L, + 9024348854253136643L, + 1103129819330605922L, + -2166392621148129624L, + 1180647242684910729L, + -1356076635533405843L, + -6621817644273909238L, + 8889272575079464367L, + 4253064062765640293L, + -8444342477389972075L, + -4449332965293453838L, + -4037054741244914652L, + -5783630812876862786L, + -6227123841055454074L, + 2689340898385899414L, + -5298687834900317834L, + -5771269026024081892L, + 1945144907664070561L, + -2548379487047027869L, + -4846198189662238716L, + 6383035859800179563L, + -538840917214433039L, + 8270516200955665520L, + -8600518090590687029L, + 3805661707968319824L, + 7599817584154307234L, + -3646938568457564007L, + 43016748520311967L, + 3409116355300614893L, + 621933859667984230L, + 4420539797901766919L, + -8854667100425996404L, + 7203838388356217445L, + -7264835226236053678L, + -1623402918890722788L, + -4166106671946901643L, + 8889077380182099507L, + 8937812779969367487L, + 4083244217264466556L, + 7823919447681612722L, + -385459494499317144L, + -5883272230680561812L, + 6356338096717516045L, + 9162899879168759439L, + 566477718171182844L, + 5138116499374346600L, + -8162099721989626792L, + 2871419627484181402L, + 4549390537257157879L, + -2450300817394156370L, + 7914639949613314474L, + 860572809253792281L, + 2292560778148293412L, + -7502514745528454484L, + -6882165832291626199L, + -2630674516935294102L, + -4989794580249597060L, + -7513651950755561937L, + 4804536116066169381L, + -5242688622696191670L, + 8047321759875327873L, + -3677209646627471284L, + 6980331724177633705L, + -375074456792592810L, + -6802449435897247678L, + -1628562059596464092L, + 8113462089103701362L, + -3970435268208640319L, + -9097918839183737600L, + 6199140712580348865L, + -268991411330185044L, + -7817073335811580945L, + -3405223752470266629L, + 7993791576935207402L, + 5192774131052489482L, + -9042927321514383766L, + -3601662122081534094L, + 4841841972164327977L, + -1645688674582329230L, + 7159999496075283486L, + -7405132443615822400L, + -3717231289253565466L, + 2918520769168028237L, + -1260804183044051163L, + 8154917047376864752L, + 5508346499230105531L, + 3285997221882934909L, + -5617134513664899328L, + 8293867188447369346L, + -3882977634293431140L, + 1239307736392879380L, + -8924851511568278673L, + -1622087619217032532L, + -5551432630671196153L, + -1121763370203524511L, + 551938970558940490L, + 448453096366444138L, + 5667305190458742300L, + 4539597042043946745L, + 5829786741944860299L, + 3393352605677422507L, + 335053384967789388L, + 4394222496211014534L, + 5370000130739018087L, + -565706613123683753L, + -7833497599449750817L, + -3437882830797020390L, + 4937862675193204437L, + 5959554141150583384L, + 3983730657745060070L, + -2467280586303360795L, + -335334767324786992L, + -640382658335040542L, + -6577797313708187062L, + 1125349079636120123L, + -494879484631175552L, + -5623945463935727777L, + -3970027725779406711L, + -8493400026672732241L, + -311293892634841311L, + 6355980595541216637L, + -5751497682715332938L, + 2347741401598364925L, + -4809577486191269354L, + 1420282983140681264L, + 3613315133783948228L, + 8625254293652687419L, + 7531382631561216614L, + 5399763597085607760L, + 3035446121449853380L, + -2120112973020043286L, + 480192923742041432L, + -2548797010939265844L, + -3405974478077804102L, + -133708079963712608L, + -337250121171329984L, + 4042336883248424281L, + -5364750416296539339L, + -6498306095021896398L, + -7473497501035559608L, + 1723304923372711161L, + 5006605643417679342L, + -909630909226495535L, + 4651967258997819637L, + -2492450197158626287L, + 8848922133698826227L, + 6782108621218678042L, + 4567479157936435262L, + -820689158472515069L, + 4826415566140008821L, + -2484634481640370398L, + 1380433635719727570L, + 8147033694125853433L, + -3881420496323039737L, + -5072661488520121646L, + -1001254897970286729L, + 6441576346453560757L, + -7535835287918290060L, + 7430502536985186200L, + 5108187444240043248L, + 1549419730978779681L, + 7111883894871337879L, + 6796158162775215639L, + 2516639939991012468L, + -2371674177998310802L, + 1127854323859071735L, + -8295387485661924306L, + 1253693892107448444L, + -354249102833783868L, + 1065848432473299948L, + 4980932879340301589L, + -3265506302710279538L, + 1321586933496286980L, + -4844842473063803960L, + -4204298827240721647L, + -3118913691980453704L, + 7305336767320557495L, + -6798785057541149778L, + 8746540548113783399L, + -7969167725986709018L, + 8609211018983958021L, + -7231030245443353922L, + 5692294488862404752L, + -5761197062576580840L, + -5894104633667262135L, + -1372322724071052152L, + -1152616426443151651L, + 935972424443347664L, + 8940890555228973330L, + -619270121883985361L, + 8372920364579516256L, + 4398889684895596727L, + -4160078105340506886L, + 17822379882525818L, + -1430879876106006468L, + 3128763795393100346L, + 607666137432825035L, + -766289326504346177L, + -4462174050261663777L, + -1140803182508002260L, + 1035794337970190842L, + 299393203454704382L, + 7734246045329515707L, + 6361639674133231345L, + -4159331747805036027L, + -4615813274428812655L, + 3873955101764325164L, + -6849074412332003603L, + -8511457087328374957L, + 1188632971701951322L, + -4073667337443196875L, + 4905058734702399313L, + -4717225456603964250L, + 5342494502015340877L, + -1341838399813369350L, + -1184900213109944408L, + 7269941727655174395L, + -8379459598706879314L, + 3162473609960755880L, + -3008200309695401191L, + 2351068467933459341L, + -71569529145854359L, + 3900859699454157168L, + 7000831594956186274L, + 4124542402944063388L, + 517836136499145469L, + -3563369622913903581L, + -6131810259721881352L, + 2478930569265994206L, + -7335894002456063877L, + -1852552332759896185L, + -7661455803549448534L, + 4220258643753458017L, + -2576514654123627237L, + -4329614475513280706L, + -6312701748516438716L, + -8712455751362790038L, + }; +} diff --git a/src/test/resources/net/openhft/chronicle/algo/hashing/reference/XxHashTest.java b/src/test/resources/net/openhft/chronicle/algo/hashing/reference/XxHashTest.java new file mode 100644 index 00000000..2323febd --- /dev/null +++ b/src/test/resources/net/openhft/chronicle/algo/hashing/reference/XxHashTest.java @@ -0,0 +1,2128 @@ +/* + * Copyright 2013-2025 chronicle.software; SPDX-License-Identifier: Apache-2.0 + */ +package net.openhft.hashing; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.util.ArrayList; +import java.util.Collection; + +@RunWith(Parameterized.class) +public class XxHashTest { + + @Parameterized.Parameters + public static Collection data() { + ArrayList data = new ArrayList(); + for (int len = 0; len < 1025; len++) { + data.add(new Object[]{len}); + } + return data; + } + + @Parameterized.Parameter + public int len; + + @Test + public void testCityWithoutSeeds() { + test(LongHashFunction.xx(), HASHES_OF_LOOPING_BYTES_WITHOUT_SEED); + } + + @Test + public void testCityWithOneSeed() { + test(LongHashFunction.xx(42L), HASHES_OF_LOOPING_BYTES_WITH_SEED_42); + } + + private void test(LongHashFunction city, long[] hashesOfLoopingBytes) { + byte[] data = new byte[len]; + for (int j = 0; j < data.length; j++) { + data[j] = (byte) j; + } + LongHashFunctionTest.test(city, data, hashesOfLoopingBytes[len]); + } + +/** + * Test data is output of the following program with xxHash implementation + * from https://github.com/Cyan4973/xxHash + * + * #include "xxhash.c" + * #include + * #include + * int main() + * { + * char* src = (char*) malloc(1024); + * const int N = 1024; + * for (int i = 0; i < N; i++) { + * src[i] = (char) i; + * } + * + * printf("without seed\n"); + * for (int i = 0; i <= N; i++) { + * printf("%lldL,\n", (long long) XXH64(src, i, 0)); + * } + * + * printf("with seed 42\n"); + * for (int i = 0; i <= N; i++) { + * printf("%lldL,\n", (long long) XXH64(src, i, 42)); + * } + * } + */ + + private static final long[] HASHES_OF_LOOPING_BYTES_WITHOUT_SEED = { + -1205034819632174695L, + -1642502924627794072L, + 5216751715308240086L, + -1889335612763511331L, + -13835840860730338L, + -2521325055659080948L, + 4867868962443297827L, + 1498682999415010002L, + -8626056615231480947L, + 7482827008138251355L, + -617731006306969209L, + 7289733825183505098L, + 4776896707697368229L, + 1428059224718910376L, + 6690813482653982021L, + -6248474067697161171L, + 4951407828574235127L, + 6198050452789369270L, + 5776283192552877204L, + -626480755095427154L, + -6637184445929957204L, + 8370873622748562952L, + -1705978583731280501L, + -7898818752540221055L, + -2516210193198301541L, + 8356900479849653862L, + -4413748141896466000L, + -6040072975510680789L, + 1451490609699316991L, + -7948005844616396060L, + 8567048088357095527L, + -4375578310507393311L, + -3749919242623962444L, + 888155921178136237L, + -228195649085979072L, + -521095004075279741L, + -2458702038214709156L, + -2792334161285995319L, + 7509323632532862410L, + 46046374822258777L, + -731200582691896855L, + 933917387460394992L, + 5623144551929396680L, + 6456984547425914359L, + -6398540474588876142L, + 1224372500617079775L, + -931727396974525131L, + 979677643219401656L, + -8078270932489049756L, + -92767506898879473L, + 2379112167176776082L, + 2065719310945572007L, + -4972682801816081667L, + -7346559332994187462L, + 4674729779638751546L, + 5844780159702313017L, + 925606237565008152L, + 8164325403643669774L, + 5124005065773312983L, + -4646462236086916483L, + 4733593776494364101L, + -6408850806317360L, + 7405089268865026700L, + -2131704682637193649L, + -592659849139514384L, + -4386868621773355429L, + -2216833672566288862L, + 4022619316305276641L, + -60464713570988944L, + 2416749694506796597L, + 3576590985110933976L, + 3368688771415645536L, + -357157638897078259L, + 3484358739758473117L, + 2078888409435083535L, + 8053093288416703076L, + -4934736471585554038L, + -7784370683223414061L, + -4109284735634941390L, + 5982490102027564625L, + -4991107002810882893L, + 8664747912276562373L, + 8536879438728327651L, + 2358675440174594061L, + 5352236919104495867L, + 6340852522718110192L, + 5075606340464035668L, + -6313168920073458239L, + -6428599582591385786L, + -7278654800402467208L, + -6630626099856243581L, + -7548742438664634646L, + 5514383762309532642L, + -5996126265702944431L, + 4011116741319319261L, + -7289240093981845088L, + 4975257207486779926L, + -3945500877932691916L, + 1973955144068521079L, + 3884425912161913184L, + 7692681977284421015L, + -1616730378439673826L, + 4799493270916844476L, + -6107310582897997679L, + 3643294092300179537L, + 5406040598516899149L, + -3032420409304067208L, + 5044227119457305622L, + 9165032773225506149L, + 7553488247682850248L, + 2247298339072845043L, + 7380491470304042584L, + -456791943260357427L, + -1906500292613319324L, + -4025157985304129897L, + 6167829983725509611L, + -8678196943431064825L, + -636391087313417831L, + 5757999497725839182L, + 8999325347316115948L, + -6042339776328081249L, + 7988836354190359013L, + 2818448030979902104L, + -8484201484113382447L, + -1140175406473847155L, + 3042776987426497381L, + 3147338037480432386L, + 5065714330193756569L, + 8827021486636772242L, + 838335823706922959L, + 481844220820054909L, + 5333474685474667077L, + -3722898251196013565L, + 7909417627390150381L, + 7116148225996109646L, + 7520381989775811302L, + 6045444672904719015L, + 169039646730338133L, + -2144629916252757106L, + -3752608501798118554L, + 8374704774878780935L, + -5830926781667225570L, + 3202139393110256022L, + 4400219135677717216L, + -5663710220155589201L, + -2589002340345751622L, + -8240133511464343390L, + -4036798392879835146L, + 501599054729008501L, + -4851415719238782188L, + 7565157933617774080L, + -6428091359957700043L, + 4081845077806300175L, + -9016659258880122392L, + 7811786097015457596L, + 1357606791019752376L, + 6522211979684949668L, + -3462397075047559451L, + 3075504459164148117L, + 3055992297861390732L, + -7230492327399411047L, + -1128103378253532506L, + 1834607408788151585L, + 7065978976369231860L, + 6566122632438908362L, + -3440855531356735824L, + 6271453770746181891L, + 413365468403580071L, + -8342682158827061522L, + -3713303136987568731L, + -8959326895824091541L, + -2793862582117663595L, + -184756427409317729L, + -7052502019782453427L, + 3666196071825438258L, + 170204095295428634L, + -1880693509859077843L, + 5179169206996749826L, + 2866097700453114958L, + 1859104195026275510L, + 3782323564639128125L, + -6485194456269981193L, + 6761934873296236857L, + 5764605515941066448L, + 597754945258033208L, + -4888986062036739232L, + -6490228233091577705L, + 3234089784845854336L, + -5506883591180767430L, + 1491493862343818933L, + 3232293217886687768L, + -4079803366160739972L, + 4884134040093556099L, + -7274733680156962461L, + 5265680254123454403L, + 1036855740788018258L, + 423439784169709263L, + -3627743032115866622L, + -6311378083791982305L, + -3058076915688265687L, + 5826550132901840796L, + 8049712006832885455L, + 1707844692241288946L, + -3293048440386932248L, + -2458638193238955307L, + 943059295184967928L, + 3899561579431348819L, + -1516862862245909493L, + 4448476568037673976L, + 8738531437146688925L, + -1033913449611929894L, + 733668166271378558L, + 438686375775205249L, + -4325889118346169305L, + -238178883117433622L, + -7972205050662019794L, + -1263398103237492853L, + -8333197763892905802L, + 7796341294364809534L, + -1381767618016537445L, + 2892579485651013970L, + -3376209887503828920L, + -8575120126045607817L, + -1609355362031172055L, + -386138918275547508L, + 4598874691849543747L, + -2961781601824749597L, + -3032925351997820092L, + -4256249198066449735L, + 6712291718681474012L, + -4281614253751277086L, + 3727487933918100016L, + -2744649548868700294L, + 8662377383917584333L, + -9154398439761221404L, + -6895275824272461794L, + 3394857180017540444L, + 2010825527298793302L, + 4894417464710366872L, + -6879244364314087051L, + 83677167865178033L, + -8258406393927169823L, + 5042126978317943321L, + 6485279223034053259L, + 4442956705009100620L, + 316801800427881731L, + 1381431847939703076L, + 5172932759041399062L, + -69656533526213521L, + -5302643413630076306L, + -3956089084400440856L, + 372087412941022771L, + 4711314482928419386L, + 3255220726505012060L, + 8917854303046844847L, + 1116214654602499731L, + 2282408585429094475L, + -9207590323584417562L, + 8881688165595519866L, + 1731908113181957442L, + 3847295165012256987L, + 4457829016858233661L, + 4944046822375522396L, + 3445091217248591320L, + -5055680960069278553L, + -399195423199498362L, + -8109174165388156886L, + 4967185977968814820L, + -5911973391056763118L, + 2239508324487797550L, + -954783563382788523L, + 8523699184200726144L, + 932575865292832326L, + -7491448407022023047L, + 1809887519026638446L, + -8610524715250756725L, + 6158809695983348998L, + 4948400960714316843L, + -4513370424175692831L, + -3955280856263842959L, + 6440233015885550592L, + 8756942107256956958L, + 7895095834297147376L, + 370033091003609904L, + 948078545203432448L, + -8523229038380945151L, + 100794871657160943L, + -2186420796072284323L, + -9221115378196347951L, + 8102537654803861332L, + 5857339063191690550L, + -4554257374958739421L, + 6607496554818971053L, + -778402196622557070L, + -3817535277727878318L, + 3564122000469288769L, + -44446230828995950L, + 1322708749649533240L, + 6150374672341998205L, + -3300275952549095391L, + 5700833512536085850L, + -8559358370491270937L, + 5434443260519512697L, + -8031025173259990945L, + 7117462129248544172L, + 5425177419943569451L, + -7215427371174054838L, + -5728669976971194528L, + -2096361446095323077L, + -4247416835972286805L, + 4912769047482466787L, + 7755341152739082452L, + 6797061233443658471L, + 4089361562209715474L, + 5830701413838808929L, + 5514515889578551370L, + 609334005368729318L, + 177310574483850759L, + -820431153866372784L, + 7188454041446661654L, + 7480194911613035473L, + 4564607884390103056L, + 888496928954372093L, + -5480535802290619117L, + 9100964700413324707L, + 510523132632789099L, + 8249362675875046694L, + 5340321809639671537L, + -4633081050124361874L, + -839915092967986193L, + -7377542419053401928L, + 1820485955145562839L, + 8517645770425584256L, + -1877318739474090786L, + 7674371564231889244L, + -3311130470964498678L, + -880090321525066135L, + -5670998531776225745L, + -8828737503035152589L, + -6029750416835830307L, + -6535608738168818581L, + -550872341393232043L, + 2831504667559924912L, + -4613341433216920241L, + 502960879991989691L, + 576723875877375776L, + -2575765564594953903L, + -4642144349520453953L, + 7939746291681241029L, + 6486356905694539404L, + -9086235573768687853L, + 5369903658359590823L, + 3199947475395774092L, + 8384948078622146995L, + -3365598033653273878L, + -2525526479099052030L, + 2648498634302427751L, + 3715448294999624219L, + -4734466095330028983L, + -8440427851760401644L, + -371198022355334589L, + 8864079431738600817L, + -4205600060099565684L, + 6617166152874298882L, + -6515522971156180292L, + 7254251246745292298L, + -420587237082849417L, + 1190495815435763349L, + -474540026828753709L, + -8150622114536376016L, + -5790621848044235275L, + -2780522220219318167L, + -2991155855957250848L, + 1692932912262846366L, + 8814949734565782733L, + -8746818869495012552L, + 7931250816026891600L, + -7434629709560596700L, + 4388261932396122996L, + 7154847153195510802L, + -2810154398655124882L, + 2601892684639182965L, + 7781574423676509607L, + -6647000723020388462L, + -8679132292226137672L, + -2447013202020963672L, + 3658855631326217196L, + 2176620921764007759L, + 3654402165357492705L, + 4511989090021652156L, + -3254638803798424003L, + 9050506214967102331L, + 922579360317805810L, + 609820949221381248L, + 5723875594772949290L, + 4637721466210023638L, + 6195303339320487374L, + -38202587086649325L, + -2142927092331878341L, + 5355751314914287101L, + -7170892783575760055L, + -7506612729078573199L, + 8645580445823695595L, + 3221950179890871958L, + 1638211443525398634L, + 7356718304253861777L, + -296260062751271549L, + -1790105985391377345L, + -7004118620405119098L, + 7056012094479909462L, + -7673357898031223798L, + -8929502135696203556L, + 7527161467311997998L, + 6182865571027510002L, + -2163310275402596869L, + 6285112477695252864L, + 3703909999924067987L, + 962491298117560533L, + 138936592567072793L, + 6094857527471100960L, + 5914305068838335718L, + -8896724991235492552L, + -2667562314507789198L, + -7456492499188304500L, + -3422709784851063201L, + -1511644999824238281L, + -7130158069449057322L, + 6243266426571961929L, + 2713895636371672711L, + 5765589573821453640L, + 2624585483746388367L, + 3933828437519859601L, + -5664404238108533781L, + 7086393398544811684L, + 1322058227068490376L, + -8232508114671021371L, + -5963804389649678229L, + -3318229976491806899L, + -6261789542948241754L, + 199130260709663583L, + 7521707465510595039L, + 507353862067534334L, + -7737968456769005928L, + -8964687882992257099L, + -7735003539801528311L, + 6989812739838460574L, + -6986289777499051441L, + 1881562796144865699L, + -6077719780113966592L, + -5427071388091979746L, + 1660707436425817310L, + -4338189980197421104L, + 5330934977599207307L, + 4461280425701571033L, + -7426107478263746863L, + 4258305289832328199L, + -8003283151332860979L, + -2500604212764835216L, + -8883941775298564436L, + -5059709834257638733L, + -4582947579039913741L, + 1371959565630689983L, + -1925163414161391371L, + -1180269729544278896L, + -6603171789097590304L, + 8985062706306079731L, + -3588748723254272836L, + -6052032019910018725L, + 6200960040430493088L, + 2146343936795524980L, + 7785948646708747443L, + 4524411768393719400L, + 749211414228926779L, + -163844243342465015L, + 1066801203344117463L, + -3687825939602944988L, + -4873811917429870500L, + -3765115783578949524L, + 3344884226049804020L, + -22793631121165636L, + -5636541624133159076L, + -6201449576244177151L, + -4533734412127714050L, + -2064657727206266594L, + -1325853623186040989L, + -2651306529045029511L, + 903264360879626406L, + 6082283797495873520L, + 6185446819995987847L, + -5727850940826115079L, + 8356646143516726527L, + -7705915341280821272L, + 9137633133909463406L, + 6613483969797411894L, + 8598514961735984460L, + 6805925079991408361L, + 6009403222422527608L, + 2216303622650116705L, + -3736062178532154638L, + -7139008962939637477L, + -1537711200058404375L, + 8896755073380580322L, + -6063426810787442347L, + -3472064301690015285L, + -4568131486464952371L, + -8141256104294687045L, + 5627435360893599536L, + 1136003802967708029L, + 2730027518034735037L, + 1985287040172139729L, + -3643431491383365431L, + -9042919736106376701L, + 8879968900590373568L, + 8504486139877409399L, + 5832665747670146536L, + 4202923651402292496L, + 1738511892080946286L, + 4512683881549777042L, + 9200194457599870145L, + -1948301178705617139L, + 8655715314401162523L, + 412698981651521600L, + -1479274044808688580L, + 2688302549664693359L, + -3059920027366623178L, + -4275753325231806565L, + -8321791698013769889L, + -3678119714812414102L, + -2500922551770832553L, + 9018541633115002061L, + 5713301371152396803L, + 4180584812840471799L, + 3062416401091271879L, + -8125716681035757962L, + -2076056159878596225L, + 8855540523533374738L, + 2402007906402689092L, + 2020584786288649542L, + 1707405964421070701L, + -3681994462249973122L, + -3982567775984742012L, + 7133200226358561844L, + -5270514263562558963L, + 9060760368219219429L, + -6967162372382490281L, + -9094664463528453384L, + -3968518633408880046L, + 8618660189330281694L, + -4668946581954397558L, + -8596433172676363407L, + -1264942061713169049L, + -5309493221793643795L, + -1099320768477039529L, + 8925041285873295227L, + -6809278181760513499L, + -7039439984223885585L, + 6188209901527865226L, + 1487353394192637059L, + 2402097349430126337L, + -3818359601525025681L, + 4123217079279439249L, + -1424515143377220376L, + 1742298536803356877L, + -2836832784751148874L, + -4838603242771410698L, + 2383745618623084414L, + -2790832243316548423L, + -1176683649587660160L, + 1862928178605117401L, + 5208694030074527671L, + 4339841406618876548L, + -7704801448691668472L, + 500068664415229033L, + -2111184635274274347L, + -1387769336519960517L, + -2368660677263980293L, + -4980481392402938776L, + -6856361166068680884L, + 1708658704968066797L, + -9013068514618931938L, + -2616479975851677179L, + 7121103440247327570L, + -7094192881960646061L, + -4042342930006488618L, + 5294323611741266775L, + 5235545113690922502L, + -2562011392475214878L, + -4613304566070234734L, + -3784386310583029381L, + -4526148219816534267L, + -8643470129031767968L, + -4573761335510927866L, + -8255399593563317902L, + -1925488377092111963L, + -1747797357090594237L, + 7292772921748919564L, + 3951718848780851600L, + 5339305877764077075L, + 7889570407201305102L, + -8935437555550449315L, + -1858205318388884024L, + 381779657795494278L, + -3769854251228686168L, + -7957724087073627355L, + 4349540075286824743L, + -2476434494603040708L, + -4506107235113109706L, + -7120863144673563848L, + -8534342596639587598L, + 2205658724629050493L, + 604438195864305027L, + 4530331938860561927L, + -2074141653226683751L, + -1114378227875974007L, + 3377301950002508302L, + 5369356700690664306L, + -1747063224581819445L, + -6320380781966280801L, + -2075443262555773155L, + 1028541493355576591L, + -4694402890123574860L, + -5250660999767019003L, + 3847087895315315136L, + -4448050214964317066L, + -4591316307978008151L, + 4894820902772635901L, + 3088847887353411593L, + -6699208183127463352L, + 4636731998354510780L, + 9095126525233209263L, + 4135373626035182291L, + 3835688804093949701L, + -3490782692819028324L, + -561453348486424761L, + -3329283619698366365L, + 3251154327320814221L, + -8006986328190314286L, + 5856651505286251345L, + -8871425101391073L, + 7806993676637210959L, + 7586479850833664643L, + -7091216108599847229L, + -3410137297792125447L, + -8251963871271100526L, + -8849730915506517177L, + 8400334327557485676L, + 1676125861848906502L, + -8480324002538122254L, + -1402216371589796114L, + 5951911012328622382L, + 8596811512609928773L, + -2266336480397111285L, + -8840962712683931463L, + 4301675602445909557L, + 1843369157327547440L, + 2169755460218905712L, + -1592865257954325910L, + -8763867324602133653L, + -4283855559993550994L, + -7577702976577664015L, + -5152834259238990784L, + 4596243922610406362L, + -4326545138850544854L, + 1480440096894990716L, + 8548031958586152418L, + 6705615952497668303L, + -2915454802887967935L, + -6137002913510169520L, + 2908515186908319288L, + 5834242853393037250L, + -6721431559266056630L, + -7810820823419696676L, + 1954209413716096740L, + 6657013078387802473L, + 2214178984740031680L, + 8789512881373922013L, + 1240231669311237626L, + 8694612319028097761L, + 492180561068515854L, + -6047127535609489112L, + 7436686740711762797L, + -4520261623507558716L, + 938282189116272147L, + 3232025564608101134L, + -5425498066931840551L, + 932123105892452494L, + 9054941090932531526L, + 8066693670021084601L, + 764877609198828864L, + -489112437588815338L, + 4827691353685521957L, + 1948321254606741278L, + 6117773063719937712L, + 4645962658121906639L, + -7846887104148029590L, + 4210795945791252618L, + -8879516722990993098L, + -2621063563373927241L, + 2094675051444850863L, + -8681225697045319537L, + 6072534474938492189L, + 6181923696407824226L, + 5463607676777614919L, + 3708342890820711111L, + 8844501223821777366L, + -1459359143442302680L, + 2225439088478089068L, + -3866259492807347627L, + 5715020051188773955L, + 3922300588924895992L, + -9142841818158905228L, + 2234845285375211931L, + 2466598091809457099L, + -5086614780930363190L, + -59740786891006359L, + 3484340182077240897L, + 5684798394905475931L, + 8492255409537329167L, + 5276601975076232447L, + -723955912320185993L, + 9032937149732310432L, + 2226206333274026280L, + 5631303328800272036L, + 3943832708526382713L, + -3756282686478033644L, + -5407377327559185078L, + 2025162219823732106L, + -8802502232162774782L, + 9039368856081455195L, + 663058667658971174L, + 3624269418844967319L, + 1835338408542062149L, + 6821836507221295281L, + 6273547355770435776L, + -3104373869480308814L, + 1150888014781722836L, + 7638478751521711777L, + -6407096352658729423L, + -2242514077180426481L, + -3181824045541296523L, + -4562287221569080073L, + -5550768647534615669L, + -5786611484859469238L, + -6147722345444149090L, + 3737249616177808079L, + 3401215612108618403L, + -713522925214097648L, + 7938558781452631257L, + -2822931074351003413L, + -6484774850345918944L, + 3384659068511379086L, + 6976459554734427695L, + 4254162229878558339L, + -3312164339867139602L, + 7263045146222903358L, + 4561625003713187235L, + -3350421200373539593L, + -6329267008823047447L, + -6889593333717619051L, + -6470291206680780949L, + -1925391510610223335L, + 4955720513801530785L, + -6515999401129420095L, + -5146900596178823847L, + 2572121582663686783L, + -4958678197003031937L, + -1295912792184970105L, + -8320363273488883198L, + -8213501149234986129L, + -3883775881968950160L, + -8925953418077243474L, + 3199784299548492168L, + -6836506744583692202L, + -5007347279129330642L, + 7387675960164975441L, + -5841389805259238070L, + 6263589037534776610L, + 3327727201189139791L, + 3673450414312153409L, + -1563909967243907088L, + -3758518049401683145L, + 6368282934319908146L, + -6025191831649813215L, + 1223512633484628943L, + -8540335264335924099L, + -8569704496403127098L, + -5712355262561236939L, + -6468621715016340600L, + 7015005898276272746L, + -1037164971883038884L, + -6108649908647520338L, + -6781540054819591698L, + -2762739023866345855L, + -270930832663123436L, + -2387080926579956105L, + -3984603512651136889L, + 2367015942733558542L, + 2997123688964990405L, + -424413420483149165L, + 2906467516125124288L, + 7979917630945955701L, + 2879736983084566817L, + 558436267366797870L, + 6471658168855475843L, + -3453803644372811678L, + 95470628886709014L, + 5666911245054448862L, + 1594133734978640945L, + 3790246368687946045L, + 8636400206261643605L, + 5901994795106283147L, + -6774812279971490610L, + -4622588246534854941L, + 5395884908872287278L, + 7381412950348018556L, + 5461775216423433041L, + 2851500852422732203L, + 1153428834012773824L, + 2567326223464897798L, + 6290362916558214218L, + 6095765709335097474L, + -3526424734043456674L, + -8411274175041022530L, + 7565408328520233290L, + -1318636864706103626L, + 1261242784453012654L, + -472643963000448611L, + -7126293899612852456L, + 5072187962931197668L, + 4775251504230927816L, + -1624676500499667689L, + 2252385971292411863L, + 7908437759266752884L, + -8948829914565397845L, + 5258787823809553293L, + 3885696202809019506L, + -4551784314460062669L, + 5315762970089305011L, + 7218180419200466576L, + 109471822471146966L, + 3901499100759315793L, + -5613018173558603696L, + 5782419706003468119L, + 8285176821902721729L, + -2944182278904878473L, + 8089487615165958290L, + 6934039118340963316L, + 8481603619533191729L, + -6321491167299496492L, + 6441589800192421521L, + 6436057639713571196L, + 6819921695214365155L, + 1185928916708893611L, + 2597068862418243401L, + -7637601550649263782L, + 9129303862479379164L, + 4047905726243458335L, + 6672087858539795207L, + -4841432774404255351L, + 5501215987763227677L, + -5300305896512100453L, + 1635946349436492617L, + -5017459781050596604L, + -7313558338536196566L, + 4625509831332846264L, + -1241826701278444028L, + 2916178164108211239L, + -6947453283344846915L, + 5520544791845620925L, + 5009241392834567026L, + -630825152277572403L, + 6246654103747517292L, + -5632205909016659384L, + -5099826214945383802L, + 2466330894206710401L, + -1463559257726812272L, + 4922422449110036517L, + -4940410396057186660L, + 8835766963654337957L, + -1984334093384497740L, + 5616151800825184227L, + -8442970605804311782L, + -5396399970392474268L, + 2711274356126287353L, + -5090439840321959043L, + 6638617029380445409L, + -6424875729377006548L, + -7243574969986334324L, + -904268348341193502L, + -6196811069886893217L, + -7742123331454617135L, + 1449632469607275832L, + 3212140938119717436L, + 8676942774083692265L, + -6625590425417154859L, + 8720904664575676760L, + 9151723732605931383L, + 7642401923610349184L, + -3454390566366389884L, + -232373658792783206L, + -8933620623437682010L, + 2514068248201398743L, + 6757007617821370359L, + -2870340646674679163L, + 416331333845426881L, + -5319172016123138702L, + 3294412564645954555L, + 2812538484970453169L, + -9128349093860081905L, + 6784456254618976198L, + -2861881330654872638L, + 3912429093271518508L, + -2562542119887175820L, + 4835616088583228965L, + 427639171891209425L, + 2590582080178010045L, + -6288067880951692635L, + -3204510905067065501L, + 9008426291442999873L, + -4085962609397876083L, + -3786041297813905157L, + -6006475053574578261L, + -6174022276199807178L, + 7958957647277035097L, + 2915785807118517755L, + 2139592530283433011L, + -8562048562533248017L, + -4991735207930685025L, + 393144860250454082L, + -5852177196425420458L, + -2652303154023739579L, + 2079679586901234739L, + -1386526064824772584L, + 1574420554361329695L, + -855542130447493508L, + 8291940350733154044L, + -5330200233059892402L, + 5140782607921164290L, + -977254437067235218L, + -261520846651909307L, + -7369143208070837455L, + -4728766390712852111L, + -8572213434879266955L, + -6754813768712497692L, + 7946121307356573089L, + 504268959085012646L, + -5536654029698676818L, + -6021520522792328781L, + 6968613512520500871L, + 4029920623217569312L, + 2738878342460920492L, + 4562432005481165726L, + -1279037845195368028L, + 1746645308450474697L, + 2538150989161378915L, + 2012299649948738944L, + -3997559675475377347L, + -5939431505669672858L, + 2077103722387383456L, + -6188261335534632204L, + 8772504603740967633L, + -1653698997940568281L, + 1676948989756529271L, + 2377579815165102226L, + -2667481192445387240L, + -5498860615033631762L, + -2490865541169744469L, + -1233441883399707566L, + 5445263795307566596L, + 2288458809413275798L, + -5908274826918996877L, + 2909363406069168415L, + 2376032171261335687L, + -5215189045919902574L, + -6083327007632847329L, + 2462785604224107327L, + -6684045035730714275L, + 2409356208468676804L, + 2814747114160772803L, + -4529204412661254980L, + -8437511853472556883L, + 1819323657613892915L, + 6862685309651627151L, + -9210337863564319258L, + -3641041551811494963L, + -6791020794026796740L, + -5261661996953805298L, + -1953516254626596632L, + -5901591005960707793L, + -7413695905040596911L, + 2952256922297384020L, + -8427771021447591769L, + -6920139339436245233L, + 2967149838604559395L, + -3253499104068010353L, + -8473804925120692039L, + -3561285603521886085L, + -4453849179065102447L, + 2050092642498054323L, + -5626434133619314199L, + 7995075368278704248L, + 7685996432951370136L, + -8037783900933102779L, + 4601459625295412851L, + -4491938778497306775L, + -9089886217821142309L, + -3947191644612298897L, + 1364225714229764884L, + 2580394324892542249L, + -3765315378396862242L, + 6023794482194323576L, + -662753714084561214L, + 3080495347149127717L, + 911710215008202776L, + -803705685664586056L, + -6101059689379533503L, + -2122356322512227634L, + 8012110874513406695L, + -4158551223425336367L, + 8282080141813519654L, + 4172879384244246799L, + 708522065347490110L, + -6997269001146828181L, + 1887955086977822594L, + 8014460039616323415L + }; + + private static final long[] HASHES_OF_LOOPING_BYTES_WITH_SEED_42 = { + -7444071767201028348L, + -8959994473701255385L, + 7116559933691734543L, + 6019482000716350659L, + -6625277557348586272L, + -5507563483608914162L, + 1540412690865189709L, + 4522324563441226749L, + -7143238906056518746L, + -7989831429045113014L, + -7103973673268129917L, + -2319060423616348937L, + -7576144055863289344L, + -8903544572546912743L, + 6376815151655939880L, + 5913754614426879871L, + 6466567997237536608L, + -869838547529805462L, + -2416009472486582019L, + -3059673981515537339L, + 4211239092494362041L, + 1414635639471257331L, + 166863084165354636L, + -3761330575439628223L, + 3524931906845391329L, + 6070229753198168844L, + -3740381894759773016L, + -1268276809699008557L, + 1518581707938531581L, + 7988048690914090770L, + -4510281763783422346L, + -8988936099728967847L, + -8644129751861931918L, + 2046936095001747419L, + 339737284852751748L, + -8493525091666023417L, + -3962890767051635164L, + -5799948707353228709L, + -6503577434416464161L, + 7718729912902936653L, + 191197390694726650L, + -2677870679247057207L, + 20411540801847004L, + 2738354376741059902L, + -3754251900675510347L, + -3208495075154651980L, + 5505877218642938179L, + 6710910171520780908L, + -9060809096139575515L, + 6936438027860748388L, + -6675099569841255629L, + -5358120966884144380L, + -4970515091611332076L, + -1810965683604454696L, + -516197887510505242L, + 1240864593087756274L, + 6033499571835033332L, + 7223146028771530185L, + 909128106589125206L, + 1567720774747329341L, + -1867353301780159863L, + 4655107429511759333L, + 5356891185236995950L, + 182631115370802890L, + -3582744155969569138L, + 595148673029792797L, + 495183136068540256L, + 5536689004903505647L, + -8472683670935785889L, + -4335021702965928166L, + 7306662983232020244L, + 4285260837125010956L, + 8288813008819191181L, + -3442351913745287612L, + 4883297703151707194L, + 9135546183059994964L, + 123663780425483012L, + 509606241253238381L, + 5940344208569311369L, + -2650142344608291176L, + 3232776678942440459L, + -922581627593772181L, + 7617977317085633049L, + 7154902266379028518L, + -5806388675416795571L, + 4368003766009575737L, + -2922716024457242064L, + 4771160713173250118L, + 3275897444752647349L, + -297220751499763878L, + 5095659287766176401L, + 1181843887132908826L, + 9058283605301070357L, + 3984713963471276643L, + 6050484112980480005L, + 1551535065359244224L, + 565337293533335618L, + 7412521035272884309L, + -4735469481351389369L, + 6998597101178745656L, + -9107075101236275961L, + 5879828914430779796L, + 6034964979406620806L, + 5666406915264701514L, + -4666218379625258428L, + 2749972203764815656L, + -782986256139071446L, + 6830581400521008570L, + 2588852022632995043L, + -5484725487363818922L, + -3319556935687817112L, + 6481961252981840893L, + 2204492445852963006L, + -5301091763401031066L, + -2615065677047206256L, + -6769817545131782460L, + -8421640685322953142L, + -3669062629317949176L, + -9167016978640750490L, + 2783671191687959562L, + -7599469568522039782L, + -7589134103255480011L, + -5932706841188717592L, + -8689756354284562694L, + -3934347391198581249L, + -1344748563236040701L, + 2172701592984478834L, + -5322052340624064417L, + -8493945390573620511L, + 3349021988137788403L, + -1806262525300459538L, + -8091524448239736618L, + 4022306289903960690L, + -8346915997379834224L, + -2106001381993805461L, + -5784123934724688161L, + 6775158099649720388L, + -3869682756870293568L, + 4356490186652082006L, + 8469371446702290916L, + -2972961082318458602L, + -7188106622222784561L, + -4961006366631572412L, + 3199991182014172900L, + 2917435868590434179L, + 8385845305547872127L, + 7706824402560674655L, + -1587379863634865277L, + -4212156212298809650L, + -1305209322000720233L, + -7866728337506665880L, + 8195089740529247049L, + -4876930125798534239L, + 798222697981617129L, + -2441020897729372845L, + -3926158482651178666L, + -1254795122048514130L, + 5192463866522217407L, + -5426289318796042964L, + -3267454004443530826L, + 471043133625225785L, + -660956397365869974L, + -6149209189144999161L, + -2630977660039166559L, + 8512219789663151219L, + -3309844068134074620L, + -6211275327487847132L, + -2130171729366885995L, + 6569302074205462321L, + 4855778342281619706L, + 3867211421508653033L, + -3002480002418725542L, + -8297543107467502696L, + 8049642289208775831L, + -5439825716055425635L, + 7251760070798756432L, + -4774526021749797528L, + -3892389575184442548L, + 5162451061244344424L, + 6000530226398686578L, + -5713092252241819676L, + 8740913206879606081L, + -8693282419677309723L, + 1576205127972543824L, + 5760354502610401246L, + 3173225529903529385L, + 1785166236732849743L, + -1024443476832068882L, + -7389053248306187459L, + 1171021620017782166L, + 1471572212217428724L, + 7720766400407679932L, + -8844781213239282804L, + -7030159830170200877L, + 2195066352895261150L, + 1343620937208608634L, + 9178233160016731645L, + -757883447602665223L, + 3303032934975960867L, + -3685775162104101116L, + -4454903657585596656L, + -5721532367620482629L, + 8453227136542829644L, + 5397498317904798888L, + 7820279586106842836L, + -2369852356421022546L, + 3910437403657116169L, + 6072677490463894877L, + -2651044781586183960L, + 5173762670440434510L, + -2970017317595590978L, + -1024698859439768763L, + -3098335260967738522L, + -1983156467650050768L, + -8132353894276010246L, + -1088647368768943835L, + -3942884234250555927L, + 7169967005748210436L, + 2870913702735953746L, + -2207022373847083021L, + 1104181306093040609L, + 5026420573696578749L, + -5874879996794598513L, + -4777071762424874671L, + -7506667858329720470L, + -2926679936584725232L, + -5530649174168373609L, + 5282408526788020384L, + 3589529249264153135L, + -6220724706210580398L, + -7141769650716479812L, + 5142537361821482047L, + -7029808662366864423L, + -6593520217660744466L, + 1454581737122410695L, + -139542971769349865L, + 1727752089112067235L, + -775001449688420017L, + -5011311035350652032L, + -8671171179275033159L, + -2850915129917664667L, + -5258897903906998781L, + -6954153088230718761L, + -4070351752166223959L, + -6902592976462171099L, + -7850366369290661391L, + -4562443925864904705L, + 3186922928616271015L, + 2208521081203400591L, + -2727824999830592777L, + -3817861137262331295L, + 2236720618756809066L, + -4888946967413746075L, + -446884183491477687L, + -43021963625359034L, + -5857689226703189898L, + -2156533592262354883L, + -2027655907961967077L, + 7151844076490292500L, + -5029149124756905464L, + 526404452686156976L, + 8741076980297445408L, + 7962851518384256467L, + -105985852299572102L, + -2614605270539434398L, + -8265006689379110448L, + 8158561071761524496L, + -6923530157382047308L, + 5551949335037580397L, + 565709346370307061L, + -4780869469938333359L, + 6931895917517004830L, + 565234767538051407L, + -8663136372880869656L, + 1427340323685448983L, + 6492705666640232290L, + 1481585578088475369L, + -1712711110946325531L, + 3281685342714380741L, + 6441384790483098576L, + -1073539554682358394L, + 5704050067194788964L, + -5495724689443043319L, + -5425043165837577535L, + 8349736730194941321L, + -4123620508872850061L, + 4687874980541143573L, + -468891940172550975L, + -3212254545038049829L, + -6830802881920725628L, + 9033050533972480988L, + 4204031879107709260L, + -677513987701096310L, + -3286978557209370155L, + 1644111582609113135L, + 2040089403280131741L, + 3323690950628902653L, + -7686964480987925756L, + -4664519769497402737L, + 3358384147145476542L, + -4699919744264452277L, + -4795197464927839170L, + 5051607253379734527L, + -8987703459734976898L, + 8993686795574431834L, + -2688919474688811047L, + 375938183536293311L, + 1049459889197081920L, + -1213022037395838295L, + 4932989235110984138L, + -6647247877090282452L, + -7698817539128166242L, + -3264029336002462659L, + 6487828018122309795L, + -2660821091484592878L, + 7104391069028909121L, + -1765840012354703384L, + 85428166783788931L, + -6732726318028261938L, + 7566202549055682933L, + 229664898114413280L, + -1474237851782211353L, + -1571058880058007603L, + -7926453582850712144L, + 2487148368914275243L, + 8740031015380673473L, + 1908345726881363169L, + -2510061320536523178L, + 7854780026906019630L, + -6023415596650016493L, + -6264841978089051107L, + 4024998278016087488L, + -4266288992025826072L, + -3222176619422665563L, + -1999258726038299316L, + 1715270077442385636L, + 6764658837948099754L, + -8646962299105812577L, + -51484064212171546L, + -1482515279051057493L, + -8663965522608868414L, + -256555202123523670L, + 1973279596140303801L, + -7280796173024508575L, + -5691760367231354704L, + -5915786562256300861L, + -3697715074906156565L, + 3710290115318541949L, + 6796151623958134374L, + -935299482515386356L, + -7078378973978660385L, + 5379481350768846927L, + -9011221735308556302L, + 5936568631579608418L, + -6060732654964511813L, + -4243141607840017809L, + 3198488845875349355L, + -7809288876010447646L, + 4371587872421472389L, + -1304197371105522943L, + 7389861473143460103L, + -1892352887992004024L, + 2214828764044713398L, + 6347546952883613388L, + 1275694314105480954L, + -5262663163358903733L, + 1524757505892047607L, + 1474285098416162746L, + -7976447341881911786L, + 4014100291977623265L, + 8994982266451461043L, + -7737118961020539453L, + -2303955536994331092L, + 1383016539349937136L, + 1771516393548245271L, + -5441914919967503849L, + 5449813464890411403L, + -3321280356474552496L, + 4084073849712624363L, + 4290039323210935932L, + 2449523715173349652L, + 7494827882138362156L, + 9035007221503623051L, + 5722056230130603177L, + -5443061851556843748L, + -7554957764207092109L, + 447883090204372074L, + 533916651576859197L, + -3104765246501904165L, + -4002281505194601516L, + -8402008431255610992L, + -408273018037005304L, + 214196458752109430L, + 6458513309998070914L, + 2665048360156607904L, + 96698248584467992L, + -3238403026096269033L, + 6759639479763272920L, + -4231971627796170796L, + -2149574977639731179L, + -1437035755788460036L, + -6000005629185669767L, + 145244292800946348L, + -3056352941404947199L, + 3748284277779018970L, + 7328354565489106580L, + -2176895260373660284L, + 3077983936372755601L, + 1215485830019410079L, + 683050801367331140L, + -3173237622987755212L, + -1951990779107873701L, + -4714366021269652421L, + 4934690664256059008L, + 1674823104333774474L, + -3974408282362828040L, + 2001478896492417760L, + -4115105568354384199L, + -2039694725495941666L, + -587763432329933431L, + -391276713546911316L, + -5543400904809469053L, + 1882564440421402418L, + -4991793588968693036L, + 3454088185914578321L, + 2290855447126188424L, + 3027910585026909453L, + 2136873580213167431L, + -6243562989966916730L, + 5887939953208193029L, + -3491821629467655741L, + -3138303216306660662L, + 8572629205737718669L, + 4154439973110146459L, + 5542921963475106759L, + -2025215496720103521L, + -4047933760493641640L, + -169455456138383823L, + -1164572689128024473L, + -8551078127234162906L, + -7247713218016599028L, + 8725299775220778242L, + 6263466461599623132L, + 7931568057263751768L, + 7365493014712655238L, + -7343740914722477108L, + 8294118602089088477L, + 7677867223984211483L, + -7052188421655969232L, + -3739992520633991431L, + 772835781531324307L, + 881441588914692737L, + 6321450879891466401L, + 5682516032668315027L, + 8493068269270840662L, + -3895212467022280567L, + -3241911302335746277L, + -7199586338775635848L, + -4606922569968527974L, + -806850906331637768L, + 2433670352784844513L, + -5787982146811444512L, + 7852193425348711165L, + 8669396209073850051L, + -6898875695148963118L, + 6523939610287206782L, + -8084962379210153174L, + 8159432443823995836L, + -2631068535470883494L, + -338649779993793113L, + 6514650029997052016L, + 3926259678521802094L, + 5443275905907218528L, + 7312187582713433551L, + -2993773587362997676L, + -1068335949405953411L, + 4499730398606216151L, + 8538015793827433712L, + -4057209365270423575L, + -1504284818438273559L, + -6460688570035010846L, + 1765077117408991117L, + 8278320303525164177L, + 8510128922449361533L, + 1305722765578569816L, + 7250861238779078656L, + -576624504295396147L, + -4363714566147521011L, + -5932111494795524073L, + 1837387625936544674L, + -4186755953373944712L, + -7657073597826358867L, + 140408487263951108L, + 5578463635002659628L, + 3400326044813475885L, + -6092804808386714986L, + -2410324417287268694L, + 3222007930183458970L, + 4932471983280850419L, + 3554114546976144528L, + -7216067928362857082L, + -6115289896923351748L, + -6769646077108881947L, + 4263895947722578066L, + 2939136721007694271L, + 1426030606447416658L, + -1316192446807442076L, + 5366182640480055129L, + 6527003877470258527L, + 5849680119000207603L, + 5263993237214222328L, + -6936533648789185663L, + -9063642143790846605L, + 3795892210758087672L, + 4987213125282940176L, + 2505500970421590750L, + -1014022559552365387L, + -3574736245968367770L, + 1180676507127340259L, + -2261908445207512503L, + -8416682633172243509L, + 1114990703652673283L, + 7753746660364401380L, + 1874908722469707905L, + 2033421444403047677L, + 21412168602505589L, + 385957952615286205L, + 2053171460074727107L, + 1915131899400103774L, + 6680879515029368390L, + 568807208929724162L, + -6211541450459087674L, + -5026690733412145448L, + 1384781941404886235L, + -98027820852587266L, + 1806580495924249669L, + 6322077317403503963L, + 9078162931419569939L, + -2809061215428363978L, + 7697867577577415733L, + -5270063855897737274L, + 5649864555290587388L, + -6970990547695444247L, + 579684606137331754L, + 3871931565451195154L, + 2030008578322050218L, + -5012357307111799829L, + -2271365921756144065L, + 4551962665158074190L, + -3385474923040271312L, + -7647625164191633577L, + 6634635380316963029L, + -5201190933687061585L, + 8864818738548593973L, + 2855828214210882907L, + 9154512990734024165L, + -6945306719789457786L, + 1200243352799481087L, + 875998327415853787L, + 1275313054449881011L, + -6105772045375948736L, + -2926927684328291437L, + 9200050852144954779L, + 5188726645765880663L, + 5197037323312705176L, + 3434926231010121611L, + -5054013669361906544L, + 2582959199749224670L, + -6053757512723474059L, + -5016308176846054473L, + -2509827316698626133L, + 7700343644503853204L, + -1997627249894596731L, + 3993168688325352290L, + -8181743677541277704L, + 3719056119682565597L, + -7264411659282947790L, + 7177028972346484464L, + -5460831176884283278L, + 1799904662416293978L, + -6549616005092764514L, + 5472403994001122052L, + 8683463751708388502L, + -7873363037838316398L, + 689134758256487260L, + -1287443614028696450L, + 4452712919702709507L, + 762909374167538893L, + 6594302592326281411L, + 1183786629674781984L, + 5021847859620133476L, + -2490098069181538915L, + 5105145136026716679L, + 4437836948098585718L, + 1987270426215858862L, + 6170312798826946249L, + 634297557126003407L, + -1672811625495999581L, + 6282971595586218191L, + 4549149305727581687L, + -5652165370435317782L, + 1064501550023753890L, + -5334885527127139723L, + -6904378001629481237L, + -1807576691784201230L, + -205688432992053911L, + 7621619053293393289L, + 6258649161313982470L, + -1111634238359342096L, + -8044260779481691987L, + 400270655839010807L, + -7806833581382890725L, + -2970563349459508036L, + -7392591524816802798L, + 2918924613160219805L, + -6444161627929149002L, + 6096497501321778876L, + -1477975665655830038L, + 1690651307597306138L, + -2364076888826085362L, + -6521987420014905821L, + -4419193480146960582L, + 3538587780233092477L, + 8374665961716940404L, + 7492412312405424500L, + 6311662249091276767L, + -1240235198282023566L, + 5478559631401166447L, + 3476714419313462133L, + 377427285984503784L, + 2570472638778991109L, + -2741381313777447835L, + -7123472905503039596L, + 2493658686946955193L, + 1024677789035847585L, + -2916713904339582981L, + -4532003852004642304L, + -2202143560366234111L, + 5832267856442755135L, + -261740607772957384L, + 239435959690278014L, + 5755548341947719409L, + 6138795458221887696L, + -7709506987360146385L, + -6657487758065140444L, + -7006376793203657499L, + 6544409861846502033L, + 3171929352014159247L, + 1051041925048792869L, + 2617300158375649749L, + 952652799620095175L, + -576661730162168147L, + -1634191369221345988L, + 4833656816115993519L, + 647566759700005786L, + 2473810683785291822L, + 3005977181064745326L, + -3321881966853149523L, + 7595337666427588699L, + 6004093624251057224L, + -563917505657690279L, + 6117428527147449302L, + -6287297509522976113L, + -4527219334756214406L, + 742626429298092489L, + 3057351806086972041L, + 645967551210272605L, + -4428701157828864227L, + 3236379103879435414L, + -8477089892132066300L, + -6127365537275859058L, + -4052490484706946358L, + -8004854976625046469L, + -3679456917426613424L, + -8212793762082595299L, + -818288739465424130L, + 1358812099481667095L, + 7835987612195254310L, + -3663247409614323059L, + -2931105150130396604L, + 7296136776835614792L, + -2014557408985889628L, + 7267662411237959788L, + 3699280615819277743L, + -212010675469091396L, + -6518374332458360120L, + 145026010541628849L, + 1879297324213501001L, + -7146296067751816833L, + -5002958800391379931L, + 6060682439924517608L, + -432234782921170964L, + -6669688947353256956L, + 7728943532792041267L, + 830911367341171721L, + 3396934884314289432L, + -779464156662780749L, + 2330041851883352285L, + -4783350380736276693L, + -5758476056890049254L, + -7551552301614791791L, + 1253334187723911710L, + -2685018208308798978L, + 5379636036360946454L, + 6154668487114681217L, + -8641287462255458898L, + 4676087643800649558L, + -2405142641398691475L, + 1088685126864246881L, + 6431149082338374041L, + -607357695335069155L, + -720970692129524140L, + 2648766932394044468L, + 8408344790179354573L, + -6193808387735667350L, + 7722524628524697419L, + -6975433852560238120L, + -2925851029234475295L, + -4274458387165211028L, + -8355836377702147319L, + 5278146397877332061L, + 8502098812383680707L, + 2292836642336580326L, + -6127608082651070062L, + 2222301962240611208L, + -1930887695854799378L, + 7640503480494894592L, + 1162652186586436094L, + -1918002592943761683L, + 7648998601717261840L, + -8472603250832757057L, + -988877663117552456L, + 2368458128168026494L, + -6480813811998475245L, + -5896967824416018967L, + -2593783161701820446L, + 6950098417530252598L, + 6362589545555771236L, + 7981389665448567125L, + 3954017080198558850L, + 1626078615050230622L, + 6650159066527969109L, + 697345338922935394L, + -1226816215461768626L, + 8740408765973837440L, + -4194155864629568323L, + 7016680023232424746L, + 6043281358142429469L, + -4201005667174376809L, + 1216727117859013155L, + 6367202436544203935L, + 35414869396444636L, + 3715622794033998412L, + 488654435687670554L, + -2503747297224687460L, + 3147101919441470388L, + -8248611218693190922L, + 970697264481229955L, + 3411465763826851418L, + 9117405004661599969L, + -5204346498331519734L, + -19637460819385174L, + -5039124225167977219L, + 2990108874601696668L, + -2623857460235459202L, + 4256291692861397446L, + 6724147860870760443L, + 3558616688507246537L, + 6487680097936412800L, + -6470792832935928161L, + 4314814550912237614L, + -1292878983006062345L, + 6791915152630414174L, + 5971652079925815310L, + 2557529546662864312L, + 466175054322801580L, + -585216717310746872L, + -2486640422147349036L, + 7212029603994220134L, + 3958995069888972500L, + 4950471855791412790L, + -3721948842035712763L, + -6184503487488243051L, + 4079570444585775332L, + -3952156172546996872L, + 4543894231118208322L, + -1739995588466209963L, + 9155948355455935530L, + 5821980345462207860L, + -2431287667309520417L, + -3890108130519441316L, + -558124689277030490L, + 6079823537335801717L, + 5409742395192364262L, + -2329885777717160453L, + -7332804342513677651L, + 1466490574975950555L, + -420549419907427929L, + -5249909814389692516L, + -5145692168206210661L, + 5934113980649113921L, + 3241618428555359661L, + -6622110266160980250L, + 5048250878669516223L, + 5747219637359976174L, + 2975906212588223728L, + 5730216838646273215L, + -176713127129024690L, + 6734624279336671146L, + 5127866734316017180L, + 7111761230887705595L, + 3457811808274317235L, + 3362961434604932375L, + -1877869936854991246L, + 7171428594877765665L, + -8252167178400462374L, + -6306888185035821047L, + -6684702191247683887L, + -7754928454824190529L, + -1902605599135704386L, + -4037319846689421239L, + 8493746058123583457L, + -8156648963857047193L, + 2051510355149839497L, + -1256416624177218909L, + -3344927996254072010L, + -1838853051925943568L, + 316927471680974556L, + -1502257066700798003L, + -5836095610125837606L, + -1594125583615895424L, + 1442211486559637962L, + -144295071206619569L, + 5159850900959273410L, + 4589139881166423678L, + -7038726987463097509L, + 2886082400772974595L, + 2780759114707171916L, + 5694649587906297495L, + 1260349041268169667L, + 4921517488271434890L, + 644696475796073018L, + 6262811963753436289L, + -6128198676595868773L, + -3625352083004760261L, + -8751453332943236675L, + 8749249479868749221L, + -2450808199545048250L, + -6517435817046180917L, + -3433321727429234998L, + -2591586258908763451L, + 3847750870868804507L, + 6603614438546398643L, + -7598682191291031287L, + 8710261565627204971L, + 4753389483755344355L, + -4645333069458786881L, + -6742695046613492214L, + 643070478568866643L, + -7543096104151965610L, + 7171495384655926161L, + 595063872610714431L, + 3292310150781130424L, + 4326847806055440904L, + -4580020566072794152L, + 3142286571820373678L, + 5530356537440155930L, + 546372639737516181L, + 7401214477400367500L, + 7406531960402873109L, + 3287639667219172570L, + 4977301681213633671L, + 5253257820925174498L, + 2906216636104297878L, + 6142955758238347523L, + -3498651268741727235L, + -5875053958265588593L, + 3896719087169993883L, + -910904726885775073L, + 380107493197368177L, + -4993591912695447004L, + 2970487257212582761L, + 2551762717569548774L, + 953061649962736812L, + 8949739538606589463L, + -2962839167079475801L, + -1375673191272573835L, + 3761793818361866390L, + -389577789190726878L, + 5661262051502180269L, + -6558556411143987683L, + -702798336372315031L, + -336662820551371779L, + 998576401126580155L, + -5945021269112582755L, + 6108533925730179871L, + 2207095297001999618L, + -9042779159998880435L, + -6177868444342118372L, + 6775965402605895077L, + -3788428885163306576L, + 7790055010527190387L, + 3581587652196995358L, + -6176354155561607694L, + -5859381340906321207L, + 395898765763528395L, + 8132967590863909348L, + -3329092504090544483L, + -6785855381158040247L, + 1497218517051796750L, + -5352392845588925911L, + -6271364901230559194L, + 2314830370653350118L, + -7617588269001325450L, + 1423166885758213795L, + 8538612578307869519L, + -61918791718295474L, + -8177103503192338593L, + -4740086042584326695L, + 3677931948215558698L, + 6558856291580149558L, + 2674975452453336335L, + 5133796555646930522L, + 5139252693299337100L, + 7949476871295347205L, + 4407815324662880678L, + -3758305875280581215L, + 6066309507576587415L, + -7368508486398350973L, + -3181640264332856492L, + 6905100869343314145L, + 3677177673848733417L, + 8862933624870506941L, + -8575223195813810568L, + 9178470351355678144L, + 4677809017145408358L, + -1194833416287894989L, + 3436364743255571183L, + -5204770725795363579L, + 560599448536335263L, + -3192077522964776200L, + -751575299648803575L, + 6334581746534596579L, + -8358187891202563300L, + -1462480609823525055L, + 5605961062646987941L, + 4968399805931440889L, + 7968693270782626653L, + -5868205923557518188L, + 1830234928743560617L, + -8435261076693154407L, + 2138416970728681332L, + 8088740745199685138L, + 806532400344230520L, + 1800590379902909333L, + -8909128842071238901L, + -7357495566969170860L, + 3679766664126940553L, + 2060050474865839094L, + 2363972840121763414L, + 525695004292982714L, + -1224842191746529593L, + 7011317848855545003L, + -6337167558180299938L, + -5184688833363785939L, + -8426673387248359061L, + -5035438815930785229L, + 3521810320608058994L, + 4803742557254962242L, + 6623527039545786598L, + -1221475882122634738L, + -3344794405518401087L, + 6510298498414053658L, + 2844753907937720338L, + 90502309714994895L, + -750403235344282494L, + -4825474181021465833L, + -3405519947983849510L, + 3503875590944089793L, + 7286294700691822468L, + 7828126881500292486L, + 8437899353709338096L, + 136052254470293480L, + 1113259077339995086L, + -8244887265606191121L, + 8089569503800461649L, + -1429698194850157567L, + 1575595674002364989L, + 3576095286627428675L, + -7653655285807569222L, + -6053506977362539111L, + -3923855345805787169L, + -8001149080454232377L, + -4382867706931832271L, + 4212860258835896297L, + 4207674254247034014L, + 5519424058779519159L, + -754483042161434654L, + 1434113479814210082L, + -6416645032698336896L, + 5624329676066514819L, + -8229557208322175959L, + 3922640911653270376L, + 7826932478782081910L, + -4862787164488635842L, + 1449234668827944573L, + -1781657689570106327L, + 5442827552725289699L, + 3589862161007644641L, + 4787115581650652778L, + -3512152721942525726L, + -6750103117958685206L, + 5012970446659949261L, + 6797752795961689017L, + 5086454597639943700L, + -7616068364979994076L, + 1492846825433110217L, + 2967476304433704510L, + -8413824338284112078L, + -1319049442043273974L, + -1756090916806844109L, + -9061091728950139525L, + -6864767830358160810L, + 4879532090226251157L, + 5528644708740739488L + }; +}