diff --git a/field.go b/field.go index d2bd17223..0927146d4 100644 --- a/field.go +++ b/field.go @@ -1110,7 +1110,7 @@ func (f *Field) createViewIfNotExistsBase(cvm *CreateViewMessage) (*view, bool, // If we already have this view, we can probably assume etcd already // has it. - if view := f.viewMap[cvm.View]; view != nil { + if view := f.viewMap[cvm.View]; view != nil && !view.isClosing() { return view, false, nil } @@ -1142,6 +1142,8 @@ func (f *Field) newView(path, name string) *view { // deleteView removes the view from the field. func (f *Field) deleteView(name string) error { + f.mu.Lock() + defer f.mu.Unlock() view := f.viewMap[name] if view == nil { return ErrInvalidView diff --git a/roaring/roaring.go b/roaring/roaring.go index 78071f505..4d9079d5b 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -444,6 +444,9 @@ func (b *Bitmap) DirectAdd(v uint64) bool { // Contains returns true if v is in the bitmap. func (b *Bitmap) Contains(v uint64) bool { + if b == nil { + return false + } c := b.Containers.Get(highbits(v)) if c == nil { return false diff --git a/view.go b/view.go index 331ef714a..36fa0ba82 100644 --- a/view.go +++ b/view.go @@ -331,11 +331,24 @@ func (v *view) Name() string { return v.name } +func (v *view) isClosing() bool { + select { + case <-v.closing: + return true + default: + return false + } +} + // CreateFragmentIfNotExists returns a fragment in the view by shard. func (v *view) CreateFragmentIfNotExists(shard uint64) (*fragment, error) { v.mu.Lock() defer v.mu.Unlock() + if v.isClosing() { + return nil, fmt.Errorf("cannot create fragment, view is closed") + } + // Find fragment in cache first. if frag := v.fragments[shard]; frag != nil { return frag, nil