Sometimes a user selects something the engine has never seen - a query it should learn from scratch. Today you let Record add a brand-new term on the fly with a starting weight.
Let Record insert a previously unknown term with an initial weight of 1, so it becomes a suggestion.
A real typeahead cannot only know words it was seeded with - people search for new
things, and the first time someone selects one, the engine should start tracking
it. So Record gains the ability to create a term: walking the path, it makes
any missing child nodes just as Add does, and if the final node did not already
end a word, it marks it, counts it, and gives it a starting weight of 1. From
then on it is an ordinary term that further selections bump.
This unifies the two ways a term’s weight grows: an existing term is incremented,
a new one is born at 1, and both paths finish by updating the caches so the term
appears in suggestions immediately. cab was never added, but one Record("cab")
makes it a real completion of ca, ranked last at weight 1; a second selection
takes it to 2. Learning and discovery now run through the same small method.
// In Record, create missing children as you walk (like Add), then:if !cur.end {cur.end = truet.size++cur.weight = 1 // a first selection starts a new term at weight 1} else {cur.weight++}for _, n := range path {updateCache(n, term, cur.weight)}