From 7a3d005a113fff01248966507c9feaa43f23dc5f Mon Sep 17 00:00:00 2001 From: Marty Schoch Date: Fri, 4 Dec 2020 10:27:03 -0500 Subject: [PATCH] move FieldCache into upsidedown previous the FieldCache type was in the index package, but it is only used by upsidedown, so we relocate it there. --- index/upsidedown/field_cache.go | 88 +++++++++++++++++++++++++++++++++ index/upsidedown/upsidedown.go | 4 +- 2 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 index/upsidedown/field_cache.go diff --git a/index/upsidedown/field_cache.go b/index/upsidedown/field_cache.go new file mode 100644 index 000000000..1f68b71dd --- /dev/null +++ b/index/upsidedown/field_cache.go @@ -0,0 +1,88 @@ +// Copyright (c) 2015 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package upsidedown + +import ( + "sync" +) + +type FieldCache struct { + fieldIndexes map[string]uint16 + indexFields []string + lastFieldIndex int + mutex sync.RWMutex +} + +func NewFieldCache() *FieldCache { + return &FieldCache{ + fieldIndexes: make(map[string]uint16), + lastFieldIndex: -1, + } +} + +func (f *FieldCache) AddExisting(field string, index uint16) { + f.mutex.Lock() + f.addLOCKED(field, index) + f.mutex.Unlock() +} + +func (f *FieldCache) addLOCKED(field string, index uint16) uint16 { + f.fieldIndexes[field] = index + if len(f.indexFields) < int(index)+1 { + prevIndexFields := f.indexFields + f.indexFields = make([]string, int(index)+16) + copy(f.indexFields, prevIndexFields) + } + f.indexFields[int(index)] = field + if int(index) > f.lastFieldIndex { + f.lastFieldIndex = int(index) + } + return index +} + +// FieldNamed returns the index of the field, and whether or not it existed +// before this call. if createIfMissing is true, and new field index is assigned +// but the second return value will still be false +func (f *FieldCache) FieldNamed(field string, createIfMissing bool) (uint16, bool) { + f.mutex.RLock() + if index, ok := f.fieldIndexes[field]; ok { + f.mutex.RUnlock() + return index, true + } else if !createIfMissing { + f.mutex.RUnlock() + return 0, false + } + // trade read lock for write lock + f.mutex.RUnlock() + f.mutex.Lock() + // need to check again with write lock + if index, ok := f.fieldIndexes[field]; ok { + f.mutex.Unlock() + return index, true + } + // assign next field id + index := f.addLOCKED(field, uint16(f.lastFieldIndex+1)) + f.mutex.Unlock() + return index, false +} + +func (f *FieldCache) FieldIndexed(index uint16) (field string) { + f.mutex.RLock() + if int(index) < len(f.indexFields) { + field = f.indexFields[int(index)] + } + f.mutex.RUnlock() + return field +} diff --git a/index/upsidedown/upsidedown.go b/index/upsidedown/upsidedown.go index 11ae985e4..6062e97c7 100644 --- a/index/upsidedown/upsidedown.go +++ b/index/upsidedown/upsidedown.go @@ -54,7 +54,7 @@ type UpsideDownCouch struct { storeName string storeConfig map[string]interface{} store store.KVStore - fieldCache *index.FieldCache + fieldCache *FieldCache analysisQueue *index.AnalysisQueue stats *indexStat @@ -74,7 +74,7 @@ type docBackIndexRow struct { func NewUpsideDownCouch(storeName string, storeConfig map[string]interface{}, analysisQueue *index.AnalysisQueue) (index.Index, error) { rv := &UpsideDownCouch{ version: Version, - fieldCache: index.NewFieldCache(), + fieldCache: NewFieldCache(), storeName: storeName, storeConfig: storeConfig, analysisQueue: analysisQueue,