Skip to content

feat: add article for when to use Bloom Filter#7928

Open
ankur-arch wants to merge 11 commits into
mainfrom
bloom-filter-blog-ankur
Open

feat: add article for when to use Bloom Filter#7928
ankur-arch wants to merge 11 commits into
mainfrom
bloom-filter-blog-ankur

Conversation

@ankur-arch
Copy link
Copy Markdown
Contributor

@ankur-arch ankur-arch commented May 31, 2026

Summary by CodeRabbit

  • New Features

    • Interactive demos: animated Bloom filter, B-tree, and hash walkthroughs; step-driven "code + terminal" runner with playback, navigation, and copyable terminal output; author listing and per-author pages with linked author names.
  • Documentation

    • New blog post on Postgres bloom indexes with a practical demo; added series metadata to an existing post.
  • Style

    • Global UI/demo styles and animations updated for improved layout, responsiveness, and transitions.
  • Bug Fixes

    • Code highlighting now recognizes SQL-style mark directives.
  • Chores

    • Spell dictionary updated; blog series registry and author utilities added.

ankur-arch and others added 6 commits May 28, 2026 14:02
Adds a new post explaining the Postgres bloom index for wide cache-style
tables, with a CodeHike-powered animated walkthrough of the bloom
algorithm (BloomFilterDemo) and two AgentPrompt animations for the SQL
schema morph and a recorded run of the bun demo.

Extends AgentPrompt's mark extractor to recognize SQL "-- !mark"
comments so the schema morph can highlight added lines.

Sample numbers were captured by running the live demo in
demos-for-content/bun-bloom-filters against a temporary Prisma Postgres
DB.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The two follow-up animations in the bloom blog were prompt-style chat
bubbles, but neither one is actually a prompt - both are commands /
schema changes. Replaces them with structures that match what they are:

- "How Postgres turns this into an index" now shows a static SQL block
  instead of a morph animation.
- "Run it" now uses a new BloomDemoRunner: code panel on the left with
  the currently-executing slice of index.ts highlighted, terminal panel
  on the right that fills cumulatively, six clickable labeled steps,
  plus prev / play-pause / next. Each step has a one-line caption
  explaining what that section of code does.

Also slows the bloom filter visualization (5.2s per step) and adds the
same prev / play-pause / next controls plus clickable step pills, so
readers can move through the algorithm at their own pace.

Drops the obsolete snippets.ts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The runner looked broken because the terminal showed only the current
step's two output lines, leaving most of the panel empty. And the
side-by-side 1.4fr:1fr split was too cramped at the blog's article
width (~768px), so the code panel was narrow enough to force horizontal
scrolling on every long line.

Fixes:

- Terminal now shows the full output across all six steps from the
  start. Lines for past steps are dimmed (60%), the current step's
  lines have a green border and full opacity, future lines are faintly
  visible. Auto-scrolls to the active line on advance.
- Code panel auto-scrolls so the highlighted slice is in view.
- Side-by-side now uses 1:1 split.
- Container query: when the runner element itself drops below 720px
  the body stacks vertically (code above terminal) so the blog body
  width never forces side-by-side at unreadable sizes.
- Each pane gets a small uppercase label (INDEX.TS, TERMINAL OUTPUT)
  so the relationship is obvious.
- Step counter now includes the active step's title; nav buttons are
  bordered 28px squares instead of unlabeled 24px gray icons.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The post jumped from a bloom-filter visualization straight to Postgres
bloom indexes without explaining how the two relate, and it kept using
btrees as the comparison baseline without ever describing what a btree
is or what it gives you.

- New "A quick refresher on btrees" section before the problem
  statement: walks through what a btree is, what it does well (exact
  lookup, range, sort), and where its costs land as indexes accumulate.
- New "From a bloom filter to a bloom index" section after the
  visualization: explicitly connects the single-bit-array filter the
  reader just played with to the per-row signature an index stores.
- "When to use it" expanded with concrete SQL examples for each bullet
  (wide tables, mixed filter subsets, write amplification, recheck
  overhead).
- "When not to use it" recast with bolded leads and the actual reason
  next to each.
