Skip to content

Issue 173 bytea jdbctype#182

Open
stalep wants to merge 1 commit into
Hyperfoil:mainfrom
stalep:issue_173_bytea_jdbctype
Open

Issue 173 bytea jdbctype#182
stalep wants to merge 1 commit into
Hyperfoil:mainfrom
stalep:issue_173_bytea_jdbctype

Conversation

@stalep

@stalep stalep commented Jul 5, 2026

Copy link
Copy Markdown
Member

No description provided.

@stalep

stalep commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

Allocation profiling results: boot-time-verbose import (50 runs, batch=5, cores=4, 8GB heap)

Profiled with async-profiler alloc event at 30-second intervals during a boot-time-verbose legacy import. Three runs compared:

Baseline (no fixes — JSONB, sql/sqlall nodes, String encoding)

Snapshot Total byte[] StringBuilder PG wire UTF-8 encode String decode WorkQueue JqParse
30s 9,785 MB 6,980 2,547 1,177 895 1,053 371 1,888
70s 11,719 MB 6,687 2,607 971 838 971 1,551 1,773

Result: OOM at ~50s, ~4,200 values processed before crash.

With #154 only (sql→jq, but still JSONB + String encoding)

Snapshot Total byte[] StringBuilder PG wire UTF-8 encode String decode WorkQueue JqParse
30s 14,607 MB 7,903 2,221 1,912 873 1,909 95 3,434

Result: OOM at ~60s, ~10,150 values. Faster throughput but higher peak allocation from in-memory jq evaluation.

With all fixes including #173 BYTEA + JqValueJdbcType

Snapshot Total byte[] StringBuilder PG wire UTF-8 encode String decode WorkQueue JqParse
30s 16,258 MB 8,183 1 1,510 0 4 755 2,747
70s 18,011 MB 9,394 0 1,274 0 1 786 2,388

Result: Completes successfully in 105s, 28,200 values. No OOM.

Summary of #173 impact

Encoding step Baseline (MB/10s) With #173 (MB/10s) Reduction
StringBuilder (toJsonString → serialize) 2,547 1 99.96%
String.encodeUTF8 (JDBC param encoding) 895 0 100%
Encoding.decode (JDBC result decoding) 1,053 4 99.6%

The serializeToBytes() near-zero-alloc path and getBytes()/setBytes() JDBC operations completely eliminate the String intermediaries that were the primary allocation bottleneck. For deferred-from-bytes JqString values (the common case for data flowing through parse→jq→serialize), the appendToBytes() path does zero-copy raw byte copying from the source array.

Performance comparison

Metric Baseline All fixes + #173
Values at 30s 1,413 7,477
Final values ~4,200 (OOM) 28,200 (complete)
Time OOM at ~50s 105s (clean exit)
Throughput ~84 vals/sec ~268 vals/sec
OOM? Yes No

3.2x throughput improvement and the import actually completes on 8GB heap for the first time.

@stalep
stalep force-pushed the issue_173_bytea_jdbctype branch from 55b6fd3 to 5a1da4b Compare July 8, 2026 07:51
@stalep
stalep marked this pull request as ready for review July 8, 2026 07:51
@stalep
stalep force-pushed the issue_173_bytea_jdbctype branch 2 times, most recently from b8e3009 to 2bd7590 Compare July 10, 2026 16:07
…qValue persistence (issue Hyperfoil#173)

Switch ValueEntity.data from JSONB to BYTEA with JqValueJdbcType from
jjq-jakarta 0.1.7, enabling direct byte[]-based JDBC I/O:

Write: JqValues.serializeToBytes(value) -> setBytes() (near-zero alloc)
Read:  getBytes() -> JqValues.parse(byte[]) (SWAR-optimized)

This eliminates the String intermediaries that dominated allocation
during bulk imports: toJsonString() on writes, String.encodeUTF8 for
JDBC encoding, and getString() decoding on reads.

Changes:
- ValueEntity.data: JSONB -> BYTEA, @JdbcType(JqValueJdbcType.class),
  @javatype(JqValueJavaType.class), remove @mutability (handled by
  JqValueJavaType ImmutableMutabilityPlan)
- Delete DatabaseJsonFormatMapper (FormatMapper no longer needed)
- Remove quarkus.hibernate-orm.mapping.format.global=ignore
- Update jjq dependency to 0.1.7 (released)
- WorkService: native UPDATE uses setBytes() with serializeToBytes(),
  remove dbKind switch (same SQL for both databases)
- ValueService fingerprint matching: BYTEA equality (v.data = :fp),
  pass byte[] parameter via serializeToBytes()
- ValueService domain comparison: convert_from(v.data, 'UTF-8')::jsonb
  for PostgreSQL, CAST(v.data AS TEXT) for SQLite
- ValueService sorter CTE: convert BYTEA to jsonb/text for domain
  ordering (fixes E-Divisive lexicographic byte sorting)
- ValueService aggregation (getGroupedValues): convert BYTEA to
  jsonb/text in tree CTE base case
- Unify sqlite/postgresql SQL where BYTEA makes them identical
- VerifyLegacy: convert_from for text display
- RecalculateTest: use byte[] parameter for native UPDATE
@stalep
stalep force-pushed the issue_173_bytea_jdbctype branch from 2bd7590 to 070088e Compare July 16, 2026 15:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant