Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
632 changes: 401 additions & 231 deletions api/rpc/wordsearcher/searcher.pb.go

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions bruno/bruno.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"version": "1",
"name": "word_db_server",
"type": "collection",
"ignore": [
"node_modules",
".git"
]
}
42 changes: 42 additions & 0 deletions bruno/samplesearch - QuestionSearcher.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
meta {
name: samplesearch - QuestionSearcher
type: http
seq: 2
}

post {
url: http://aerolith.localhost/word_db_server/api/wordsearcher.QuestionSearcher/Search
body: json
auth: none
}

headers {
Content-Type: application/json
}

body:json {
{
"searchparams": [
{
"condition": "LEXICON",
"stringvalue": {
"value": "NWL23"
}
},
{
"condition": "LENGTH",
"minmax": {
"min": 7,
"max": 8
}
},
{
"condition": "NUMBER_OF_VOWELS",
"minmax": {
"min": 6,
"max": 8
}
}
]
}
}
35 changes: 35 additions & 0 deletions bruno/samplesearch 2 - QuestionSearcher.bru
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
meta {
name: samplesearch 2 - QuestionSearcher
type: http
seq: 3
}

post {
url: http://aerolith.localhost/word_db_server/api/wordsearcher.QuestionSearcher/Search
body: json
auth: none
}

headers {
Content-Type: application/json
}