- Trimmed filler ("That's the whole idea.", redundant recap line about
  being smaller and faster) and minor grammar fixes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Replace "btree" / "btrees" with "B-tree" / "B-trees" in the bloom
  filter blog's prose, meta description, runner step titles, captions,
  and the displayed terminal output. JS identifiers (btreeMB, btreeMs)
  and the literal Postgres index name prefix (btree_<col>) stay as is.
- Add btree, btrees, Btree, Btrees to the repo's cspell dictionary so
  the variant spellings inside code identifiers and index names do not
  trip the docs spellcheck.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…button

Two fixes for the runner terminal pane:

- Active-step highlight was being clipped at the original parent width
  when the line content overflowed horizontally. The line div's box was
  staying at parent-content-box width while the text overflowed past
  it, so the green background stopped at the visible viewport edge.
  Switching the line to "width: max-content; min-width: 100%" makes
  the box grow to the content's width when wide and to the parent's
  width when short, so the background covers the whole scrollable
  line on both axes.

- New "Copy" button in the terminal pane label that puts the full
  cumulative output on the clipboard. Uses navigator.clipboard and
  flips the label to "Copied" with a Check icon for 1.6s after a
  successful copy. The setTimeout is tracked in a ref and cleaned up
  on unmount.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 31, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
blog Ready Ready Preview, Comment Jun 1, 2026 3:15pm
docs Ready Ready Preview, Comment Jun 1, 2026 3:15pm
eclipse Ready Ready Preview, Comment Jun 1, 2026 3:15pm
site Ready Ready Preview, Comment Jun 1, 2026 3:15pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 31, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0f590a10-1edf-4ec6-b21e-023e8b997c32

📥 Commits

Reviewing files that changed from the base of the PR and between 03cc01c and ad16f87.

📒 Files selected for processing (4)
  • apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BTreeDemo.tsx
  • apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BTreeDemoClient.tsx
  • apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BloomDemoRunnerClient.tsx
  • apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/HashDemoClient.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BTreeDemo.tsx
  • apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BloomDemoRunnerClient.tsx
  • apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BTreeDemoClient.tsx

Walkthrough

Adds a new MDX article on Postgres bloom indexes plus interactive demos (bloom filter, bloom-index benchmark runner, B-tree walkthrough, hash walkthrough), server-side highlighting wrappers, client visualizers, demo CSS, small AgentPrompt mark parsing tweak, cspell entries, and author/profile pages.

Changes

Bloom Index Blog Post and Demos

Layer / File(s) Summary
Bloom Filter Interactive Demo
apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BloomFilterDemo.tsx, apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BloomFilterDemoClient.tsx
Server component highlights TypeScript snippets and passes HighlightedCode[] to BloomFilterDemoClient, which drives a phased 16-bit bloom-filter walkthrough with SmoothPre token-transition animations, visibility-gated autoplay, bit-grid UI, verdict text, and step controls.
Bloom Index Benchmark Runner
apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BloomDemoRunner.tsx, apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BloomDemoRunnerClient.tsx
Server component embeds a multi-step SOURCE SQL/TS demo and STEPS metadata, highlights the source, and renders BloomDemoRunnerClient. The client manages step navigation, play/pause with IntersectionObserver gating, per-step code marking, synchronized scrolling of code and terminal panes, and clipboard copy of terminal output.
B-tree Walkthrough
apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BTreeDemo.tsx, apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BTreeDemoClient.tsx
Server highlights a B-tree lookup snippet and renders BTreeDemoClient, which advances phases with visibility-aware autoplay, applies per-phase code marks, visualizes nodes/edges/leaves, and shows per-phase captions and results.
Hash Functions Demo
apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/HashDemo.tsx, apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/HashDemoClient.tsx
Server highlights hash-function example code and renders HashDemoClient, which animates per-phase hash steps, marks active source lines, shows pipe/raw/mod/bit indices, and renders a bit grid for probing/lit bits with navigation and autoplay gating.
Interactive Demo Styling
apps/blog/src/app/global.css
Adds .bloom-demo, .runner, .btree-demo, and .hash-demo styles (variables, layout, cell/grid states, flip/probe animations, responsive and container-query rules) and expands/refactors several .agent-prompt transition/@keyframes declarations into multi-line block form.
Blog Post: PostgreSQL Bloom Indexes
apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/index.mdx
New MDX article with frontmatter, conceptual explanation of bloom filters, Postgres bloom index details and SQL examples, embedded demos (hash/btree/bloom), the six-B-tree vs one-bloom comparison, and guidance on fit/avoid criteria.
Code Marker Detection and Configuration
apps/blog/src/components/AgentPrompt/index.tsx, apps/docs/cspell.json
extractMarks now recognizes -- !mark SQL/shell-style directives alongside // !mark and # !mark; related highlight helper refactored. CSpell dictionary adds btree, btrees, Btree, Btrees.
Author Pages and Helpers
apps/blog/src/app/(blog)/author/[slug]/page.tsx, apps/blog/src/lib/authors-pages.ts, apps/blog/src/components/AuthorAvatarGroup.tsx
Adds author listing route, static param/metadata generation, authors-pages.ts utilities to gather profiles and posts, and updates AuthorAvatarGroup to optionally link author names to author pages.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • prisma/web#7902: Related changes touching AgentPrompt mark/directive handling and the highlighting pipeline.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main change: a new blog article explaining when to use Bloom Filters, which is the primary focus of the changeset including new demo components and the MDX article.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@argos-ci
Copy link
Copy Markdown

