orieg/judy-polyfill

Pure-PHP polyfill for the Judy extension (sparse dynamic arrays). Provides the Judy class API when ext-judy is not installed.

Maintainers

Package info

github.com/orieg/judy-polyfill

Documentation

pkg:composer/orieg/judy-polyfill

Transparency log

Statistics

Installs: 55

Dependents: 1

Suggesters: 0

Stars: 1

Open Issues: 0

v2.4.2 2026-08-14 19:24 UTC

This package is auto-updated.

Last update: 2026-08-14 20:48:05 UTC


README

CI Packagist Version License

Pure-PHP polyfill for the Judy extension (sparse dynamic arrays). When ext-judy is not installed, this package provides an API-compatible Judy class plus the judy_version() / judy_type() functions, so your code — and your library's users — run everywhere, and get the native extension's speed and memory profile wherever it is installed.

composer require orieg/judy-polyfill
$judy = new Judy(Judy::INT_TO_INT);   // native class if ext-judy is loaded,
$judy[42] = 1000;                     // polyfill otherwise — same API

For library authors

Depend on the polyfill and suggest the extension. Your library works out of the box, and users who install ext-judy (pie install orieg/judy) get the native performance transparently:

{
    "require": { "orieg/judy-polyfill": "^2.4" },
    "suggest": { "ext-judy": "2-4x less memory and C-speed operations" }
}

This package deliberately does not declare "provide": {"ext-judy": "*"}: a package that hard-requires ext-judy is asking for the native performance profile, and the polyfill cannot honestly satisfy that.

What you get (and don't)

The polyfill is API-compatible, not performance-equivalent. It is backed by a native PHP array:

  • ✅ All 10 Judy type constants, full method surface of ext-judy 2.4
  • ✅ Same coercion, ordering, exception, and edge-case semantics — verified by a parity suite that runs every covered scenario against both implementations in CI (249 checks)
  • ❌ No memory savings — that is the extension's job
  • memoryUsage() / free() byte counts are estimates (the extension reports real allocator numbers); memoryUsage() still returns null for string-keyed types exactly like the extension

Known divergences

  • lastEmpty() / empty-slot scans near the unsigned 64-bit boundary follow signed-integer wrap semantics; identical for practical key ranges.
  • Iteration while mutating is undefined in both implementations, and the undefined behavior differs.

Testing

php tests/behavior.php                      # polyfill standalone
php -d extension=judy tests/parity.php      # diff every scenario vs native

CI runs both legs on PHP 8.1–8.5, with the extension installed via PIE.

License

MIT. The Judy extension itself is licensed under the PHP License.