UNPKG

@azure/cosmos

Version:
142 lines (141 loc) 5.52 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var smartRoutingMapProvider_exports = {}; __export(smartRoutingMapProvider_exports, { PARITIONKEYRANGE: () => PARITIONKEYRANGE, SmartRoutingMapProvider: () => SmartRoutingMapProvider }); module.exports = __toCommonJS(smartRoutingMapProvider_exports); var import_constants = require("../common/constants.js"); var import_partitionKeyRangeCache = require("./partitionKeyRangeCache.js"); var import_QueryRange = require("./QueryRange.js"); const PARITIONKEYRANGE = import_constants.Constants.PartitionKeyRange; class SmartRoutingMapProvider { partitionKeyRangeCache; constructor(clientContext) { this.partitionKeyRangeCache = new import_partitionKeyRangeCache.PartitionKeyRangeCache(clientContext); } static _secondRangeIsAfterFirstRange(range1, range2) { if (typeof range1.max === "undefined") { throw new Error("range1 must have max"); } if (typeof range2.min === "undefined") { throw new Error("range2 must have min"); } if (range1.max > range2.min) { return false; } else { if (range1.max === range2.min && range1.isMaxInclusive && range2.isMinInclusive) { return false; } return true; } } static _isSortedAndNonOverlapping(ranges) { for (let idx = 1; idx < ranges.length; idx++) { const previousR = ranges[idx - 1]; const r = ranges[idx]; if (!this._secondRangeIsAfterFirstRange(previousR, r)) { return false; } } return true; } static _stringMax(a, b) { return a >= b ? a : b; } static _stringCompare(a, b) { return a === b ? 0 : a > b ? 1 : -1; } static _subtractRange(r, partitionKeyRange) { const left = this._stringMax(partitionKeyRange[PARITIONKEYRANGE.MaxExclusive], r.min); const leftInclusive = this._stringCompare(left, r.min) === 0 ? r.isMinInclusive : false; return new import_QueryRange.QueryRange(left, r.max, leftInclusive, r.isMaxInclusive); } /** * Given the sorted ranges and a collection, invokes the callback on the list of overlapping partition key ranges * @param callback - Function execute on the overlapping partition key ranges result, * takes two parameters error, partition key ranges * @hidden */ async getOverlappingRanges(collectionLink, sortedRanges, diagnosticNode) { if (!SmartRoutingMapProvider._isSortedAndNonOverlapping(sortedRanges)) { throw new Error("the list of ranges is not a non-overlapping sorted ranges"); } let partitionKeyRanges = []; if (sortedRanges.length === 0) { return partitionKeyRanges; } const collectionRoutingMap = await this.partitionKeyRangeCache.onCollectionRoutingMap( collectionLink, diagnosticNode ); let index = 0; let currentProvidedRange = sortedRanges[index]; for (; ; ) { if (currentProvidedRange.isEmpty()) { if (++index >= sortedRanges.length) { return partitionKeyRanges; } currentProvidedRange = sortedRanges[index]; continue; } let queryRange; if (partitionKeyRanges.length > 0) { queryRange = SmartRoutingMapProvider._subtractRange( currentProvidedRange, partitionKeyRanges[partitionKeyRanges.length - 1] ); } else { queryRange = currentProvidedRange; } const overlappingRanges = collectionRoutingMap.getOverlappingRanges(queryRange); if (overlappingRanges.length <= 0) { throw new Error(`error: returned overlapping ranges for queryRange ${queryRange} is empty`); } partitionKeyRanges = partitionKeyRanges.concat(overlappingRanges); const lastKnownTargetRange = import_QueryRange.QueryRange.parsePartitionKeyRange( partitionKeyRanges[partitionKeyRanges.length - 1] ); if (!lastKnownTargetRange) { throw new Error("expected lastKnowTargetRange to be truthy"); } if (SmartRoutingMapProvider._stringCompare(currentProvidedRange.max, lastKnownTargetRange.max) > 0) { throw new Error(`error: returned overlapping ranges ${overlappingRanges} does not contain the requested range ${queryRange}`); } if (++index >= sortedRanges.length) { return partitionKeyRanges; } currentProvidedRange = sortedRanges[index]; while (SmartRoutingMapProvider._stringCompare( currentProvidedRange.max, lastKnownTargetRange.max ) <= 0) { if (++index >= sortedRanges.length) { return partitionKeyRanges; } currentProvidedRange = sortedRanges[index]; } } } } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { PARITIONKEYRANGE, SmartRoutingMapProvider });