argos-ci Bot commented May 31, 2026

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Jun 1, 2026, 3:23 PM

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BloomDemoRunner.tsx`:
- Around line 91-100: The caption claims "Drop the B-trees" but the SOURCE block
never drops them, so update SOURCE (the block that creates indexes and measures
bloomMB via totalIndexMB()) to make the measurement honest: either (A) insert
DROP INDEX IF EXISTS statements for the six per-column B-tree indexes (the same
index names created earlier) immediately before the CREATE INDEX … USING bloom
so bloomMB reflects only the bloom index, or (B) change the caption string in
the object with title "B: One bloom index" to remove the "Drop the B-trees"
wording so it accurately matches the code; modify the SOURCE block or the
caption accordingly and ensure bloomMB = await totalIndexMB() then measures the
intended state.
- Around line 108-112: The hardcoded "70% smaller" in the output array conflicts
with the computed percentage (1 - bloomMB / btreeMB) * 100 and the byte figures;
update the output to compute and inject the actual percentage using the existing
bloomMB and btreeMB values (or else change the byte figures to match 70%), i.e.
replace the literal "70% smaller" string with a formatted value derived from the
computed percentage expression used elsewhere (referencing bloomMB and btreeMB)
so the output array and BloomDemoRunner.tsx's displayed numbers stay consistent.

In
`@apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BloomDemoRunnerClient.tsx`:
- Around line 107-115: In copyOutput(), handle rejection from
navigator.clipboard.writeText by chaining a .catch handler on the returned
promise (keeping the existing .then path); inside the .catch log or process the
error (e.g., processLogger/error or console.error) and ensure UI state is
consistent (don’t setCopied(true) on failure and clear any pending
copyTimeoutRef as needed), referencing the copyOutput function,
navigator.clipboard.writeText call, setCopied, copyTimeoutRef, and allOutput to
locate the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a089a0fc-0eda-4eb1-b5a5-bfe2193d9c08

📥 Commits

Reviewing files that changed from the base of the PR and between ffe9059 and 2c28d38.

📒 Files selected for processing (8)
  • apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BloomDemoRunner.tsx
  • apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BloomDemoRunnerClient.tsx
  • apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BloomFilterDemo.tsx
  • apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BloomFilterDemoClient.tsx
  • apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/index.mdx
  • apps/blog/src/app/global.css
  • apps/blog/src/components/AgentPrompt/index.tsx
  • apps/docs/cspell.json

Comment on lines +91 to +100
{
title: "B: One bloom index",
caption:
"Drop the B-trees and create a single bloom index spanning all six columns. Same three lookups.",
lines: { from: 37, to: 43 },
output: [
"",
"B. One bloom index (all six columns)...",
" index size: 0.2 MB",
" 3 lookups: 302.7 ms",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Caption says "drop the B-trees" but the script never does.

The step caption promises "Drop the B-trees and create a single bloom index", yet section B of SOURCE (lines 37-43) only runs CREATE INDEX … USING bloom — there's no DROP INDEX. Since bloomMB = await totalIndexMB() measures total index size, leaving the six B-trees in place means the bloom-vs-btree comparison would be measuring btrees+bloom against btrees if a reader actually ran it. Either add the drop to the source so the measurement is honest, or soften the caption to match what the code does.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BloomDemoRunner.tsx`
around lines 91 - 100, The caption claims "Drop the B-trees" but the SOURCE
block never drops them, so update SOURCE (the block that creates indexes and
measures bloomMB via totalIndexMB()) to make the measurement honest: either (A)
insert DROP INDEX IF EXISTS statements for the six per-column B-tree indexes
(the same index names created earlier) immediately before the CREATE INDEX …
USING bloom so bloomMB reflects only the bloom index, or (B) change the caption
string in the object with title "B: One bloom index" to remove the "Drop the
B-trees" wording so it accurately matches the code; modify the SOURCE block or
the caption accordingly and ensure bloomMB = await totalIndexMB() then measures
the intended state.

