Pull request: querylog: fix logic

Merge in DNS/adguard-home from fix-querylog-logs to master

Squashed commit of the following:

commit db6edb86f1f024c85efd3bca3ceb6dfc6ce04edd
Merge: d1981696 a3968658
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon Dec 13 13:48:25 2021 +0300

    Merge branch 'master' into fix-querylog-logs

commit d1981696782ca9adc5213f76cdbe2dc9f859f921
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Fri Dec 10 21:14:04 2021 +0300

    querylog: fix logic
This commit is contained in:
Ainar Garipov 2021-12-13 13:55:41 +03:00
parent a396865869
commit 0bd436f4b0
6 changed files with 40 additions and 29 deletions

View File

@ -92,6 +92,8 @@ func IfaceDNSIPAddrs(
time.Sleep(backoff) time.Sleep(backoff)
} }
n--
switch len(addrs) { switch len(addrs) {
case 0: case 0:
// Don't return errors in case the users want to try and enable // Don't return errors in case the users want to try and enable

View File

@ -54,7 +54,7 @@ func NewQLogFile(path string) (*QLogFile, error) {
}, nil }, nil
} }
// SeekTS performs binary search in the query log file looking for a record // seekTS performs binary search in the query log file looking for a record
// with the specified timestamp. Once the record is found, it sets // with the specified timestamp. Once the record is found, it sets
// "position" so that the next ReadNext call returned that record. // "position" so that the next ReadNext call returned that record.
// //
@ -71,7 +71,7 @@ func NewQLogFile(path string) (*QLogFile, error) {
// so that when we call "ReadNext" this line was returned. // so that when we call "ReadNext" this line was returned.
// * Depth of the search (how many times we compared timestamps). // * Depth of the search (how many times we compared timestamps).
// * If we could not find it, it returns one of the errors described above. // * If we could not find it, it returns one of the errors described above.
func (q *QLogFile) SeekTS(timestamp int64) (int64, int, error) { func (q *QLogFile) seekTS(timestamp int64) (int64, int, error) {
q.lock.Lock() q.lock.Lock()
defer q.lock.Unlock() defer q.lock.Unlock()

View File

@ -175,7 +175,7 @@ func TestQLogFile_SeekTS_good(t *testing.T) {
assert.NotEqualValues(t, 0, ts) assert.NotEqualValues(t, 0, ts)
// Try seeking to that line now. // Try seeking to that line now.
pos, _, err := q.SeekTS(ts) pos, _, err := q.seekTS(ts)
require.NoError(t, err) require.NoError(t, err)
assert.NotEqualValues(t, 0, pos) assert.NotEqualValues(t, 0, pos)
@ -228,7 +228,7 @@ func TestQLogFile_SeekTS_bad(t *testing.T) {
assert.NotEqualValues(t, 0, tc.ts) assert.NotEqualValues(t, 0, tc.ts)
var depth int var depth int
_, depth, err = q.SeekTS(tc.ts) _, depth, err = q.seekTS(tc.ts)
assert.NotEmpty(t, l.num) assert.NotEmpty(t, l.num)
require.Error(t, err) require.Error(t, err)
@ -340,7 +340,7 @@ func TestQLog_Seek(t *testing.T) {
q := NewTestQLogFileData(t, data) q := NewTestQLogFileData(t, data)
_, depth, err := q.SeekTS(timestamp.Add(time.Second * time.Duration(tc.delta)).UnixNano()) _, depth, err := q.seekTS(timestamp.Add(time.Second * time.Duration(tc.delta)).UnixNano())
require.Truef(t, errors.Is(err, tc.wantErr), "%v", err) require.Truef(t, errors.Is(err, tc.wantErr), "%v", err)
assert.Equal(t, tc.wantDepth, depth) assert.Equal(t, tc.wantDepth, depth)
}) })

View File

@ -53,35 +53,44 @@ func NewQLogReader(files []string) (*QLogReader, error) {
}, nil }, nil
} }
// SeekTS performs binary search of a query log record with the specified // seekTS performs binary search of a query log record with the specified
// timestamp. If the record is found, it sets QLogReader's position to point to // timestamp. If the record is found, it sets QLogReader's position to point to
// that line, so that the next ReadNext call returned this line. // that line, so that the next ReadNext call returned this line.
func (r *QLogReader) SeekTS(timestamp int64) (err error) { func (r *QLogReader) seekTS(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.SeekTS(timestamp) _, _, err = q.seekTS(timestamp)
if err == nil { if err != nil {
// Search is finished, and the searched element have if errors.Is(err, ErrTSTooEarly) {
// been found. Update currentFile only, position is // Look at the next file, since we've reached the end of this
// already set properly in QLogFile. // one. If there is no next file, it's not found.
err = ErrTSNotFound
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) {
return err
} else {
return fmt.Errorf("seekts: file at index %d: %w", i, err)
}
}
// The search is finished, and the searched element has been found.
// Update currentFile only, position is already set properly in
// QLogFile.
r.currentFile = i r.currentFile = i
return nil 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 fmt.Errorf("querylog: %w", err) if err != nil {
return fmt.Errorf("seekts: %w", err)
}
return nil
} }
// SeekStart changes the current position to the end of the newest file // SeekStart changes the current position to the end of the newest file

View File

@ -97,7 +97,7 @@ func TestQLogReader_Seek(t *testing.T) {
}, { }, {
name: "non-existent_long_ago", name: "non-existent_long_ago",
time: "2000-02-19T01:23:16.920973+03:00", time: "2000-02-19T01:23:16.920973+03:00",
want: ErrTSTooEarly, want: ErrTSNotFound,
}, { }, {
name: "non-existent_far_ahead", name: "non-existent_far_ahead",
time: "2100-02-19T01:23:16.920973+03:00", time: "2100-02-19T01:23:16.920973+03:00",
@ -113,7 +113,7 @@ func TestQLogReader_Seek(t *testing.T) {
ts, err := time.Parse(time.RFC3339Nano, tc.time) ts, err := time.Parse(time.RFC3339Nano, tc.time)
require.NoError(t, err) require.NoError(t, err)
err = r.SeekTS(ts.UnixNano()) err = r.seekTS(ts.UnixNano())
assert.ErrorIs(t, err, tc.want) assert.ErrorIs(t, err, tc.want)
}) })
} }

View File

@ -152,7 +152,7 @@ func (l *queryLog) searchFiles(
if params.olderThan.IsZero() { if params.olderThan.IsZero() {
err = r.SeekStart() err = r.SeekStart()
} else { } else {
err = r.SeekTS(params.olderThan.UnixNano()) err = r.seekTS(params.olderThan.UnixNano())
if err == nil { if err == nil {
// Read to the next record, because we only need the one // Read to the next record, because we only need the one
// that goes after it. // that goes after it.