diff --git a/holder.go b/holder.go index d54fae43e..7fbb1b52c 100644 --- a/holder.go +++ b/holder.go @@ -398,7 +398,7 @@ func (h *Holder) CreateIndex(name string, opt IndexOptions) (*Index, error) { defer h.mu.Unlock() // Ensure index doesn't already exist. - if h.indexes[name] != nil { + if h.index(name) != nil { return nil, newConflictError(ErrIndexExists) } return h.createIndex(name, opt) @@ -407,21 +407,15 @@ func (h *Holder) CreateIndex(name string, opt IndexOptions) (*Index, error) { // CreateIndexIfNotExists returns an index by name. // The index is created if it does not already exist. func (h *Holder) CreateIndexIfNotExists(name string, opt IndexOptions) (*Index, error) { - h.mu.RLock() + h.mu.Lock() + defer h.mu.Unlock() - // Find index in cache first. - if index := h.indexes[name]; index != nil { - h.mu.RUnlock() + // Return index if it exists. + if index := h.index(name); index != nil { return index, nil } - h.mu.RUnlock() - - index, err := h.CreateIndex(name, opt) - if _, ok := err.(ConflictError); err != nil && !ok { - return nil, err - } - return index, nil + return h.createIndex(name, opt) } func (h *Holder) createIndex(name string, opt IndexOptions) (*Index, error) { @@ -429,11 +423,6 @@ func (h *Holder) createIndex(name string, opt IndexOptions) (*Index, error) { return nil, errors.New("index name required") } - // Return index if it exists. - if index := h.index(name); index != nil { - return index, nil - } - // Otherwise create a new index. index, err := h.newIndex(h.IndexPath(name), name) if err != nil { @@ -443,9 +432,10 @@ func (h *Holder) createIndex(name string, opt IndexOptions) (*Index, error) { index.keys = opt.Keys index.trackExistence = opt.TrackExistence - if err := index.Open(); err != nil { + if err = index.Open(); err != nil { return nil, errors.Wrap(err, "opening") - } else if err := index.saveMeta(); err != nil { + } + if err = index.saveMeta(); err != nil { return nil, errors.Wrap(err, "meta") } diff --git a/holder_test.go b/holder_test.go index 3f88703e5..24d42d1a0 100644 --- a/holder_test.go +++ b/holder_test.go @@ -197,7 +197,31 @@ func TestHolder_Open(t *testing.T) { t.Fatalf("unexpected error: %s", err) } }) + // Try to re-create existing index + t.Run("CreateIndexIfNotExists", func(t *testing.T) { + h := test.MustOpenHolder() + defer h.Close() + idx1, err := h.CreateIndexIfNotExists("aaa", pilosa.IndexOptions{}) + if err != nil { + t.Fatal(err) + } + + if _, err = h.CreateIndex("aaa", pilosa.IndexOptions{}); err == nil { + t.Fatalf("expected: ConflictError, got: nil") + } else if _, ok := err.(pilosa.ConflictError); !ok { + t.Fatalf("expected: ConflictError, got: %s", err) + } + + idx2, err := h.CreateIndexIfNotExists("aaa", pilosa.IndexOptions{}) + if err != nil { + t.Fatal(err) + } + + if idx1 != idx2 { + t.Fatalf("expected the same indexes, got: %s and %s", idx1.Name(), idx2.Name()) + } + }) } func TestHolder_HasData(t *testing.T) {