/*! * lunr.stemmer * Copyright (C) @YEAR Oliver Nightingale * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt */ /** * lunr.TokenStore is used for efficient storing and lookup of the reverse * index of token to document ref. * * @constructor */ lunr.TokenStore = function () { this.root = { docs: {} } this.length = 0 } /** * Loads a previously serialised token store * * @param {Object} serialisedData The serialised token store to load. * @returns {lunr.TokenStore} * @memberOf TokenStore */ lunr.TokenStore.load = function (serialisedData) { var store = new this store.root = serialisedData.root store.length = serialisedData.length return store } /** * Adds a new token doc pair to the store. * * By default this function starts at the root of the current store, however * it can start at any node of any token store if required. * * @param {String} token The token to store the doc under * @param {Object} doc The doc to store against the token * @param {Object} root An optional node at which to start looking for the * correct place to enter the doc, by default the root of this lunr.TokenStore * is used. * @memberOf TokenStore */ lunr.TokenStore.prototype.add = function (token, doc, root) { var root = root || this.root, key = token.charAt(0), rest = token.slice(1) if (!(key in root)) root[key] = {docs: {}} if (rest.length === 0) { root[key].docs[doc.ref] = doc this.length += 1 return } else { return this.add(rest, doc, root[key]) } } /** * Checks whether this key is contained within this lunr.TokenStore. * * By default this function starts at the root of the current store, however * it can start at any node of any token store if required. * * @param {String} token The token to check for * @param {Object} root An optional node at which to start * @memberOf TokenStore */ lunr.TokenStore.prototype.has = function (token) { if (!token) return false var node = this.root for (var i = 0; i < token.length; i++) { if (!node[token.charAt(i)]) return false node = node[token.charAt(i)] } return true } /** * Retrieve a node from the token store for a given token. * * By default this function starts at the root of the current store, however * it can start at any node of any token store if required. * * @param {String} token The token to get the node for. * @param {Object} root An optional node at which to start. * @returns {Object} * @see TokenStore.prototype.get * @memberOf TokenStore */ lunr.TokenStore.prototype.getNode = function (token) { if (!token) return {} var node = this.root for (var i = 0; i < token.length; i++) { if (!node[token.charAt(i)]) return {} node = node[token.charAt(i)] } return node } /** * Retrieve the documents for a node for the given token. * * By default this function starts at the root of the current store, however * it can start at any node of any token store if required. * * @param {String} token The token to get the documents for. * @param {Object} root An optional node at which to start. * @returns {Object} * @memberOf TokenStore */ lunr.TokenStore.prototype.get = function (token, root) { return this.getNode(token, root).docs || {} } lunr.TokenStore.prototype.count = function (token, root) { return Object.keys(this.get(token, root)).length } /** * Remove the document identified by ref from the token in the store. * * By default this function starts at the root of the current store, however * it can start at any node of any token store if required. * * @param {String} token The token to get the documents for. * @param {String} ref The ref of the document to remove from this token. * @param {Object} root An optional node at which to start. * @returns {Object} * @memberOf TokenStore */ lunr.TokenStore.prototype.remove = function (token, ref) { if (!token) return var node = this.root for (var i = 0; i < token.length; i++) { if (!(token.charAt(i) in node)) return node = node[token.charAt(i)] } delete node.docs[ref] } /** * Find all the possible suffixes of the passed token using tokens * currently in the store. * * @param {String} token The token to expand. * @returns {Array} * @memberOf TokenStore */ lunr.TokenStore.prototype.expand = function (token, memo) { var root = this.getNode(token), docs = root.docs || {}, memo = memo || [] if (Object.keys(docs).length) memo.push(token) Object.keys(root) .forEach(function (key) { if (key === 'docs') return memo.concat(this.expand(token + key, memo)) }, this) return memo } /** * Returns a representation of the token store ready for serialisation. * * @returns {Object} * @memberOf TokenStore */ lunr.TokenStore.prototype.toJSON = function () { return { root: this.root, length: this.length } }