JungleConfig sits a read/write cache between your application and the file system to minimize the number of expensive disk operations. Rather than decoding the config file on everyDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/himansaBro/JungleConfig/llms.txt
Use this file to discover all available pages before exploring further.
get call and re-encoding it on every Set call, the cache keeps an in-memory copy of the entire TypeMap and only reloads from disk when specific thresholds are crossed.
How the Cache Works
The cache is implemented byNativeInternalCache, which wraps the lower-level ConverterInterface (i.e., NativeConverter, NativeEncryptedConverter, or NativeFlatJsonConverter). It holds two internal counters — currentReads and currentWrites — and a dirty flag called isDirty.
On every read operation, NativeInternalCache.getCache() first evaluates three conditions:
| Condition | Effect |
|---|---|
isDirty == true | Immediately re-reads the backing store and resets both counters and the dirty flag |
currentReads > MAX_READS_MARGE | Re-reads the backing store (default threshold: 100 reads) |
currentWrites > MAX_WRITES_MARGE | Re-reads the backing store (default threshold: 10 writes) |
converter.decode() to reload the data, resets both currentReads and currentWrites to zero, and clears the dirty flag. After the flush check (whether or not a reload happened), currentReads is incremented. This means currentReads grows on every call to getCache(), not only when the cache is served from memory.
The default thresholds — MAX_WRITES_MARGE = 10 and MAX_READS_MARGE = 100 — are hard-wired in all four JungleConfig factory constructors:
Invalidating the Cache
If another process or thread modifies the underlying config file, the in-memory cache will be stale until one of the automatic thresholds fires. You can force an immediate reload on the next access by callingInvalidateCache():
InvalidateCache() simply sets isDirty = true inside NativeInternalCache. The actual file read is deferred until the next call to any method that needs the cached data — get, Get, getCollection, Exists, getAllKeys, etc. This means invalidation is cheap: it is always a single boolean assignment.
Transactions and the Cache
When you useBeginTransaction(), pending Set and Remove operations are buffered in memory by NativeInternalTransaction and are not written to the file or reflected in the cache until you call Commit() or EndTransaction(). At that point the transaction writes are merged into the TypeMap and the cache is updated atomically with the flush.
Rollback() inside a transaction discards all buffered changes without touching the cache or the file.
The in-memory mode (
JungleConfig.InMemoryConfig()) and flat JSON mode (JungleConfig.FlatJsonConfig()) both use the same NativeInternalCache wrapper with the same default thresholds (MAX_WRITES_MARGE = 10, MAX_READS_MARGE = 100), but their backing store is a NativeInMemoryIOHandler rather than a real file. Re-reading from the in-memory handler is effectively a no-op copy of an in-process string, so the cache threshold logic still runs but the I/O cost is negligible. InvalidateCache() is safe to call in these modes — it simply forces a re-copy of the in-memory string on the next access rather than a disk read.