// Remove entry from request log and compact func (this *RequestLog) ditch(id string) errors.Error { cacheNum := util.HashString(id, _CACHES) this.locks[cacheNum].Lock() defer this.locks[cacheNum].Unlock() logMap, ok := this.requestMaps[cacheNum][id] if ok { delete(this.requestMaps[cacheNum], id) l := len(this.requestMaps[cacheNum]) // Nature abhors a vacuum! // We copy the last map entry onto the currently empty entry. // This is a quick way to keep the two caches in sync without // reallocating memory and / or copying huge quantities of data, // but it does mean that for scans occurring during deletes, // later entries might be skipped. // Given the fact that deletes will likely purge huge numbers of // entries, copying subslices on a per deleted row basis has the // potential for a significant bottleneck. // Given the huge benefit in lock contention and memory usage, we // are willing to take that risk. if logMap.logIdx < l { this.requestCaches[cacheNum][logMap.logIdx] = this.requestCaches[cacheNum][l] newMap := this.requestMaps[cacheNum][this.requestCaches[cacheNum][l].RequestId] newMap.logIdx = logMap.logIdx } return nil } else { return errors.NewSystemStmtNotFoundError(nil, id) } }
func (this *RequestLog) add(entry *RequestLogEntry) { var requestLogMap RequestLogMap cacheNum := util.HashString(entry.RequestId, _CACHES) this.locks[cacheNum].Lock() defer this.locks[cacheNum].Unlock() mLen := len(this.requestMaps[cacheNum]) cLen := len(this.requestCaches[cacheNum]) // Resize the slice if required // The map gets handled automatically // TODO handle memory allocation failures if mLen >= cLen { caches := make([]*RequestLogEntry, cLen*2) copy(caches, this.requestCaches[cacheNum]) this.requestCaches[cacheNum] = caches } requestLogMap.logEntry = entry requestLogMap.logIdx = mLen this.requestMaps[cacheNum][entry.RequestId] = requestLogMap this.requestCaches[cacheNum][mLen] = entry }
func (this *RequestLog) get(id string) *RequestLogEntry { cacheNum := util.HashString(id, _CACHES) this.locks[cacheNum].RLock() defer this.locks[cacheNum].RUnlock() return this.requestMaps[cacheNum][id].logEntry }