From 580d9013b213a318194b6e844d693cad9c49aff7 Mon Sep 17 00:00:00 2001 From: Marty Schoch Date: Thu, 14 May 2015 09:50:10 -0400 Subject: [PATCH] fix registering tokenizers with dependencies closes #201 --- mapping_index.go | 31 +++++++++++++++++--- mapping_test.go | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 4 deletions(-) diff --git a/mapping_index.go b/mapping_index.go index edb95f49..18692ff5 100644 --- a/mapping_index.go +++ b/mapping_index.go @@ -40,10 +40,33 @@ func (c *customAnalysis) registerAll(i *IndexMapping) error { return err } } - for name, config := range c.Tokenizers { - _, err := i.cache.DefineTokenizer(name, config) - if err != nil { - return err + + if len(c.Tokenizers) > 0 { + // put all the names in map tracking work to do + todo := map[string]struct{}{} + for name, _ := range c.Tokenizers { + todo[name] = struct{}{} + } + registered := 1 + errs := []error{} + // as long as we keep making progress, keep going + for len(todo) > 0 && registered > 0 { + registered = 0 + errs = []error{} + for name, _ := range todo { + config := c.Tokenizers[name] + _, err := i.cache.DefineTokenizer(name, config) + if err != nil { + errs = append(errs, err) + } else { + delete(todo, name) + registered++ + } + } + } + + if len(errs) > 0 { + return errs[0] } } for name, config := range c.TokenMaps { diff --git a/mapping_test.go b/mapping_test.go index 6d947768..8918e7fe 100644 --- a/mapping_test.go +++ b/mapping_test.go @@ -244,3 +244,78 @@ func TestMappingForPath(t *testing.T) { } } + +func TestMappingWithTokenizerDeps(t *testing.T) { + + tokNoDeps := map[string]interface{}{ + "type": "regexp", + "regexp": "", + } + + tokDepsL1 := map[string]interface{}{ + "type": "exception", + "tokenizer": "a", + } + + // this tests a 1-level dependency + // it is run 100 times to increase the + // likelihood that it fails along time way + // (depends on key order iteration in map) + for i := 0; i < 100; i++ { + + m := NewIndexMapping() + ca := customAnalysis{ + Tokenizers: map[string]map[string]interface{}{ + "a": tokNoDeps, + "b": tokDepsL1, + }, + } + err := ca.registerAll(m) + if err != nil { + t.Fatal(err) + } + } + + tokDepsL2 := map[string]interface{}{ + "type": "exception", + "tokenizer": "b", + } + + // now test a second-level dependency + for i := 0; i < 100; i++ { + + m := NewIndexMapping() + ca := customAnalysis{ + Tokenizers: map[string]map[string]interface{}{ + "a": tokNoDeps, + "b": tokDepsL1, + "c": tokDepsL2, + }, + } + err := ca.registerAll(m) + if err != nil { + t.Fatal(err) + } + } + + tokUnsatisfied := map[string]interface{}{ + "type": "exception", + "tokenizer": "e", + } + + // now make sure an unsatisfied dep still + // results in an error + m := NewIndexMapping() + ca := customAnalysis{ + Tokenizers: map[string]map[string]interface{}{ + "a": tokNoDeps, + "b": tokDepsL1, + "c": tokDepsL2, + "d": tokUnsatisfied, + }, + } + err := ca.registerAll(m) + if err == nil { + t.Fatal(err) + } +}