Comment on lines +108 to +112
output: [
"",
" Bloom index is 70% smaller (0.2 MB vs 0.5 MB),",
" and one index covers any subset of those six columns.",
],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

The "70% smaller" figure doesn't match the numbers next to it.

Here's the arithmetic the script itself uses on line 48: (1 - bloomMB / btreeMB) * 100. With 0.2 MB vs 0.5 MB that's (1 - 0.2/0.5) * 100 = 60%, not 70%. Note the MDX prose (line 119) describes it as "roughly 2.5x smaller", and 0.5 / 0.2 = 2.5 — so the prose is right and this hardcoded output is the outlier. Either correct the percentage or adjust the byte figures so the demo and the article tell the same story.

📐 Proposed fix
-      "   Bloom index is 70% smaller (0.2 MB vs 0.5 MB),",
+      "   Bloom index is 60% smaller (0.2 MB vs 0.5 MB),",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
output: [
"",
" Bloom index is 70% smaller (0.2 MB vs 0.5 MB),",
" and one index covers any subset of those six columns.",
],
output: [
"",
" Bloom index is 60% smaller (0.2 MB vs 0.5 MB),",
" and one index covers any subset of those six columns.",
],
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BloomDemoRunner.tsx`
around lines 108 - 112, The hardcoded "70% smaller" in the output array
conflicts with the computed percentage (1 - bloomMB / btreeMB) * 100 and the
byte figures; update the output to compute and inject the actual percentage
using the existing bloomMB and btreeMB values (or else change the byte figures
to match 70%), i.e. replace the literal "70% smaller" string with a formatted
value derived from the computed percentage expression used elsewhere
(referencing bloomMB and btreeMB) so the output array and BloomDemoRunner.tsx's
displayed numbers stay consistent.

Comment on lines +107 to +115
function copyOutput() {
const text = allOutput.map((e) => e.line).join("\n");
if (!navigator.clipboard) return;
navigator.clipboard.writeText(text).then(() => {
setCopied(true);
if (copyTimeoutRef.current) clearTimeout(copyTimeoutRef.current);
copyTimeoutRef.current = setTimeout(() => setCopied(false), 1600);
});
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a .catch to the clipboard write.

navigator.clipboard.writeText returns a promise that can reject — denied permission, a non-secure context, or the user dismissing a prompt. Right now a rejection becomes an unhandled promise rejection and the "Copied" state silently never appears. A small catch keeps things tidy and lets you optionally surface a failure.

🛡️ Proposed fix
-    navigator.clipboard.writeText(text).then(() => {
-      setCopied(true);
-      if (copyTimeoutRef.current) clearTimeout(copyTimeoutRef.current);
-      copyTimeoutRef.current = setTimeout(() => setCopied(false), 1600);
-    });
+    navigator.clipboard
+      .writeText(text)
+      .then(() => {
+        setCopied(true);
+        if (copyTimeoutRef.current) clearTimeout(copyTimeoutRef.current);
+        copyTimeoutRef.current = setTimeout(() => setCopied(false), 1600);
+      })
+      .catch(() => {
+        /* clipboard unavailable or permission denied */
+      });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function copyOutput() {
const text = allOutput.map((e) => e.line).join("\n");
if (!navigator.clipboard) return;
navigator.clipboard.writeText(text).then(() => {
setCopied(true);
if (copyTimeoutRef.current) clearTimeout(copyTimeoutRef.current);
copyTimeoutRef.current = setTimeout(() => setCopied(false), 1600);
});
}
function copyOutput() {
const text = allOutput.map((e) => e.line).join("\n");
if (!navigator.clipboard) return;
navigator.clipboard
.writeText(text)
.then(() => {
setCopied(true);
if (copyTimeoutRef.current) clearTimeout(copyTimeoutRef.current);
copyTimeoutRef.current = setTimeout(() => setCopied(false), 1600);
})
.catch(() => {
/* clipboard unavailable or permission denied */
});
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BloomDemoRunnerClient.tsx`
around lines 107 - 115, In copyOutput(), handle rejection from
navigator.clipboard.writeText by chaining a .catch handler on the returned
promise (keeping the existing .then path); inside the .catch log or process the
error (e.g., processLogger/error or console.error) and ensure UI state is
consistent (don’t setCopied(true) on failure and clear any pending
copyTimeoutRef as needed), referencing the copyOutput function,
navigator.clipboard.writeText call, setCopied, copyTimeoutRef, and allOutput to
locate the change.

