(url: string)
| 166 | } |
| 167 | |
| 168 | accessed(url: string): void { |
| 169 | // When a URL is accessed, its node needs to be moved to the head of the chain. |
| 170 | // This is accomplished in two steps: |
| 171 | // |
| 172 | // 1) remove the node from its position within the chain. |
| 173 | // 2) insert the node as the new head. |
| 174 | // |
| 175 | // Sometimes, a URL is accessed which has not been seen before. In this case, step 1 can |
| 176 | // be skipped completely (which will grow the chain by one). Of course, if the node is |
| 177 | // already the head, this whole operation can be skipped. |
| 178 | if (this.state.head === url) { |
| 179 | // The URL is already in the head position, accessing it is a no-op. |
| 180 | return; |
| 181 | } |
| 182 | |
| 183 | // Look up the node in the map, and construct a new entry if it's |
| 184 | const node = this.state.map[url] || {url, next: null, previous: null}; |
| 185 | |
| 186 | // Step 1: remove the node from its position within the chain, if it is in the chain. |
| 187 | if (this.state.map[url] !== undefined) { |
| 188 | this.remove(url); |
| 189 | } |
| 190 | |
| 191 | // Step 2: insert the node at the head of the chain. |
| 192 | |
| 193 | // First, check if there's an existing head node. If there is, it has previous: null. |
| 194 | // Its previous pointer should be set to the node we're inserting. |
| 195 | if (this.state.head !== null) { |
| 196 | this.state.map[this.state.head]!.previous = url; |
| 197 | } |
| 198 | |
| 199 | // The next pointer of the node being inserted gets set to the old head, before the head |
| 200 | // pointer is updated to this node. |
| 201 | node.next = this.state.head; |
| 202 | |
| 203 | // The new head is the new node. |
| 204 | this.state.head = url; |
| 205 | |
| 206 | // If there is no tail, then this is the first node, and is both the head and the tail. |
| 207 | if (this.state.tail === null) { |
| 208 | this.state.tail = url; |
| 209 | } |
| 210 | |
| 211 | // Set the node in the map of nodes (if the URL has been seen before, this is a no-op) |
| 212 | // and count the insertion. |
| 213 | this.state.map[url] = node; |
| 214 | this.state.count++; |
| 215 | } |
| 216 | } |
| 217 | |
| 218 | /** |
no test coverage detected