token_set_builder.js 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. lunr.TokenSet.Builder = function () {
  2. this.previousWord = ""
  3. this.root = new lunr.TokenSet
  4. this.uncheckedNodes = []
  5. this.minimizedNodes = {}
  6. }
  7. lunr.TokenSet.Builder.prototype.insert = function (word) {
  8. var node,
  9. commonPrefix = 0
  10. if (word < this.previousWord) {
  11. throw new Error ("Out of order word insertion")
  12. }
  13. for (var i = 0; i < word.length && i < this.previousWord.length; i++) {
  14. if (word[i] != this.previousWord[i]) break
  15. commonPrefix++
  16. }
  17. this.minimize(commonPrefix)
  18. if (this.uncheckedNodes.length == 0) {
  19. node = this.root
  20. } else {
  21. node = this.uncheckedNodes[this.uncheckedNodes.length - 1].child
  22. }
  23. for (var i = commonPrefix; i < word.length; i++) {
  24. var nextNode = new lunr.TokenSet,
  25. char = word[i]
  26. node.edges[char] = nextNode
  27. this.uncheckedNodes.push({
  28. parent: node,
  29. char: char,
  30. child: nextNode
  31. })
  32. node = nextNode
  33. }
  34. node.final = true
  35. this.previousWord = word
  36. }
  37. lunr.TokenSet.Builder.prototype.finish = function () {
  38. this.minimize(0)
  39. }
  40. lunr.TokenSet.Builder.prototype.minimize = function (downTo) {
  41. for (var i = this.uncheckedNodes.length - 1; i >= downTo; i--) {
  42. var node = this.uncheckedNodes[i],
  43. childKey = node.child.toString()
  44. if (childKey in this.minimizedNodes) {
  45. node.parent.edges[node.char] = this.minimizedNodes[childKey]
  46. } else {
  47. // Cache the key for this node since
  48. // we know it can't change anymore
  49. node.child._str = childKey
  50. this.minimizedNodes[childKey] = node.child
  51. }
  52. this.uncheckedNodes.pop()
  53. }
  54. }