The post opened with a B-tree primer, which felt wrong for a piece
titled "Bloom Filters in Postgres" - the reader landed on a paragraph
about a different index type before anything else. The "The problem it
solves" heading also used a bare "it" with no clear antecedent.

- Reordered sections: bloom filter concept and visualization come first,
  followed by the bloom-filter-to-bloom-index bridge, then the
  wide-table use case, then the B-tree primer (now framed as
  comparison context right before the demo).
- Renamed "The problem it solves" to "The wide-table problem".
- Added a one-line lead to the B-tree primer explaining why it shows
  up at that point in the article.
- Reworded the intro's "what it is, when it wins" pointer to match the
  new section order.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… and hash demos

- Hero image: copied the new "Bloom Filters in Postgres" PNG into the
  blog's public folder; set heroImagePath, metaImagePath and
  heroImageAlt on the post frontmatter.

- Series: marked this post as part of a new "postgres-features"
  series at index 2. Updated the previous post
  (you-dont-need-redis-postgres-already-has-pub-sub) to be index 1 of
  the same series. Added a short intro paragraph linking back to the
  Pub/Sub post.

- BTreeDemo: new CodeHike-driven walkthrough of a B-tree lookup.
  Single shared pseudocode block with the active line marked per
  step; a small 2-level tree (root with 2 keys, 3 leaves of 3
  entries each) highlights the active node and the matched key as
  the lookup descends to find "t42" -> row 142. Six labeled steps
  with prev/play/next and clickable pills.

- HashDemo: new CodeHike-driven walkthrough of the hashes() function
  used by the bloom filter. Shows three independent hashes (fnv1a,
  djb2, murmur3) running on "alice", their raw outputs, the mod 16
  step, and the three bit positions [2, 7, 11] lighting up on a
  16-cell array. Five labeled steps.

