* Gets the existing item in the tree or creates a new one with the value provided by valueHandler * @param {Iterator} keyIterator * @param {Function} valueHandler * @return {Object}
(keyIterator, valueHandler)
| 56 | * @return {Object} |
| 57 | */ |
| 58 | getOrCreate(keyIterator, valueHandler) { |
| 59 | if (typeof keyIterator.next !== 'function') { |
| 60 | keyIterator = keyIterator[Symbol.iterator](); |
| 61 | } |
| 62 | let node = this; |
| 63 | let isMatch = false; |
| 64 | let item = keyIterator.next(); |
| 65 | while (true) { |
| 66 | let newBranch; |
| 67 | // Check node keys at position 1 and above |
| 68 | for (let i = 1; i < node.key.length; i++) { |
| 69 | if (item.done || node.key[i] !== item.value) { |
| 70 | // We should branch out |
| 71 | newBranch = this._createBranch(node, i, item.done, valueHandler); |
| 72 | break; |
| 73 | } |
| 74 | item = keyIterator.next(); |
| 75 | } |
| 76 | |
| 77 | if (item.done) { |
| 78 | isMatch = true; |
| 79 | break; |
| 80 | } |
| 81 | |
| 82 | if (newBranch !== undefined) { |
| 83 | break; |
| 84 | } |
| 85 | |
| 86 | const edges = node.edges; |
| 87 | let nextNode; |
| 88 | for (let i = 0; i < edges.length; i++) { |
| 89 | const e = edges[i]; |
| 90 | if (e.key[0] === item.value) { |
| 91 | // its a match |
| 92 | nextNode = e; |
| 93 | item = keyIterator.next(); |
| 94 | break; |
| 95 | } |
| 96 | } |
| 97 | |
| 98 | if (nextNode === undefined) { |
| 99 | // Current node is the root for a new leaf |
| 100 | break; |
| 101 | } |
| 102 | else { |
| 103 | node = nextNode; |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | if (!isMatch) { |
| 108 | // Create using "node" as the root |
| 109 | const value = valueHandler(); |
| 110 | node.edges.push(new Node(iteratorToArray(item.value, keyIterator), value)); |
| 111 | this._onItemAdded(); |
| 112 | return value; |
| 113 | } |
| 114 | if (node.value === null && node.edges.length > 0) { |
| 115 | node.value = valueHandler(); |
no test coverage detected