Skip to content

feat(ffi): stateful O(N) iterator — qjd_iter_init / qjd_iter_next #29

@membphis

Description

@membphis

Problem

qd.pairs and the __newindex materialization path in lua/quickdecode.lua currently walk the object cursor from the start on every step. For an object with N keys, full enumeration is O(N²).

This is acceptable for the primary use case — read a handful of known keys — but becomes a bottleneck when encoding a fully-materialized object with many keys.

Proposal

Add a stateful iterator to the FFI surface:

// include/lua_quick_decode.h

typedef struct qjd_iter qjd_iter;

// Allocate an iterator positioned at the first key of the object/array at `path`.
// Returns NULL on OOM or if `path` does not point to an object/array.
qjd_iter *qjd_iter_init(const qjd_doc *doc, const char *path, size_t path_len);

// Advance to next entry. Returns QJD_OK while entries remain, QJD_NOT_FOUND when exhausted.
// On QJD_OK, *key_ptr / *key_len are set for object keys (NULL/0 for arrays).
// Value type and value getters operate on the current position via a companion cursor.
qjd_err  qjd_iter_next(qjd_iter *it,
                        const char **key_ptr, size_t *key_len,
                        qjd_type *type_out);

void     qjd_iter_free(qjd_iter *it);

The LuaJIT wrapper would use this to provide an O(N) qd.pairs on objects.

Notes

  • qjd_iter holds a Cursor (idx_start, idx_end) that advances by one key/value pair per qjd_iter_next call — no re-scan from the root.
  • Must still wrap the body in catch_unwind per the FFI panic barrier convention in src/ffi.rs.
  • Existing qd.pairs / qd.ipairs semantics stay unchanged at the Lua level; the iterator is an implementation detail.
  • The __newindex materialization path in the lazy-table API is the secondary beneficiary.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions