Skip to content

👻 Ghost Serializer v1.2.3

Choose a tag to compare

@juanchurtado1991 juanchurtado1991 released this 30 Jun 02:16
· 461 commits to main since this release

We are excited to announce the release of Ghost Serializer v1.2.3! This version introduces massive memory footprint optimizations for small/medium models, native Android UI thread pooling enhancements, native ByteArray support, and resolves several compiler edge-cases and limits.
Our complete Kotlin Multiplatform verification suite has grown to 825/825 passing tests!

⚡ Performance & Memory Optimizations

  • Dynamic Perfect Hash Table Sizing: Instead of allocating a fixed 1024-size dispatch table for every class, the compiler now starts searching for a collision-free perfect hash at size 128 and scales up (256, 512, 1024, etc.) only on demand. This reduces the runtime memory footprint of the dispatch table by 50% to 87.5% for small and medium-sized models.
  • Android ThreadLocal UI Thread Bypass: Optimized getLocalPool() on Android. By caching the main UI thread reference on first access and performing a fast identity comparison (===), we now completely bypass the ThreadLocal.get() map lookup on the UI thread.
  • String Pool Cache Locality: Added a contiguous primitive IntArray (stringPoolHashes) to both GhostJsonFlatReader and GhostJsonStringReader. This keeps string pool miss lookups inside the CPU's L1 data cache and avoids dereferencing cold String object references.

🛠️ Bug Fixes

  • Perfect Hash Table Scaling for Large Models: Refactored PerfectHashFinder.kt and JsonReaderOptions.kt to support dynamic table sizes up to 8192. This resolves KSP processing failures for large models (like the 100-field CollisionModel) that could not find a perfect hash at the default size.
  • Android JVM Unit Test Looper Mocking: Wrapped Looper.getMainLooper() in GhostPools.android.kt in a try-catch block to prevent Method getMainLooper in android.os.Looper not mocked crashes when executing Android unit tests in a pure JVM environment.
  • classDeclaration Inaccessible in GhostCodeGenerator: Declared the classDeclaration constructor parameter as a val, making it visible to annotation-reading helpers inside buildSerializerObject().
  • @GhostFallback Support for Enum Deserialization: Enums annotated with @GhostFallback no longer throw GhostJsonException on an unrecognized ordinal. The compiler now reads the annotation and emits an else -> branch pointing to the marked fallback constant.
  • Auto-UNKNOWN Fallback for Enums: If an enum class has a constant named UNKNOWN (any case variation), the compiler now automatically generates a fallback to it without requiring the @GhostFallback annotation.
  • KSP Duplicate Property Collection on Interface/Superclass Override (Issue #4): getAllProperties() returns both the original and the overriding declaration when a data class overrides an interface property, causing the same JSON field to be registered twice. Fixed by filtering out any property for which findOverridee() returns a non-null result before building property models.
  • StackOverflowError in emitFlattenedGroup on Path-Length Mismatch (Issue #5): When colliding @GhostFlatten / @WrappedKeys paths have different depths, pathIndex could exceed the shorter path's length, leading to infinite recursion. Fixed by using >= for the single-property leaf termination check and adding an explicit guard that throws a clear IllegalStateException.

➕ Added

  • ByteArray Field Type Support: Fields declared as ByteArray are now serialized by writing the pre-encoded bytes directly into the JSON stream via rawValue(), and deserialized by capturing the raw token span via captureRawJsonBytes(). Adds GhostJsonReaderCapture, GhostJsonFlatReaderCapture, and GhostJsonStringReaderCapture for all three reader flavors.

📦 Installation (Gradle)

plugins {
    id("com.google.devtools.ksp") version "2.1.10-1.0.31"
    id("com.ghostserializer.ghost") version "1.2.3"
}
dependencies {
    // Core Runtime & Platform Adapters
    implementation("com.ghostserializer:ghost-serialization:1.2.3")
    implementation("com.ghostserializer:ghost-ktor:1.2.3")
    implementation("com.ghostserializer:ghost-retrofit:1.2.3")
}