Adding support for multi row batched return for ChangesetReader typescript api#1474
Adding support for multi row batched return for ChangesetReader typescript api#1474soham-bentley wants to merge 14 commits into
ChangesetReader typescript api#1474Conversation
There was a problem hiding this comment.
Pull request overview
This PR is a WIP that updates the native ChangesetReader plumbing in ECDb and changes the Node addon’s TypeScript-facing API to support batched/multi-row retrieval (returning metadata plus old/new stage values per row).
Changes:
- Node addon: replaces per-row
step()/getValue()/getChangeMetadata()usage with a singlestep(numOfRows, rowOptions)call that returns an array of{ metadata, oldValues, newValues }. - ECDb: refactors
ChangesetReaderto ownPreparedChangesetReaderdirectly, introduces an LRUTableColumnCache, and changesGetChangeFetchedPropertyNames()to return a pointer (ornullptr) instead of filling an out-parameter. - Tests/build: updates existing tests for the new property-name API and adds cache-focused tests; removes the obsolete
ChangesetReaderImplfiles from build inputs.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 16 comments.
Show a summary per file
| File | Description |
|---|---|
| iModelJsNodeAddon/IModelJsNative.cpp | Updates the JS projection of ChangesetReader to return batched rows with metadata + old/new values. |
| iModelJsNodeAddon/api_package/ts/src/NativeLibrary.ts | Updates TypeScript declarations to the new batched ChangesetReader.step() signature and new row types. |
| iModelCore/ECDb/Tests/NonPublished/ChangesetReaderTests.cpp | Adapts tests to new GetChangeFetchedPropertyNames() signature; adds new cache behavior tests. |
| iModelCore/ECDb/PublicAPI/ECDb/ChangesetReader.h | Updates ChangesetReader public API to use PreparedChangesetReader and pointer-returning property-name list. |
| iModelCore/ECDb/ECDb/PreparedChangesetReader.h | Adds TableColumnCache + filter context/iterator helpers; updates filtering APIs and property-name retrieval. |
| iModelCore/ECDb/ECDb/PreparedChangesetReader.cpp | Implements TableColumnCache, filter context, iterator refactor, and updated row processing. |
| iModelCore/ECDb/ECDb/ECDbPch.h | Removes include of deleted ChangesetReaderImpl.h. |
| iModelCore/ECDb/ECDb/ECDb.mke | Removes deleted ChangesetReaderImpl.* from build inputs. |
| iModelCore/ECDb/ECDb/ChangesetValueFactory.h | Changes changed-prop collection to optional pointer; adds helper to conditionally append. |
| iModelCore/ECDb/ECDb/ChangesetValueFactory.cpp | Implements optional changed-prop collection and helper; minor comment tweaks needed. |
| iModelCore/ECDb/ECDb/ChangesetReaderImpl.h | Deleted (obsolete wrapper). |
| iModelCore/ECDb/ECDb/ChangesetReaderImpl.cpp | Deleted (obsolete wrapper). |
| iModelCore/ECDb/ECDb/ChangesetReader.cpp | Refactors ChangesetReader to own PreparedChangesetReader directly; adds open checks/logging (but currently has critical status-handling bugs). |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…ham/adding_multi-row_return_for_typescript_caching
…https://github.com/iTwin/imodel-native into soham/adding_multi-row_return_for_typescript_caching
ChangesetReader typescript apiChangesetReader typescript api
…ham/adding_multi-row_return_for_typescript_caching
|
This PR and its peer native PR collectively made changes that improve performance. But there is no number show what and how much this code contributed to improvements. It be nice we have that idea and also add that to NextVersion.md to advertise the improvements made to the api. |
Added to NextVersion.md the results after running perf test before and after |
|
/azp run imodel-native |
|
Azure Pipelines successfully started running 1 pipeline(s). |
…ham/adding_multi-row_return_for_typescript_caching
…ham/adding_multi-row_return_for_typescript_caching
Fixes https://github.com/iTwin/itwinjs-backlog/issues/2162
Fixes iTwin/itwinjs-core#9415
itwinjs-core: iTwin/itwinjs-core#9435
Overview
This PR updates the native
ChangesetReaderplumbing in ECDb and changes the Node addon's TypeScript-facing API to support batched / multi-row retrieval, returning metadata plus old/new stage values per row in a single call. It also refactors the internal design to remove the now-obsoleteChangesetReaderImplfiles, introduces an LRUTableColumnCache, and tightens the public API surface.Key Changes
Node Addon (N-API / TypeScript API)
step() / getValue() / getChangeMetadata()call pattern.step(numOfRows, rowOptions)call that:numOfRowsrows internally.ChangesetRowData[]array where each element contains{ metadata, oldValues, newValues }.getValueandgetChangeMetadataN-API method registrations (InstanceMethodentries).NativeLibrary.ts:BuildRowMetadataandBuildRowValueextracted in C++ for cleaner per-row construction.ECDb —
ChangesetReader(public API)ChangesetReadernow owns astd::unique_ptr<PreparedChangesetReader> m_innerReaderinstead of a rawImpl* m_pimpl.m_innerReaderwithstd::make_unique<PreparedChangesetReader>().m_innerReader.reset()explicitly.OpenChangesetFile,OpenChangeGroup,OpenInMemoryChangeset,Close,Step,GetTableName,GetOpcode,GetValue,GetECDb,GetColumnCount,GetInstanceKey,IsECTable,IsIndirectChange,SetTableFilters,SetOpcodeFilters,SetECClassNameFilters,ClearTableFilters,ClearOpcodeFilters,ClearECClassNameFilters,EnableStrictMode,DisableStrictMode) now forward tom_innerReaderinstead ofm_pimpl.GetChangeFetchedPropertyNamessignature changed from an out-parameter to a pointer return:nullptrwhen the reader is not positioned on a valid row.struct Implforward declaration and the PIMPL comment; public header now forward-declaresstruct PreparedChangesetReaderinstead.ECDbCR ecdbas a parameter directly (previously stored on construction), keepingChangesetReaderitself ECDb-agnostic untilOpen*is called.ECDb —
PreparedChangesetReader(internal refactor)explicit PreparedChangesetReader(ECDbCR ecdb)toexplicit PreparedChangesetReader()— ECDb reference is now passed at open time rather than construction time, allowing the reader to be constructed without an ECDb.m_ecdbchanged fromECDbCR(reference) toECDb const*(pointer,nullptrwhen closed).PreparedChangesetReader.h:TableColumnCache— LRU cache (max 25 entries) mapping SQLite table name → ordered column names, populated on miss viaPRAGMA_TABLE_INFO. Improves performance on repeated access.ChangesetFilterContext— consolidates all filter and mode state (m_propertyFilter,m_strictMode,m_tableFilters,m_opcodeFilters,m_ecclassNameFilters) and exposesIsTableAllowed,IsOpcodeAllowed,IsECClassNameAllowed,CheckColumnCount, andReset.InternalChangeIterator— owns theChangeStream / Changes / Changetriple and drives low-level row iteration (Open,Advance,Reset,IsOpen,IsStepped).m_oldFieldsandm_newFields(previously a singlem_fieldsmap keyed by stage).m_columnValueshoisted to a member (std::unordered_map<Utf8String, DbValue>) to avoid repeated re-allocation per step.GetColumnValues(Stage)now writes intom_columnValues(member) rather than returning a map by reference.ProcessStageValuesnow takesstd::vector<Utf8String>*(nullable) forchangedPropNamesso callers can opt out of name collection.CloseInfalliblemoved frompublictoprivate; called by destructor.PreparedChangesetReaderchanged from inline void setters to properBentleyStatus-returning methods withIsOpen()guard checks.WriteGroupToFilenow takesECDbCR ecdbexplicitly.GetColumnCountForCurrentChangedTablenow usesTableColumnCachefor efficiency and is no longerconst.IsOpen()now checksm_ecdb != nullptr && m_iterator.IsOpen().ChangesetValueFactory(internal)changedPropsparameters acrossCreate,BuildPropertyFields,CreatePrimitive,CreateSystem,CreatePoint2d,CreatePoint3d,CreateNav,CreateArray,CreateStruct, andCreateValueForPropertychanged fromstd::vector<Utf8String>&(out-reference) tostd::vector<Utf8String>*(nullable pointer).static void FillChangedPropIfApplicable(std::vector<Utf8String>* changedProps, Utf8String const& propName)— appends only when pointer is non-null; replaces all directemplace_backcalls.CreateStructhoists thememberTemp/memberChangedPropsvectors outside the loop and uses.clear()to avoid per-iteration allocation.Build & Headers
ChangesetReaderImpl.cppandChangesetReaderImpl.hdeleted entirely.ECDb.mke: removedChangesetReaderImpl.cppcompilation rule andChangesetReaderImpl.hfromECDbAllHeaders.ECDbPch.h: removed#include "ChangesetReaderImpl.h".<list>added toPreparedChangesetReader.h(required bystd::listused inTableColumnCache).Tests
ChangesetReaderTests.cppupdated for the newGetChangeFetchedPropertyNames()pointer API (no out-parameter).TableColumnCachebehaviour.