package fate

type bigrams map[token]*tokset

func (b bigrams) Observe(tok0 token, tok1 token) {
	ctx, ok := b[tok0]
	if !ok {
		ctx = &tokset{}
		b[tok0] = ctx
	}
	ctx.Add(tok1)
}

type fwdrev struct {
	fwd *tokset
	rev *tokset
}

type trigrams map[bigram]*fwdrev

func (t trigrams) Observe(tok0, tok1, tok2, tok3 token) (had2 bool) {
	ctx := bigram{tok1, tok2}

	chain, had2 := t[ctx]
	if !had2 {
		chain = &fwdrev{&tokset{}, &tokset{}}
		t[ctx] = chain
	}

	chain.fwd.Add(tok3)
	chain.rev.Add(tok0)

	return had2
}

func (t trigrams) Fwd(ctx bigram) *tokset {
	return t[ctx].fwd
}

func (t trigrams) Rev(ctx bigram) *tokset {
	return t[ctx].rev
}

package fate

type bigrams map[token]*tokset

func (b bigrams) Observe(tok0 token, tok1 token) {
	ctx, ok := b[tok0]
	if !ok {
		ctx = &tokset{}
		b[tok0] = ctx
	}
	ctx.Add(tok1)
}

type fwdrev struct {
	fwd tokset
	rev tokset
}

type trigrams map[bigram]*fwdrev

func (t trigrams) Observe(tok0, tok1, tok2, tok3 token) (had2 bool) {
	ctx := bigram{tok1, tok2}

	chain, had2 := t[ctx]
	if !had2 {
		chain = &fwdrev{}
		t[ctx] = chain
	}

	chain.fwd.Add(tok3)
	chain.rev.Add(tok0)

	return had2
}

func (t trigrams) Fwd(ctx bigram) *tokset {
	return &(t[ctx].fwd)
}

func (t trigrams) Rev(ctx bigram) *tokset {
	return &(t[ctx].rev)
}

Remove an extra layer of pointer indirection in the trigram map
Remove an extra layer of pointer indirection in the trigram map

Reduces memory usage and makes learning faster.

benchmark                    old ns/op     new ns/op     delta
BenchmarkLearn-4             23213         20426         -12.01%
BenchmarkReply-4             15738         14160         -10.03%
BenchmarkLearnParallel-4     22922         21090         -7.99%
BenchmarkReplyParallel-4     4594          4566          -0.61%
BenchmarkOverhead-4          8171          7955          -2.64%
BenchmarkToksetAdd-4         2136          2127          -0.42%

benchmark            old MB/s     new MB/s     speedup
BenchmarkLearn-4     7.97         9.06         1.14x

benchmark                    old allocs     new allocs     delta
BenchmarkLearn-4             61             40             -34.43%
BenchmarkReply-4             8              8              +0.00%
BenchmarkLearnParallel-4     61             36             -40.98%
BenchmarkReplyParallel-4     9              9              +0.00%
BenchmarkOverhead-4          1              1              +0.00%

benchmark                    old bytes     new bytes     delta
BenchmarkLearn-4             2758          2593          -5.98%
BenchmarkReply-4             609           608           -0.16%
BenchmarkLearnParallel-4     2760          2238          -18.91%
BenchmarkReplyParallel-4     621           621           +0.00%
BenchmarkOverhead-4          32            32            +0.00%
