@azure/cosmos
Version:
Microsoft Azure Cosmos DB Service Node.js SDK for NOSQL API
89 lines • 4.13 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.InMemoryCollectionRoutingMap = void 0;
const index_js_1 = require("../common/index.js");
const QueryRange_js_1 = require("./QueryRange.js");
/** @hidden */
class InMemoryCollectionRoutingMap {
orderedPartitionKeyRanges;
orderedRanges;
// TODO: chrande made this public, even though it is implementation detail for a test
orderedPartitionInfo;
/**
* Represents a InMemoryCollectionRoutingMap Object,
* Stores partition key ranges in an efficient way with some additional information and provides
* convenience methods for working with set of ranges.
*/
constructor(orderedPartitionKeyRanges, orderedPartitionInfo) {
this.orderedPartitionKeyRanges = orderedPartitionKeyRanges;
this.orderedRanges = orderedPartitionKeyRanges.map((pkr) => {
return new QueryRange_js_1.QueryRange(pkr[index_js_1.Constants.PartitionKeyRange.MinInclusive], pkr[index_js_1.Constants.PartitionKeyRange.MaxExclusive], true, false);
});
this.orderedPartitionInfo = orderedPartitionInfo;
}
getOrderedParitionKeyRanges() {
return this.orderedPartitionKeyRanges;
}
getOverlappingRanges(providedQueryRanges) {
// TODO This code has all kinds of smells. Multiple iterations and sorts just to grab overlapping ranges
// stfaul attempted to bring it down to one for-loop and failed
const pqr = Array.isArray(providedQueryRanges)
? providedQueryRanges
: [providedQueryRanges];
const minToPartitionRange = {}; // TODO: any
// this for loop doesn't invoke any async callback
for (const queryRange of pqr) {
if (queryRange.isEmpty()) {
continue;
}
if (queryRange.isFullRange()) {
return this.orderedPartitionKeyRanges;
}
const minIndex = this.orderedRanges.findIndex((range) => {
if (queryRange.min > range.min && queryRange.min < range.max) {
return true;
}
if (queryRange.min === range.min) {
return true;
}
if (queryRange.min === range.max) {
return true;
}
});
if (minIndex < 0) {
throw new Error("error in collection routing map, queried value is less than the start range.");
}
// Start at the end and work backwards
let maxIndex;
for (let i = this.orderedRanges.length - 1; i >= 0; i--) {
const range = this.orderedRanges[i];
if (queryRange.max > range.min && queryRange.max < range.max) {
maxIndex = i;
break;
}
if (queryRange.max === range.min) {
maxIndex = i;
break;
}
if (queryRange.max === range.max) {
maxIndex = i;
break;
}
}
if (maxIndex > this.orderedRanges.length) {
throw new Error("error in collection routing map, queried value is greater than the end range.");
}
for (let j = minIndex; j < maxIndex + 1; j++) {
if (queryRange.overlaps(this.orderedRanges[j])) {
minToPartitionRange[this.orderedPartitionKeyRanges[j][index_js_1.Constants.PartitionKeyRange.MinInclusive]] = this.orderedPartitionKeyRanges[j];
}
}
}
const overlappingPartitionKeyRanges = Object.keys(minToPartitionRange).map((k) => minToPartitionRange[k]);
return overlappingPartitionKeyRanges.sort((a, b) => {
return a[index_js_1.Constants.PartitionKeyRange.MinInclusive].localeCompare(b[index_js_1.Constants.PartitionKeyRange.MinInclusive]);
});
}
}
exports.InMemoryCollectionRoutingMap = InMemoryCollectionRoutingMap;
//# sourceMappingURL=inMemoryCollectionRoutingMap.js.map