func Exist(dirpath string) bool { names, err := fileutil.ReadDir(dirpath) if err != nil { return false } return len(names) != 0 }
// openLast opens the last wal file for read and write. func openLast(dirpath string) (*os.File, error) { names, err := fileutil.ReadDir(dirpath) if err != nil { return nil, err } names = checkWalNames(names) if len(names) == 0 { return nil, ErrFileNotFound } last := path.Join(dirpath, names[len(names)-1]) return os.OpenFile(last, os.O_RDWR, 0) }
func openAtIndex(dirpath string, snap walpb.Snapshot, write bool) (*WAL, error) { names, err := fileutil.ReadDir(dirpath) if err != nil { return nil, err } names = checkWalNames(names) if len(names) == 0 { return nil, ErrFileNotFound } nameIndex, ok := searchIndex(names, snap.Index) if !ok || !isValidSeq(names[nameIndex:]) { return nil, ErrFileNotFound } // open the wal files for reading rcs := make([]io.ReadCloser, 0) ls := make([]fileutil.Lock, 0) for _, name := range names[nameIndex:] { f, err := os.Open(path.Join(dirpath, name)) if err != nil { return nil, err } l, err := fileutil.NewLock(f.Name()) if err != nil { return nil, err } err = l.TryLock() if err != nil { if write { return nil, err } } rcs = append(rcs, f) ls = append(ls, l) } rc := MultiReadCloser(rcs...) // create a WAL ready for reading w := &WAL{ dir: dirpath, start: snap, decoder: newDecoder(rc), locks: ls, } if write { // open the last wal file for appending seq, _, err := parseWalName(names[len(names)-1]) if err != nil { rc.Close() return nil, err } last := path.Join(dirpath, names[len(names)-1]) f, err := os.OpenFile(last, os.O_WRONLY|os.O_APPEND, 0) if err != nil { rc.Close() return nil, err } err = fileutil.Preallocate(f, segmentSizeBytes) if err != nil { rc.Close() plog.Errorf("failed to allocate space when creating new wal file (%v)", err) return nil, err } w.f = f w.seq = seq } return w, nil }