func (l *Layer) ListFiles(after string, limit int) ([]File, error) { if limit < 0 { return nil, ErrBadArgument } var query kvl.RangeQuery query.Low = fileKey(after) query.High = keys.PrefixNext(tuple.MustAppend(nil, "file")) if limit > 0 { query.Limit = limit + 1 } pairs, err := l.inner.Range(query) if err != nil { return nil, err } files := make([]File, 0, len(pairs)) for _, pair := range pairs { var f File err := f.fromPair(pair) if err != nil { return nil, err } if f.Path > after { files = append(files, f) if limit > 0 && len(files) == limit { break } } } return files, nil }
func (l *Layer) GetFilesByLocation(id [16]byte, count int) ([]File, error) { var rang kvl.RangeQuery rang.Low, rang.High = keys.PrefixRange(tuple.MustAppend(nil, "file", "location", id)) rang.Limit = count ps, err := l.index.Range(rang) if err != nil { return nil, err } fs := make([]File, 0, len(ps)) for _, p := range ps { var typ, detail, path string var loc [16]byte err := tuple.UnpackInto(p.Key, &typ, &detail, &loc, &path) if err != nil { return nil, err } f, err := l.GetFile(path) if err != nil { return nil, err } if f != nil { fs = append(fs, *f) } } return fs, nil }
func (l *Layer) GetLocationContents(id [16]byte, after string, count int) ([]string, error) { var rang kvl.RangeQuery rang.Low = keys.LexNext(tuple.MustAppend(nil, "locationlist", id, after)) rang.High = keys.PrefixNext(tuple.MustAppend(nil, "locationlist", id)) if count > 0 { rang.Limit = count + 1 } ps, err := l.index.Range(rang) if err != nil { return nil, err } names := make([]string, 0, len(ps)) for _, p := range ps { var typ, name string var loc [16]byte err := tuple.UnpackInto(p.Key, &typ, &loc, &name) if err != nil { return nil, err } if name > after { names = append(names, name) if count > 0 && len(names) >= count { break } } } return names, nil }
func (l *Layer) WALClearOld() error { var rang kvl.RangeQuery rang.Low, rang.High = keys.PrefixRange(tuple.MustAppend(nil, "wal2")) rang.Limit = 100 for { ps, err := l.inner.Range(rang) if err != nil { return err } now := time.Now().Unix() for _, p := range ps { var typ string var id [16]byte err = tuple.UnpackInto(p.Key, &typ, &id) if err != nil { return err } timestamps, err := walParse(p.Value) if err != nil { return err } newestAge := time.Duration(now-timestamps[len(timestamps)-1]) * time.Second oldestAge := time.Duration(now-timestamps[0]) * time.Second if newestAge < -walUnsafeFutureAge { log.Printf("WARNING: WAL entry %v is %v in the future! Skipping it.", uuid.Fmt(id), newestAge) } else if oldestAge > walUnsafeOldAge { log.Printf("WARNING: WAL entry %v is %v in the past! Skipping it.", uuid.Fmt(id), oldestAge) } else if oldestAge > walExpireAge { log.Printf("Removing expired WAL entry %v (%v old)", uuid.Fmt(id), oldestAge) // Remove the oldest timestamp (only); we'll get to the other timestamps // in future passes if needed. timestamps = timestamps[1:] if len(timestamps) == 0 { err = l.inner.Delete(p.Key) if err != nil { return err } } else { err = l.inner.Set(kvl.Pair{p.Key, walDump(timestamps)}) if err != nil { return err } } } } if len(ps) < rang.Limit { break } rang.Low = ps[len(ps)-1].Key } return nil }