body:json {
{
"searchparams": [
{
"condition": "LEXICON",
"stringvalue": {
"value": "NWL23"
}
},
{
"condition": "LENGTH",
"minmax": {
"min": 7,
"max": 15
}
}
]
}
}
3 changes: 2 additions & 1 deletion cmd/searchserver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ func main() {
Config: cfg,
}
anagramServer := &anagramserver.Server{
Config: &wglconfig.Config{DataPath: cfg.DataPath},
Config: &wglconfig.Config{DataPath: cfg.DataPath},
WDBConfig: cfg,
}
wordSearchServer := &searchserver.WordSearchServer{
Config: cfg,
Expand Down
2 changes: 2 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type Config struct {
MaxNonmemberCards int
MaxCardsAdd int
SmallJitterOnAddCard bool
MaxQueryResults int
}

// Load loads the configs from the given arguments
Expand All @@ -26,6 +27,7 @@ func (c *Config) Load(args []string) error {
fs.IntVar(&c.MaxCardsAdd, "max-cards-add", 1000, "maximum cards that can be added at once")
fs.IntVar(&c.MaxNonmemberCards, "max-nonmember-cards", 10000, "maximum total cards for non-members")
fs.BoolVar(&c.SmallJitterOnAddCard, "jitter-on-addcard", true, "add small jitter in time due when first adding card")
fs.IntVar(&c.MaxQueryResults, "max-query-results", 150000, "maximum results from a single search query to prevent OOM")
err := fs.Parse(args)
return err
}
2 changes: 1 addition & 1 deletion dbmaker/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
const DeletionToken = "X"

func loadKWG(dataPath, lexName string) *kwg.KWG {
k, err := kwg.Get(&config.Config{DataPath: dataPath}, lexName)
k, err := kwg.GetKWG(&config.Config{DataPath: dataPath}, lexName)
if err != nil {
log.Err(err).Str("lexName", lexName).Msg("unable to load kwg")
}
Expand Down
2 changes: 1 addition & 1 deletion internal/anagramserver/blank_challenges.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func try(nBlanks int32, dist *tilemapping.LetterDistribution, wordLength int32,
func GenerateBlanks(ctx context.Context, cfg *config.Config, req *pb.BlankChallengeCreateRequest) (
[]*pb.Alphagram, error) {

dawg, err := kwg.Get(cfg, req.Lexicon)
dawg, err := kwg.GetKWG(cfg, req.Lexicon)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/anagramserver/blank_challenges_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var DefaultConfig = &config.Config{
}

func loadKWG(lexName string) (*kwg.KWG, error) {
return kwg.Get(DefaultConfig, lexName)
return kwg.GetKWG(DefaultConfig, lexName)
}

func TestRacks(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion internal/anagramserver/build_challenges.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
func GenerateBuildChallenge(ctx context.Context, cfg *config.Config, req *pb.BuildChallengeCreateRequest) (
*pb.Alphagram, error) {

dawg, err := kwg.Get(cfg, req.Lexicon)
dawg, err := kwg.GetKWG(cfg, req.Lexicon)
if err != nil {
return nil, err
}
Expand Down
20 changes: 10 additions & 10 deletions internal/anagramserver/legacyanagrammer/anagrammer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func wordlistToSet(wl []string) map[string]struct{} {
func TestAnagram(t *testing.T) {
is := is.New(t)

d, err := kwg.Get(DefaultConfig, "America")
d, err := kwg.GetKWG(DefaultConfig, "America")
is.NoErr(err)

for _, pair := range buildTests {
Expand All @@ -121,7 +121,7 @@ func TestAnagram(t *testing.T) {

func TestAnagramSpanish(t *testing.T) {
is := is.New(t)
d, err := kwg.Get(DefaultConfig, "FISE2")
d, err := kwg.GetKWG(DefaultConfig, "FISE2")
is.NoErr(err)
for _, pair := range spanishBuildTests {
answers := Anagram(pair.rack, d, ModeBuild)
Expand All @@ -141,7 +141,7 @@ func TestAnagramSpanish(t *testing.T) {
func BenchmarkAnagramBlanks(b *testing.B) {
// ~ 21.33 ms per op on my macbook pro.
is := is.New(b)
d, err := kwg.Get(DefaultConfig, "CSW15")
d, err := kwg.GetKWG(DefaultConfig, "CSW15")
is.NoErr(err)
b.ResetTimer()
for i := 0; i < b.N; i++ {
Expand All @@ -152,7 +152,7 @@ func BenchmarkAnagramBlanks(b *testing.B) {
func BenchmarkAnagramFourBlanks(b *testing.B) {
// ~ 453.6ms
is := is.New(b)
d, err := kwg.Get(DefaultConfig, "America")
d, err := kwg.GetKWG(DefaultConfig, "America")
is.NoErr(err)

b.ResetTimer()
Expand All @@ -163,7 +163,7 @@ func BenchmarkAnagramFourBlanks(b *testing.B) {

func TestBuildFourBlanks(t *testing.T) {
is := is.New(t)
d, err := kwg.Get(DefaultConfig, "America")
d, err := kwg.GetKWG(DefaultConfig, "America")
is.NoErr(err)
answers := Anagram("AEINST????", d, ModeBuild)
expected := 61711
Expand All @@ -174,7 +174,7 @@ func TestBuildFourBlanks(t *testing.T) {

func TestAnagramFourBlanks(t *testing.T) {
is := is.New(t)
d, err := kwg.Get(DefaultConfig, "America")
d, err := kwg.GetKWG(DefaultConfig, "America")
is.NoErr(err)
answers := Anagram("AEINST????", d, ModeExact)
expected := 863
Expand Down Expand Up @@ -202,7 +202,7 @@ func TestMakeRack(t *testing.T) {

func TestAnagramRangeSmall(t *testing.T) {
is := is.New(t)
d, err := kwg.Get(DefaultConfig, "CSW19")
d, err := kwg.GetKWG(DefaultConfig, "CSW19")
is.NoErr(err)
answers := Anagram("(JQXZ)A", d, ModeExact)
log.Info().Msgf("answers: %v", answers)
Expand All @@ -212,7 +212,7 @@ func TestAnagramRangeSmall(t *testing.T) {

func TestAnagramRangeSmall2(t *testing.T) {
is := is.New(t)
d, err := kwg.Get(DefaultConfig, "CSW19")
d, err := kwg.GetKWG(DefaultConfig, "CSW19")
is.NoErr(err)
answers := Anagram("(AEIOU)(JQXZ)", d, ModeExact)
log.Info().Msgf("answers: %v", answers)
Expand All @@ -222,7 +222,7 @@ func TestAnagramRangeSmall2(t *testing.T) {

func TestAnagramRangeSmallOrderDoesntMatter(t *testing.T) {
is := is.New(t)
d, err := kwg.Get(DefaultConfig, "CSW19")
d, err := kwg.GetKWG(DefaultConfig, "CSW19")
is.NoErr(err)
answers := Anagram("(JQXZ)(AEIOU)", d, ModeExact)
log.Info().Msgf("answers: %v", answers)
Expand All @@ -232,7 +232,7 @@ func TestAnagramRangeSmallOrderDoesntMatter(t *testing.T) {

func TestAnagramRange(t *testing.T) {
is := is.New(t)
d, err := kwg.Get(DefaultConfig, "CSW19")
d, err := kwg.GetKWG(DefaultConfig, "CSW19")
is.NoErr(err)
answers := Anagram("AE(JQXZ)NR?(KY)?", d, ModeExact)
log.Info().Msgf("answers: %v", answers)
Expand Down
11 changes: 4 additions & 7 deletions internal/anagramserver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ const (
)

type Server struct {
Config *wglconfig.Config
Config *wglconfig.Config
WDBConfig *config.Config
}

func timeTrack(start time.Time, name string) {
Expand Down Expand Up @@ -63,7 +64,7 @@ func (s *Server) Anagram(ctx context.Context, req *connect.Request[pb.AnagramReq
*connect.Response[pb.AnagramResponse], error) {
defer timeTrack(time.Now(), "anagram")

dawg, err := kwg.Get(s.Config, req.Msg.Lexicon)
dawg, err := kwg.GetKWG(s.Config, req.Msg.Lexicon)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -108,12 +109,8 @@ func (s *Server) Anagram(ctx context.Context, req *connect.Request[pb.AnagramReq
var words []*pb.Word
if req.Msg.Expand && len(sols) > 0 {
// Build an expand request.

// searchServer needs a *config.Config
cfg := &config.Config{}
cfg.DataPath = s.Config.DataPath
expander := &searchserver.Server{
Config: cfg,
Config: s.WDBConfig,
}
alphagram := &pb.Alphagram{
Alphagram: req.Msg.Letters, // not technically an alphagram but doesn't matter rn
Expand Down
65 changes: 65 additions & 0 deletions internal/querygen/clauses.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,71 @@ func (lc *LimitOffsetClause) Render() (string, []interface{}, error) {
return "LIMIT ? OFFSET ?", []interface{}{limit, offset}, nil
}

// WhereHooksClause handles front_hooks and back_hooks searches
type WhereHooksClause struct {
column string
hooks string
notCondition bool
}

func (w *WhereHooksClause) Render() (string, []interface{}, error) {
var clauses []string
var bindParams []interface{}

// Special handling for empty hooks
if w.hooks == "" {
if w.notCondition {
// Search for words that have some hooks (non-empty)
return fmt.Sprintf("%s != ?", w.column), []interface{}{""}, nil
} else {
// Search for words that have no hooks (empty)
return fmt.Sprintf("%s = ?", w.column), []interface{}{""}, nil
}
}

if w.notCondition {
// Search for words that do NOT contain any of the specified hook letters
for _, letter := range w.hooks {
clauses = append(clauses, fmt.Sprintf("%s NOT LIKE ?", w.column))
bindParams = append(bindParams, fmt.Sprintf("%%%c%%", letter))
}
condition := "(" + strings.Join(clauses, " AND ") + ")"
return condition, bindParams, nil
} else {
// Search for words that contain at least one of the specified hook letters
for _, letter := range w.hooks {
clauses = append(clauses, fmt.Sprintf("%s LIKE ?", w.column))
bindParams = append(bindParams, fmt.Sprintf("%%%c%%", letter))
}
condition := "(" + strings.Join(clauses, " OR ") + ")"
return condition, bindParams, nil
}
}

// WhereInnerHooksClause handles inner_hooks searches
type WhereInnerHooksClause struct {
hasInnerHooks bool
}

func (w *WhereInnerHooksClause) Render() (string, []interface{}, error) {
if w.hasInnerHooks {
return "(inner_front_hook = 1 OR inner_back_hook = 1)", []interface{}{}, nil
} else {
return "(inner_front_hook = 0 AND inner_back_hook = 0)", []interface{}{}, nil
}
}

// WhereDefinitionContainsClause handles definition searches
type WhereDefinitionContainsClause struct {
searchTerm string
}

func (w *WhereDefinitionContainsClause) Render() (string, []interface{}, error) {
condition := "definition LIKE ? COLLATE NOCASE"
bindParams := []interface{}{"%" + w.searchTerm + "%"}
return condition, bindParams, nil
}

func isListClause(clause Clause) bool {
// try to cast to a WhereIn clause.
_, ok := clause.(*WhereInClause)
Expand Down
Loading