Use a shared traversal engine #40

Closed
opened 2026-07-19 14:53:52 +00:00 by UserCurt · 6 comments
UserCurt commented 2026-07-19 14:53:52 +00:00 (Migrated from codeberg.org)

get, set, remove, exists each invoke resolve prior to getting, setting, or removing. This means they effectively need to traverse the hierarchy twice. Each method is then responsible for the part that comes after, which can have some shared logic.

This issue proposes creating one shared internal traversal engine that walks the path once no matter the method, and within the traversal engine, take action depending on which public method is used on the terminal targets.

Add focused tests showing that resolve, get, set, and remove share traversal behavior, including comma-separated-list branches and overloaded indexing cases where grouping matters.

Contracts to preserve

With this change, resolve would not be invoked first within get, set, remove, exists. Nevertheless, after this issue is tackled, contracts related to calling resolve first should still be satisfied. In particular:

Stability Under Bare Resolve

r1 = mpath.resolve(data, path, ...);
r2 = mpath.resolve(data, r1);
isequal(r1, r2)

Resolved Input Equivalence

Whether resolve is called first or not, the result of an operation should be the same in most normal circumstances. For example:

g1 = mpath.get(data, path, ...);
g2 = mpath.get(data, mpath.resolve(data, path, ...), ...);
isequal(g1, g2)

Get-Set Round Trip

Setting values to obtained values should preserve the data.

g = mp.get(data, UniformPaths=false, UniformValues=false);
s = mp.set(data, g, UniformPaths=false, UniformValues=false);
isequaln(data, s)

Behavior in this contract could be dependent on issue #35.

`get`, `set`, `remove`, `exists` each invoke `resolve` prior to getting, setting, or removing. This means they effectively need to traverse the hierarchy twice. Each method is then responsible for the part that comes after, which can have some shared logic. This issue proposes creating one shared internal traversal engine that walks the path once no matter the method, and within the traversal engine, take action depending on which public method is used on the terminal targets. Add focused tests showing that `resolve`, `get`, `set`, and `remove` share traversal behavior, including comma-separated-list branches and overloaded indexing cases where grouping matters. ## Contracts to preserve With this change, resolve would not be invoked first within `get`, `set`, `remove`, `exists`. Nevertheless, after this issue is tackled, contracts related to calling `resolve` first should still be satisfied. In particular: ### Stability Under Bare Resolve ```matlab r1 = mpath.resolve(data, path, ...); r2 = mpath.resolve(data, r1); isequal(r1, r2) ``` ### Resolved Input Equivalence Whether resolve is called first or not, the result of an operation should be the same in most normal circumstances. For example: ```matlab g1 = mpath.get(data, path, ...); g2 = mpath.get(data, mpath.resolve(data, path, ...), ...); isequal(g1, g2) ``` ### Get-Set Round Trip Setting values to obtained values should preserve the data. ```matlab g = mp.get(data, UniformPaths=false, UniformValues=false); s = mp.set(data, g, UniformPaths=false, UniformValues=false); isequaln(data, s) ``` Behavior in this contract could be dependent on issue #35.
UserCurt commented 2026-07-19 15:11:27 +00:00 (Migrated from codeberg.org)

take action depending on which public method is used on the terminal targets

With issue #41 in mind, "take action" would add to a queue rather than applying the mutation itself in set and remove

> take action depending on which public method is used on the terminal targets With issue #41 in mind, "take action" would add to a queue rather than applying the mutation itself in `set` and `remove`
UserCurt commented 2026-07-23 10:08:58 +00:00 (Migrated from codeberg.org)

Commit c6165e6 begins the shared traversal-engine work.

resolve now uses a dedicated scalar traversal entry point that returns source-aware traversal rows. Concrete rows also retain the terminal values they reached, allowing later consumers such as get to use the same traversal without replaying resolved paths.

The next step is to make get consume these traversal results directly.

Commit `c6165e6` begins the shared traversal-engine work. `resolve` now uses a dedicated scalar traversal entry point that returns source-aware traversal rows. Concrete rows also retain the terminal values they reached, allowing later consumers such as `get` to use the same traversal without replaying resolved paths. The next step is to make `get` consume these traversal results directly.
UserCurt commented 2026-07-23 13:20:17 +00:00 (Migrated from codeberg.org)

Commit 1ee3c6b continues the shared traversal-engine work by separating shape planning from pointer construction. The next step is to migrate get away from calling and replaying resolve.

Commit `1ee3c6b` continues the shared traversal-engine work by separating shape planning from pointer construction. The next step is to migrate `get` away from calling and replaying `resolve`.
Owner

Commit 7ff390f now has get use the shared traversal pipeline. It no longer calls resolve first and then traverses again to fetch values.

Still need to migrate exists, set, and remove to the shared traversal pipeline.

Commit `7ff390f` now has `get` use the shared traversal pipeline. It no longer calls `resolve` first and then traverses again to fetch values. Still need to migrate `exists`, `set`, and `remove` to the shared traversal pipeline.
Owner

Commit 193d59a now has exists using the shared traversal pipeline. It no longer calls resolve first before checking for existence.

Still need to migrate set and remove to the shared traversal engine.

Commit `193d59a` now has `exists` using the shared traversal pipeline. It no longer calls `resolve` first before checking for existence. Still need to migrate `set` and `remove` to the shared traversal engine.
Owner

Completed by commit a03e30b, which handled set and remove.

Completed by commit `a03e30b`, which handled `set` and `remove`.
Sign in to join this conversation.
No description provided.