orieg / judy-polyfill
Pure-PHP polyfill for the Judy extension (sparse dynamic arrays). Provides the Judy class API when ext-judy is not installed.
Requires
- php: >=8.1
Suggests
- ext-judy: The native extension: 2-4x less memory and C-speed operations (pie install orieg/judy)
README
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 returnsnullfor 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.