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:
parent
a396865869
commit
0bd436f4b0
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
})
|
})
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue