mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-10 05:35:05 +08:00
Move and rename files. NOAUTOREVERT=true NOPRESUBMIT=true NOTREECHECKS=true Bug: 768828 TBR=darin@chromium.org NOTRY=true Change-Id: I66d3b155808bc5bdbf237b80208e1e552bcf7f28 Reviewed-on: https://chromium-review.googlesource.com/1001153 Reviewed-by: Blink Reformat <blink-reformat@chromium.org> Commit-Queue: Blink Reformat <blink-reformat@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#549061} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: 0aee4434a4dba42a42abaea9bfbc0cd196a63bc1
136 lines
3.1 KiB
JavaScript
136 lines
3.1 KiB
JavaScript
// Copyright 2016 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
/**
|
|
* @unrestricted
|
|
*/
|
|
Common.Trie = class {
|
|
constructor() {
|
|
this.clear();
|
|
}
|
|
|
|
/**
|
|
* @param {string} word
|
|
*/
|
|
add(word) {
|
|
let node = this._root;
|
|
++this._wordsInSubtree[this._root];
|
|
for (let i = 0; i < word.length; ++i) {
|
|
const edge = word[i];
|
|
let next = this._edges[node][edge];
|
|
if (!next) {
|
|
if (this._freeNodes.length) {
|
|
// No need to reset any fields since they were properly cleaned up in remove().
|
|
next = this._freeNodes.pop();
|
|
} else {
|
|
next = this._size++;
|
|
this._isWord.push(false);
|
|
this._wordsInSubtree.push(0);
|
|
this._edges.push({__proto__: null});
|
|
}
|
|
this._edges[node][edge] = next;
|
|
}
|
|
++this._wordsInSubtree[next];
|
|
node = next;
|
|
}
|
|
this._isWord[node] = true;
|
|
}
|
|
|
|
/**
|
|
* @param {string} word
|
|
* @return {boolean}
|
|
*/
|
|
remove(word) {
|
|
if (!this.has(word))
|
|
return false;
|
|
let node = this._root;
|
|
--this._wordsInSubtree[this._root];
|
|
for (let i = 0; i < word.length; ++i) {
|
|
const edge = word[i];
|
|
const next = this._edges[node][edge];
|
|
if (!--this._wordsInSubtree[next]) {
|
|
delete this._edges[node][edge];
|
|
this._freeNodes.push(next);
|
|
}
|
|
node = next;
|
|
}
|
|
this._isWord[node] = false;
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @param {string} word
|
|
* @return {boolean}
|
|
*/
|
|
has(word) {
|
|
let node = this._root;
|
|
for (let i = 0; i < word.length; ++i) {
|
|
node = this._edges[node][word[i]];
|
|
if (!node)
|
|
return false;
|
|
}
|
|
return this._isWord[node];
|
|
}
|
|
|
|
/**
|
|
* @param {string=} prefix
|
|
* @return {!Array<string>}
|
|
*/
|
|
words(prefix) {
|
|
prefix = prefix || '';
|
|
let node = this._root;
|
|
for (let i = 0; i < prefix.length; ++i) {
|
|
node = this._edges[node][prefix[i]];
|
|
if (!node)
|
|
return [];
|
|
}
|
|
const results = [];
|
|
this._dfs(node, prefix, results);
|
|
return results;
|
|
}
|
|
|
|
/**
|
|
* @param {number} node
|
|
* @param {string} prefix
|
|
* @param {!Array<string>} results
|
|
*/
|
|
_dfs(node, prefix, results) {
|
|
if (this._isWord[node])
|
|
results.push(prefix);
|
|
const edges = this._edges[node];
|
|
for (const edge in edges)
|
|
this._dfs(edges[edge], prefix + edge, results);
|
|
}
|
|
|
|
/**
|
|
* @param {string} word
|
|
* @param {boolean} fullWordOnly
|
|
* @return {string}
|
|
*/
|
|
longestPrefix(word, fullWordOnly) {
|
|
let node = this._root;
|
|
let wordIndex = 0;
|
|
for (let i = 0; i < word.length; ++i) {
|
|
node = this._edges[node][word[i]];
|
|
if (!node)
|
|
break;
|
|
if (!fullWordOnly || this._isWord[node])
|
|
wordIndex = i + 1;
|
|
}
|
|
return word.substring(0, wordIndex);
|
|
}
|
|
|
|
clear() {
|
|
this._size = 1;
|
|
this._root = 0;
|
|
/** @type {!Array<!Object<string, number>>} */
|
|
this._edges = [{__proto__: null}];
|
|
/** @type {!Array<boolean>} */
|
|
this._isWord = [false];
|
|
/** @type {!Array<number>} */
|
|
this._wordsInSubtree = [0];
|
|
/** @type {!Array<number>} */
|
|
this._freeNodes = [];
|
|
}
|
|
};
|