qlog_reader.go (AdGuardHome-0.104.1) | : | qlog_reader.go (AdGuardHome-0.104.3) | ||
---|---|---|---|---|
package querylog | package querylog | |||
import ( | import ( | |||
"errors" | "errors" | |||
"fmt" | ||||
"io" | "io" | |||
"github.com/AdguardTeam/AdGuardHome/internal/agherr" | "github.com/AdguardTeam/AdGuardHome/internal/agherr" | |||
) | ) | |||
// QLogReader allows reading from multiple query log files in the reverse order. | // QLogReader allows reading from multiple query log files in the reverse order. | |||
// | // | |||
// Please note that this is a stateful object. | // Please note that this is a stateful object. | |||
// Internally, it contains a pointer to a particular query log file, and | // Internally, it contains a pointer to a particular query log file, and | |||
// to a specific position in this file, and it reads lines in reverse order | // to a specific position in this file, and it reads lines in reverse order | |||
skipping to change at line 52 | skipping to change at line 53 | |||
currentFile: (len(qFiles) - 1), | currentFile: (len(qFiles) - 1), | |||
}, nil | }, nil | |||
} | } | |||
// Seek performs binary search of a query log record with the specified timestam p. | // Seek performs binary search of a query log record with the specified timestam p. | |||
// If the record is found, it sets QLogReader's position to point to that line, | // If the record is found, it sets QLogReader's position to point to that line, | |||
// so that the next ReadNext call returned this line. | // so that the next ReadNext call returned this line. | |||
// | // | |||
// Returns nil if the record is successfully found. | // Returns nil if the record is successfully found. | |||
// Returns an error if for some reason we could not find a record with the speci fied timestamp. | // Returns an error if for some reason we could not find a record with the speci fied timestamp. | |||
func (r *QLogReader) Seek(timestamp int64) error { | func (r *QLogReader) Seek(timestamp int64) (err error) { | |||
for i := len(r.qFiles) - 1; i >= 0; i-- { | for i := len(r.qFiles) - 1; i >= 0; i-- { | |||
q := r.qFiles[i] | q := r.qFiles[i] | |||
_, _, err := q.Seek(timestamp) | _, _, err = q.Seek(timestamp) | |||
if err == nil || errors.Is(err, ErrEndOfLog) { | if err == nil { | |||
// Our search is finished, and we either found the | // Search is finished, and the searched element have | |||
// element we were looking for or reached the end of the | // been found. Update currentFile only, position is | |||
// log. Update currentFile only, position is already | // already set properly in QLogFile. | |||
// set properly in QLogFile. | ||||
r.currentFile = i | r.currentFile = i | |||
return err | return nil | |||
} else if errors.Is(err, ErrTSTooEarly) { | ||||
// Look at the next file, since we've reached the end of | ||||
// this one. | ||||
continue | ||||
} else if errors.Is(err, ErrTSTooLate) { | ||||
// Just seek to the start then. timestamp is probably | ||||
// between the end of the previous one and the start of | ||||
// this one. | ||||
return r.SeekStart() | ||||
} else if errors.Is(err, ErrTSNotFound) { | ||||
break | ||||
} | } | |||
} | } | |||
return ErrSeekNotFound | return fmt.Errorf("querylog: %w", err) | |||
} | } | |||
// SeekStart changes the current position to the end of the newest file | // SeekStart changes the current position to the end of the newest file | |||
// Please note that we're reading query log in the reverse order | // Please note that we're reading query log in the reverse order | |||
// and that's why log start is actually the end of file | // and that's why log start is actually the end of file | |||
// | // | |||
// Returns nil if we were able to change the current position. | // Returns nil if we were able to change the current position. | |||
// Returns error in any other case. | // Returns error in any other case. | |||
func (r *QLogReader) SeekStart() error { | func (r *QLogReader) SeekStart() error { | |||
if len(r.qFiles) == 0 { | if len(r.qFiles) == 0 { | |||
End of changes. 5 change blocks. | ||||
9 lines changed or deleted | 20 lines changed or added |