Skip to content

Adding support for caching inChangesetReader api#9435

Open
soham-bentley wants to merge 18 commits into
masterfrom
soham/adding-batching-in-changesetreader
Open

Adding support for caching inChangesetReader api#9435
soham-bentley wants to merge 18 commits into
masterfrom
soham/adding-batching-in-changesetreader

Conversation

@soham-bentley

@soham-bentley soham-bentley commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

imodel-native: iTwin/imodel-native#1474
Fixes https://github.com/iTwin/itwinjs-backlog/issues/2161

Summary

Adds native-side row batching/caching to the ChangesetReader iteration API in @itwin/core-backend. Introduces a new setBatchSize(n) method to tune how many change rows are fetched and cached per native call, along with stricter "configure-before-stepping" guards for filters, strict mode, and the new batch size setting.


Key Changes

New API — ChangesetReader.setBatchSize(n: number)

  • Controls how many rows are fetched and cached per native call.
  • Must be called before the first step() call — throws IModelError if called after iteration begins.
  • Also throws if the supplied value is not a positive integer.

Default batch sizes (when setBatchSize is not called):

Active configuration Default batch size
propFilter: InstanceKey 100
propFilter: All or BisCoreElement, abbreviateBlobs: false 5
propFilter: All or BisCoreElement (all other cases) 20

Stricter configure-before-step guards

Filters (setTableNameFilters, clearTableNameFilters, etc.), strict mode (enableStrictMode / disableStrictMode), and setBatchSize must all be configured before the first successful step() call. Previously, strict mode could be toggled mid-stream; this is no longer allowed.

inserted / deleted converted to getters

ChangeInstance.inserted and ChangeInstance.deleted changed from plain optional properties to proper get accessors in the public API surface (core-backend.api.md).


Files Changed

File Description
core/backend/src/ChangesetReader.ts Core implementation: batched stepping, setBatchSize, stricter guards
core/backend/src/test/standalone/ChangesetReader.test.ts Expanded tests for new behaviour (+414 lines)
common/api/core-backend.api.md API surface update: setBatchSize, getter conversions
docs/changehistory/NextVersion.md Change history entry for ChangesetReader.setBatchSize
docs/learning/backend/ChangesetReader.md Updated learning docs: invert, batch size section, filter/strict-mode guards
example-code/snippets/src/backend/ChangesetReader-examples.test.ts New code examples: InvertChangeset, SetBatchSize, instanceCount usage
common/changes/@itwin/core-backend/...json Rush changelog entry (type: none)

Performance Trade-off

Larger batch size Smaller batch size
Higher throughput for large changesets Lower peak memory usage
More rows cached in memory at once Fewer native round-trips saved

ChangesetReader — default batch size rationale

The rationale is explained in this comment in the attached work item

@soham-bentley soham-bentley changed the title Adding support for multi row batched return for ChangesetReader api Adding support for caching inChangesetReader api Jun 23, 2026
Comment thread core/backend/src/ChangesetReader.ts Outdated
@soham-bentley soham-bentley changed the title Adding support for caching inChangesetReader api WIP Adding support for caching inChangesetReader api Jun 23, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds native-side row batching/caching to the ChangesetReader iteration API, along with a new setBatchSize() tuning knob and tighter “configure-before-stepping” guards. Updates learning docs, change history, and examples/tests to reflect the new behavior and options.

Changes:

  • Implement batched stepping in ChangesetReader and expose setBatchSize(n) to tune native fetch/cache size.
  • Enforce that filters/strict mode (and now batch size) are configured before the first successful step().
  • Add/refresh documentation, change history notes, and examples; expand standalone backend tests for the new behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
example-code/snippets/src/backend/ChangesetReader-examples.test.ts Adds snippet coverage for invert and setBatchSize, plus a small assertion using pcu.instanceCount.
docs/learning/backend/ChangesetReader.md Documents invert, clarifies “configure-before-step” constraints, and adds batch size guidance/defaults.
docs/changehistory/NextVersion.md Adds change history entry describing ChangesetReader.setBatchSize and defaults.
core/backend/src/test/standalone/ChangesetReader.test.ts Adds new standalone tests for the “already stepped” guard, batched stepping exhaustion behavior, lazy getters, and a larger insert-many scenario.
core/backend/src/ChangesetReader.ts Implements native batch caching, adds setBatchSize, converts inserted/deleted to lazy getters, and adds “already stepped” guards to configuration methods.

Comment thread core/backend/src/ChangesetReader.ts
Comment thread core/backend/src/ChangesetReader.ts
Comment thread core/backend/src/ChangesetReader.ts
Comment thread example-code/snippets/src/backend/ChangesetReader-examples.test.ts
Comment thread core/backend/src/ChangesetReader.ts
@soham-bentley soham-bentley changed the title WIP Adding support for caching inChangesetReader api Adding support for caching inChangesetReader api Jun 24, 2026
@soham-bentley soham-bentley marked this pull request as ready for review June 24, 2026 12:23
@soham-bentley soham-bentley requested review from a team as code owners June 24, 2026 12:23
Comment thread core/backend/src/ChangesetReader.ts Outdated
Comment thread core/backend/src/ChangesetReader.ts
Comment thread core/backend/src/ChangesetReader.ts Outdated
Comment thread core/backend/src/ChangesetReader.ts
Comment thread core/backend/src/ChangesetReader.ts

@MichaelSwigerAtBentley MichaelSwigerAtBentley left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewing on behalf of docs. Docs lgtm

expect(() => reader.op).to.throw("no current row");
});

it("setBatchSize(1) produces same instances as default batch size", () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there any tests that check the default batch sizes? We would want that caught if it changes

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have any getters for the default batch size.....the default values are internal concept to the changeset reader, so I am not sure how we can assert on default batch sizes. Do we really need to?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mike, were you referring to tests that mock native and check the behavior, to test if we actually use expected batch sizes, or are you suggesting just checking the default batch sizes?

The second sounds like the "assert a constant equals its own value" anti pattern, I'd vote against doing that here. It would tell us nothing except "someone changed the number".

@MichaelSwigerAtBentley MichaelSwigerAtBentley Jun 26, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant that we test if we actually use expected default batch sizes. Making sure that the default that is set is actually in use, and is what is returned in scenarios where no value is passed. It might be more appropriate to live in native

@aruniverse aruniverse added this to the iTwin.js 5.12 milestone Jun 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants