// Called when the tap feed receives an updated channel-log document. func (c *channelLogWriter) channelLogUpdated(rawLog []byte) { if c == nil { return } c.cacheMutex.Lock() defer c.cacheMutex.Unlock() lastCachedSequence := c.cachedLog.LastSequence() log := channels.DecodeChangeLog(bytes.NewReader(rawLog), lastCachedSequence, &c.cachedLog) if log == nil { return } log.TruncateTo(CachedChangeLogLength) c.cachedLog = *log }
// Loads a channel's log from the database and returns it. func (c *changesWriter) getChangeLog(channelName string, afterSeq uint64) (*channels.ChangeLog, error) { raw, err := c.bucket.GetRaw(channelLogDocID(channelName)) if err != nil { if base.IsDocNotFoundError(err) { err = nil } return nil, err } log := channels.DecodeChangeLog(bytes.NewReader(raw), afterSeq) if log == nil { // Log is corrupt, so delete it; caller will regenerate it. c.bucket.Delete(channelLogDocID(channelName)) return nil, fmt.Errorf("Corrupt log") } base.LogTo("ChannelLog", "Read %q -- %d bytes, %d entries (since=%d) after #%d", channelName, len(raw), len(log.Entries), log.Since, afterSeq) return log, nil }
// Loads a channel's log from the database and returns it. func (c *channelLogWriter) getChangeLog(afterSeq uint64) (*channels.ChangeLog, error) { c.cacheMutex.RLock() cachedLog := c.cachedLog c.cacheMutex.RUnlock() // Read from cache if available: entries := cachedLog.EntriesAfter(afterSeq) if entries == nil && afterSeq > cachedLog.Since { entries = cachedLog.Entries } if entries != nil { log := &channels.ChangeLog{Since: afterSeq, Entries: entries} if log.HasEmptyEntries() { log = log.CopyRemovingEmptyEntries() } base.LogTo("Changes", "Using cached entries for afterSeq=%d (returning %d)", afterSeq, len(log.Entries)) dbExpvars.Add("channelLogCacheHits", 1) return log, nil } raw, err := c.bucket.GetRaw(channelLogDocID(c.channelName)) if err != nil { if base.IsDocNotFoundError(err) { err = nil } return nil, err } dbExpvars.Add("channelLogCacheMisses", 1) log := channels.DecodeChangeLog(bytes.NewReader(raw), afterSeq, nil) if log == nil { // Log is corrupt, so delete it; caller will regenerate it. c.bucket.Delete(channelLogDocID(c.channelName)) return nil, fmt.Errorf("Corrupt log") } log = log.CopyRemovingEmptyEntries() base.LogTo("ChannelLog", "Read %q -- %d bytes, %d entries (since=%d) after #%d", c.channelName, len(raw), len(log.Entries), log.Since, afterSeq) return log, nil }
func decodeChannelLog(raw []byte) (*channels.ChangeLog, error) { if raw == nil { return nil, nil } return channels.DecodeChangeLog(bytes.NewReader(raw)), nil }