)]}'
{
  "commit": "63fcb766dcc0030e6659e81a78c8991db7ecb83e",
  "tree": "d863f732175de1691edb9f60b2b5e75ed7722c4b",
  "parents": [
    "041ddb57a6c03d22d934721628375bace2bfd5cf"
  ],
  "author": {
    "name": "Lee Rhodes",
    "email": "leerho@users.noreply.github.com",
    "time": "Mon Sep 07 19:35:16 2026 -0700"
  },
  "committer": {
    "name": "Lee Rhodes",
    "email": "leerho@users.noreply.github.com",
    "time": "Mon Sep 07 19:35:16 2026 -0700"
  },
  "message": "Add UpdatableThetaSketch.compactTrimmed() to compact and reduce to k in one pass\n\nAn update sketch retains more than the nominal size k between rebuilds. Callers\nwho need a result bounded by k currently have to call rebuild(), which mutates\nthe sketch and rebuilds its hash table, before compact().\n\nThis adds two concrete methods on UpdatableThetaSketch:\n\n    public CompactThetaSketch compactTrimmed()\n    public CompactThetaSketch compactTrimmed(boolean dstOrdered, MemorySegment dstWSeg)\n\nBoth are concrete on the base, so none of the subclasses change. A separate\nmethod rather than a trim flag on compact(): Java has no default parameter\nvalues, so a flag would only ever be passed true, and compact(dstOrdered,\nMemorySegment) is abstract with seven overriders, so its signature cannot grow\na parameter in any case.\n\nThe implementation gathers the valid entries into a dense array, since the\nmethod must not modify the sketch and QuickSelect.select permutes whatever\narray it is given, then selects 0-based index k. That is the same hash value\nthe (k + 1) 1-based pivot yields in rebuild(), so the two cannot drift apart,\nand a test asserts the result serializes byte-for-byte identically to\nrebuild() + compact().\n\nBecause it never mutates, this also works on a read-only sketch, where\nrebuild() throws SketchesReadOnlyException.\n\nThe Alpha family is excluded and throws UnsupportedOperationException: it\nmaintains theta by its own discipline and never needs reducing to k. The guard\nis a family denylist rather than a QuickSelect allowlist, because Theta\u0027s\nfamily names are historically fragmented and an allowlist could wrongly reject\na legitimate member.\n\nTrimming stays an explicit opt-in because it is lossy. Relative error scales\nwith 1 / sqrt(retained), so discarding entries always widens the confidence\nbounds, and a sketch in exact mode that retains more than k loses exactness and\nis returned in estimation mode. Both effects are documented and pinned by tests.\n\nThis is the Java counterpart of apache/datasketches-cpp#524.\n\nCo-Authored-By: Claude Opus 5 \u003cnoreply@anthropic.com\u003e\nClaude-Session: https://claude.ai/code/session_017EDHa7UhfW4eSj5L82panJ\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "8b75c7883c92f5017954aa702c0f167200be1321",
      "old_mode": 33188,
      "old_path": "src/main/java/org/apache/datasketches/theta/UpdatableThetaSketch.java",
      "new_id": "693fa02dbb74de6dbb7de9ce5dd2fb2cd02a71de",
      "new_mode": 33188,
      "new_path": "src/main/java/org/apache/datasketches/theta/UpdatableThetaSketch.java"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "6e9cfac3d1391aab4ed60af7c0d22b0ca477cc62",
      "new_mode": 33188,
      "new_path": "src/test/java/org/apache/datasketches/theta/CompactTrimTest.java"
    }
  ]
}
