add lock around existencFld

This commit is contained in:
Travis Turner 2018-09-11 10:24:49 -05:00
parent f8c745340f
commit f7abf60627
No known key found for this signature in database
GPG key ID: 7F08008DFD9314C9
4 changed files with 17 additions and 14 deletions

6
api.go
View file

@ -741,13 +741,13 @@ func (api *API) ImportValue(_ context.Context, req *ImportValueRequest) error {
}
func importExistenceColumns(index *Index, columnIDs []uint64) error {
nnf := index.unprotectedExistenceField()
if nnf == nil {
ef := index.existenceField()
if ef == nil {
return nil
}
existenceRowIDs := make([]uint64, len(columnIDs))
return nnf.Import(existenceRowIDs, columnIDs, nil)
return ef.Import(existenceRowIDs, columnIDs, nil)
}
// MaxShards returns the maximum shard number for each index in a map.

View file

@ -1132,8 +1132,8 @@ func (e *executor) executeSet(ctx context.Context, index string, c *pql.Call, op
}
// Set column on existence field.
if nnf := idx.unprotectedExistenceField(); nnf != nil {
if _, err := nnf.SetBit(0, colID, nil); err != nil {
if ef := idx.existenceField(); ef != nil {
if _, err := ef.SetBit(0, colID, nil); err != nil {
return false, errors.Wrap(err, "setting existence column")
}
}

View file

@ -36,9 +36,9 @@ type Index struct {
name string
keys bool // use string keys
// Not-null tracking.
// Existence tracking.
trackExistence bool
existenceField *Field
existenceFld *Field
// Fields by name.
fields map[string]*Field
@ -166,7 +166,7 @@ func (i *Index) openExistenceField() error {
if err != nil {
return errors.Wrap(err, "creating existence field")
}
i.existenceField = f
i.existenceFld = f
return nil
}
@ -275,9 +275,12 @@ func (i *Index) Fields() []*Field {
return a
}
// unprotectedExistenceField returns the internal field used to track column existence.
func (i *Index) unprotectedExistenceField() *Field {
return i.existenceField
// existenceField returns the internal field used to track column existence.
func (i *Index) existenceField() *Field {
i.mu.RLock()
defer i.mu.RUnlock()
return i.existenceFld
}
// recalculateCaches recalculates caches on every field in the index.
@ -425,7 +428,7 @@ func (i *Index) DeleteField(name string) error {
// turn off existence tracking on the index.
if name == existenceFieldName {
i.trackExistence = false
i.existenceField = nil
i.existenceFld = nil
// Update meta data on disk.
if err := i.saveMeta(); err != nil {

View file

@ -62,7 +62,7 @@ func TestIndex_Existence_Delete(t *testing.T) {
t.Fatalf("expected field to have been created: %s", existenceFieldName)
} else if !index.trackExistence {
t.Fatalf("expected index.trackExistence to be true")
} else if index.existenceField == nil {
} else if index.existenceFld == nil {
t.Fatalf("expected index.existenceField to be non-nil")
}
@ -82,7 +82,7 @@ func TestIndex_Existence_Delete(t *testing.T) {
t.Fatalf("expected field to have been deleted: %s", existenceFieldName)
} else if index.trackExistence {
t.Fatalf("expected index.trackExistence to be false")
} else if index.existenceField != nil {
} else if index.existenceFld != nil {
t.Fatalf("expected index.existenceField to be nil")
}
}