UNPKG

@graffy/common

Version:

Common libraries that used by various Graffy modules.

193 lines (157 loc) 5.53 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault"); exports.__esModule = true; exports["default"] = slice; exports.sliceRange = sliceRange; var _extends2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/extends")); var _getIterator2 = _interopRequireDefault(require("@babel/runtime-corejs3/core-js/get-iterator")); var _isArray2 = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/array/is-array")); var _node2 = require("../node"); var _step = require("./step"); var _path = require("../path"); var _merge = _interopRequireDefault(require("./merge")); var _add = _interopRequireDefault(require("./add")); var Result = /*#__PURE__*/ function () { function Result(root) { // When linked queries are added, they are forwarded to the root. this.root = root || this; } var _proto = Result.prototype; _proto.addKnown = function addKnown(node) { this.known = this.known || []; (0, _merge["default"])(this.known, [node]); }; _proto.addUnknown = function addUnknown(node) { this.unknown = this.unknown || []; this.unknown.push(node); }; _proto.addLinked = function addLinked(children) { if (this.root !== this) return this.root.addLinked(children); this.linked = this.linked || []; (0, _add["default"])(this.linked, children); }; return Result; }(); function slice(graph, query, root) { var result = new Result(root); var currentQuery = query; while (currentQuery) { var index = 0; for (var _iterator = currentQuery, _isArray = (0, _isArray2["default"])(_iterator), _i = 0, _iterator = _isArray ? _iterator : (0, _getIterator2["default"])(_iterator);;) { var _ref; if (_isArray) { if (_i >= _iterator.length) break; _ref = _iterator[_i++]; } else { _i = _iterator.next(); if (_i.done) break; _ref = _i.value; } var queryNode = _ref; if ((0, _node2.isRange)(queryNode)) { sliceRange(graph, queryNode, result); } else { var key = queryNode.key; index = (0, _node2.getIndex)(graph, key, index); // console.log('Index', graph, key, index); sliceNode(graph[index], queryNode, result); } } currentQuery = result.linked; delete result.linked; } delete result.root; return result; } function sliceNode(graph, query, result) { var key = query.key, version = query.version; var root = result.root; // console.log('Slicing', graph, query); if (!graph || graph.key > key || (0, _node2.isOlder)(graph, version)) { // The node found doesn't match the query or it's too old. result.addUnknown(query); } else if ((0, _node2.isRange)(graph)) { // The graph is indicating that this value was deleted. result.addKnown({ key: key, end: key, version: graph.version }); } else if ((0, _node2.isBranch)(graph) && (0, _node2.isBranch)(query)) { // Both sides are branches; recurse into them. var _slice = slice(graph.children, query.children, root), known = _slice.known, unknown = _slice.unknown; if (known) result.addKnown((0, _extends2["default"])({}, graph, { children: known })); if (unknown) result.addUnknown((0, _extends2["default"])({}, query, { children: unknown })); } else if ((0, _node2.isLink)(graph) && (0, _node2.isBranch)(query)) { result.addKnown(graph); result.addLinked((0, _path.wrap)(query.children, graph.path, version)); } else if ((0, _node2.isBranch)(graph) || (0, _node2.isBranch)(query)) { // One side is a branch while the other is a leaf; throw error. throw new Error('slice.leaf_branch_mismatch'); } else if ((0, _node2.isRange)(graph)) { result.addKnown({ key: key, end: key, version: graph.version }); } else { result.addKnown(graph); } } function sliceRange(graph, query, result) { var key = query.key, end = query.end, count = query.count, version = query.version; if (count > 0) { for (var i = (0, _node2.getIndex)(graph, key); key <= end && count > 0; i++) { var node = graph[i]; if (!node || key < node.key || (0, _node2.isOlder)(node, version)) break; if ((0, _node2.isRange)(node)) { result.addKnown(getOverlap(node, key, end)); } else { sliceNode(node, (0, _extends2["default"])({}, query, { key: key }), result); count--; } key = (0, _step.keyAfter)(node.end || node.key); } } else { for (var _i2 = (0, _node2.getLastIndex)(graph, end) - 1; end >= key && count < 0; _i2--) { var _node = graph[_i2]; if (!_node || end > (_node.end || _node.key) || (0, _node2.isOlder)(_node, version)) break; if ((0, _node2.isRange)(_node)) { result.addKnown(getOverlap(_node, key, end)); } else { sliceNode(_node, (0, _extends2["default"])({}, query, { key: end }), result); count++; } end = (0, _step.keyBefore)(_node.key); } } if (count && key < end) { var unknown = (0, _extends2["default"])({}, query, { key: key, end: end, count: count }); result.addUnknown(unknown); } } function getOverlap(node, key, end) { if (node.key >= key && node.end <= end) return node; return (0, _extends2["default"])({}, node, { key: node.key > key ? node.key : key, end: node.end < end ? node.end : end }); }