- Famous-users line: added a one-liner naming where bloom filters
  show up in production (Chrome safe browsing, Cassandra/HBase,
  Akamai, Medium, Bitcoin SPV).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BTreeDemo.tsx`:
- Around line 26-63: Phases are off-by-one against SOURCE because line numbering
is mismatched; update the phase data and/or the mapping logic in codeForPhase so
indices align: either change the literal phase entries—set lookup("t42") to
{from:10,to:10} and set "Search the leaf" and "Return the row pointer" to
{from:7,to:7}—or (preferable) fix codeForPhase to treat SOURCE as having 1-based
line numbers (clamp requested from/to to [1, lineCount] and convert to
zero-based when slicing) so all phase labels (e.g., "lookup(\"t42\")", "Pick the
child", "Search the leaf", "Return the row pointer") produce the correct
highlighted lines.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 019dee17-7391-4873-a12a-9914840ca984

📥 Commits

Reviewing files that changed from the base of the PR and between 9bca8e1 and 25db701.

⛔ Files ignored due to path filters (1)
  • apps/blog/public/postgres-bloom-index-the-overlooked-postgres-feature/imgs/bloom-filters-in-postgres.png is excluded by !**/*.png
📒 Files selected for processing (7)
  • apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BTreeDemo.tsx
  • apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/BTreeDemoClient.tsx
  • apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/HashDemo.tsx
  • apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/HashDemoClient.tsx
  • apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/index.mdx
  • apps/blog/content/blog/you-dont-need-redis-postgres-already-has-pub-sub/index.mdx
  • apps/blog/src/app/global.css
✅ Files skipped from review due to trivial changes (1)
  • apps/blog/content/blog/postgres-bloom-index-the-overlooked-postgres-feature/index.mdx

- Add the postgres-features series to the series registry so
  /blog/series/postgres-features stops 404ing and renders the two
  posts in it (the Pub/Sub post and the Bloom Filters post). Marked
  featured so it surfaces on the home shelf.

- New /blog/author/[slug] route. Slug uses the existing toAuthorSlug
  helper, so "Ankur Datta" -> ankur-datta and so on. Page lists every
  post that includes the author, newest first. generateStaticParams
  enumerates the union of author slugs across the corpus.

- New lib/authors-pages.ts collecting unique author profiles
  (slug, display name, avatar src, post count) and the per-slug post
  filter.

- AuthorAvatarGroup now links each author name to the author landing
  page. The link can be turned off with linkAuthors={false} where the
  parent doesn't want it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/blog/src/app/(blog)/author/[slug]/page.tsx (1)

7-7: ⚡ Quick win

Drop the unused blog import and the void blog; placeholder.

Here's the teaching moment: void blog; is doing nothing functional — it just evaluates the reference and discards it. Its only purpose is to silence an "unused import" lint warning. If a symbol isn't used, the cleaner answer is to not import it at all. Importing @/lib/source purely as a side-effect anchor is a trap for the next maintainer, who will reasonably wonder what invariant that line protects. (If the import is meant to trigger module side-effects, that intent should be documented explicitly rather than expressed as void.)

♻️ Proposed cleanup
-import { blog } from "`@/lib/source`";
 import {
   findAuthorProfile,
   getAllAuthorProfiles,
   getPostsByAuthorSlug,
 } from "`@/lib/authors-pages`";
-
-void blog;

Also applies to: 129-129

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/blog/src/app/`(blog)/author/[slug]/page.tsx at line 7, Remove the unused
imported symbol blog from the import of "`@/lib/source`" and delete the
corresponding void blog; placeholder; if the import was intended to trigger
module side-effects instead of providing blog, replace with an explicit
side-effect import (e.g., import "`@/lib/source`" with a comment) or add a clear
comment explaining the intent — otherwise simply drop the import and placeholder
to clean lint warnings and avoid confusion.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@apps/blog/src/app/`(blog)/author/[slug]/page.tsx:
- Line 7: Remove the unused imported symbol blog from the import of
"`@/lib/source`" and delete the corresponding void blog; placeholder; if the
import was intended to trigger module side-effects instead of providing blog,
replace with an explicit side-effect import (e.g., import "`@/lib/source`" with a
comment) or add a clear comment explaining the intent — otherwise simply drop
the import and placeholder to clean lint warnings and avoid confusion.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: be9250e8-52f5-4e8e-951f-712368e7fb3c

📥 Commits

Reviewing files that changed from the base of the PR and between 25db701 and 03cc01c.

📒 Files selected for processing (4)
  • apps/blog/src/app/(blog)/author/[slug]/page.tsx
  • apps/blog/src/components/AuthorAvatarGroup.tsx
  • apps/blog/src/lib/authors-pages.ts
  • apps/blog/src/lib/series-registry.ts
✅ Files skipped from review due to trivial changes (1)
  • apps/blog/src/lib/series-registry.ts

Two phases of the BTreeDemo referenced source lines that didn't exist:

- Phase 2 ("lookup('t42')") pointed at line 11, but the source has
  only 10 lines, so its actual call site is line 10.
- Phases 4 and 5 ("Search the leaf" / "Return the row pointer")
  pointed at line 6, which is the closing brace of the while loop;
  the line we actually want to highlight is line 7
  (return node.findEntry(key)?.rowPointer).

When the annotation referenced a line beyond the end of the source,
CodeHike's applyBlockAnnotation read undefined.range and threw,
which froze the next button and the rest of the demo. Fixed by
pointing at the correct lines, and clamping from/to to
[1, totalLines] in codeForPhase/codeForStep so a stray index in any
demo can't take the page down again. Applied the same clamp in
BloomDemoRunnerClient and HashDemoClient for defence-in-depth.

Verified by clicking through all 5 BTreeDemo step pills under
playwright with zero page errors.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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