Changeset 408 in code for trunk/logger.go


Ignore:
Timestamp:
Aug 20, 2020, 6:05:01 PM (5 years ago)
Author:
contact
Message:

Introduce loadHistoryLatestID

This loads latest messages from logs up to a given message ID. This is
similar to the IRCv3 CHATHISTORY LATEST command [1].

[1]: https://github.com/ircv3/ircv3-specifications/blob/0c271a5f1df4f93b5ae4c7597422821c40a8cfeb/extensions/chathistory.md#latest

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/logger.go

    r407 r408  
    234234}
    235235
    236 func parseMessagesBefore(network *network, entity string, ref time.Time, limit int) ([]*irc.Message, error) {
     236func parseMessagesBefore(network *network, entity string, ref time.Time, limit int, afterOffset int64) ([]*irc.Message, error) {
    237237        path := logPath(network, entity, ref)
    238238        f, err := os.Open(path)
     
    249249
    250250        sc := bufio.NewScanner(f)
     251
     252        if afterOffset >= 0 {
     253                if _, err := f.Seek(afterOffset, io.SeekStart); err != nil {
     254                        return nil, nil
     255                }
     256                sc.Scan() // skip till next newline
     257        }
     258
    251259        for sc.Scan() {
    252260                msg, t, err := parseMessage(sc.Text(), entity, ref)
     
    317325        tries := 0
    318326        for remaining > 0 && tries < messageLoggerMaxTries {
    319                 buf, err := parseMessagesBefore(network, entity, t, remaining)
     327                buf, err := parseMessagesBefore(network, entity, t, remaining, -1)
    320328                if err != nil {
    321329                        return nil, err
     
    357365        return history, nil
    358366}
     367
     368func truncateDay(t time.Time) time.Time {
     369        year, month, day := t.Date()
     370        return time.Date(year, month, day, 0, 0, 0, 0, t.Location())
     371}
     372
     373func loadHistoryLatestID(network *network, entity, id string, limit int) ([]*irc.Message, error) {
     374        var afterTime time.Time
     375        var afterOffset int64
     376        if id != "" {
     377                var idNet, idEntity string
     378                var err error
     379                idNet, idEntity, afterTime, afterOffset, err = parseMsgID(id)
     380                if err != nil {
     381                        return nil, err
     382                }
     383                if idNet != network.GetName() || idEntity != entity {
     384                        return nil, fmt.Errorf("cannot find message ID: message ID doesn't match network/entity")
     385                }
     386        }
     387
     388        history := make([]*irc.Message, limit)
     389        t := time.Now()
     390        remaining := limit
     391        tries := 0
     392        for remaining > 0 && tries < messageLoggerMaxTries && !truncateDay(t).Before(afterTime) {
     393                var offset int64 = -1
     394                if afterOffset >= 0 && truncateDay(t).Equal(afterTime) {
     395                        offset = afterOffset
     396                }
     397
     398                buf, err := parseMessagesBefore(network, entity, t, remaining, offset)
     399                if err != nil {
     400                        return nil, err
     401                }
     402                if len(buf) == 0 {
     403                        tries++
     404                } else {
     405                        tries = 0
     406                }
     407                copy(history[remaining-len(buf):], buf)
     408                remaining -= len(buf)
     409                year, month, day := t.Date()
     410                t = time.Date(year, month, day, 0, 0, 0, 0, t.Location()).Add(-1)
     411        }
     412
     413        return history[remaining:], nil
     414}
Note: See TracChangeset for help on using the changeset viewer.