Last active
April 29, 2016 19:17
-
-
Save dead-claudia/0d53b10f7525e11620b8eb5dcebca0fa to your computer and use it in GitHub Desktop.
Path list to tree for easy lookup.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Add and check that a path exists in a tree. | |
// | |
// Notes: | |
// 1. The comparison algorithms assume the paths are already resolved. | |
// 2. `matchEnd` is a sentinel to mark a leaf end of the cache tree. | |
// 3. Windows drive letters are intentionally included in the cache. | |
const path = require("path") | |
const hasOwn = Object.prototype.hasOwnProperty | |
// The cache also intentionally includes Windows drive letters. | |
const cache = {} | |
const matchEnd = {} | |
function getStart(dir) { | |
let start = 0 | |
let ch = dir.charCodeAt(0) | |
// Ignore preceding slashes when getting the path start. | |
while (start !== dir.length && ch === 92/*\*/ || ch === 47/*/*/) { | |
ch = dir.charCodeAt(++start) | |
} | |
return start | |
} | |
exports.addPath = function (dir) { | |
// Ignore preceding slashes. Also, `last` always points to the last | |
// potential path start. | |
let last = getStart(dir) | |
let node = cache | |
for (let i = last; i < dir.length; i++) { | |
const code = dir.charCodeAt(i) | |
if (code === 92/*\*/ || code === 47/*/*/) { | |
const entry = dir.slice(last, i) | |
if (node === matchEnd) { | |
node = node[entry] = {} | |
} else if (!hasOwn.call(node, entry)) { | |
node = node[entry] = matchEnd | |
} else { | |
node = node[entry] | |
} | |
last = i + 1 | |
} | |
} | |
// If we didn't stop at the end, we still have one last known file to add. | |
if (last - 1 !== dir.length) { | |
const entry = dir.slice(last - 1) | |
if (!hasOwn.call(node, entry)) { | |
node[entry] = matchEnd | |
} | |
} | |
} | |
exports.hasPath = function (file) { | |
let node = cache | |
let last = getStart(dir) | |
for (let i = 0; i < dir.length; i++) { | |
const code = dir.charCodeAt(i) | |
if (code === 92/*\*/ || code === 47/*/*/) { | |
if (node === matchEnd) { | |
return true | |
} | |
const entry = dir.slice(last, i + 1) | |
if (!hasOwn.call(node, entry)) { | |
return false | |
} | |
node = node[entry] | |
last = i + 1 | |
} | |
} | |
// If there's a trailing slash or we've reached the end, it's okay. | |
return last - 1 === dir.length || | |
// If the last part is exact, it's okay (i.e. the directory is cached) | |
node === matchEnd || | |
// Check the last part. | |
hasOwn.call(node, dir.slice(start, last)) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Add and check that a path exists in a tree. | |
// | |
// Notes: | |
// 1. The comparison algorithms assume the paths are already resolved. | |
// 2. `matchEnd` is a sentinel to mark a leaf end of the cache tree. | |
// 3. Windows drive letters are intentionally included in the cache. | |
const path = require("path") | |
const hasOwn = Object.prototype.hasOwnProperty | |
// The cache also intentionally includes Windows drive letters. | |
const cache = {} | |
const matchEnd = {} | |
const splitPath = dir => dir.replace(/^[\\\/]+/, "").split(/[\\\/]+/) | |
exports.addPath = function (dir) { | |
let parts = splitPath(dir) | |
let node = cache | |
for (const entry of parts) { | |
if (node === matchEnd) { | |
node = node[entry] = {} | |
} else if (!hasOwn.call(node, entry)) { | |
node = node[entry] = matchEnd | |
} else { | |
node = node[entry] | |
} | |
} | |
} | |
exports.hasPath = function (file) { | |
let node = cache | |
for (const entry of splitPath(dir)) { | |
if (node === matchEnd) { | |
return true | |
} else if (!hasOwn.call(node, entry)) { | |
return false | |
} else { | |
node = node[entry] | |
} | |
} | |
return node === matchEnd | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment