github.com/go-kivik/kivik/v4@v4.3.2/x/fsdb/compact.go (about) 1 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 // use this file except in compliance with the License. You may obtain a copy of 3 // the License at 4 // 5 // http://www.apache.org/licenses/LICENSE-2.0 6 // 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 // License for the specific language governing permissions and limitations under 11 // the License. 12 13 package fs 14 15 import ( 16 "context" 17 "strings" 18 19 "github.com/go-kivik/kivik/v4" 20 "github.com/go-kivik/kivik/v4/x/fsdb/cdb" 21 "github.com/go-kivik/kivik/v4/x/fsdb/cdb/decode" 22 "github.com/go-kivik/kivik/v4/x/fsdb/filesystem" 23 ) 24 25 type docIndex map[string]*cdb.Document 26 27 func (i docIndex) readIndex(ctx context.Context, fs filesystem.Filesystem, path string) error { 28 dir, err := fs.Open(path) 29 if err != nil { 30 return kerr(err) 31 } 32 files, err := dir.Readdir(-1) 33 if err != nil { 34 return kerr(err) 35 } 36 37 c := cdb.New(path, fs) 38 39 var docID string 40 for _, info := range files { 41 if err := ctx.Err(); err != nil { 42 return err 43 } 44 switch { 45 case !info.IsDir(): 46 id, _, ok := decode.ExplodeFilename(info.Name()) 47 if !ok { 48 // ignore unrecognized files 49 continue 50 } 51 docID = id 52 case info.IsDir() && info.Name()[0] == '.': 53 docID = strings.TrimPrefix(info.Name(), ".") 54 default: 55 continue 56 } 57 if _, ok := i[docID]; ok { 58 // We've already read this one 59 continue 60 } 61 doc, err := c.OpenDocID(docID, kivik.Params(nil)) 62 if err != nil { 63 return err 64 } 65 i[docID] = doc 66 } 67 return nil 68 } 69 70 func (d *db) Compact(ctx context.Context) error { 71 return d.compact(ctx, filesystem.Default()) 72 } 73 74 func (d *db) compact(ctx context.Context, fs filesystem.Filesystem) error { 75 docs := docIndex{} 76 if err := docs.readIndex(ctx, fs, d.path()); err != nil { 77 return err 78 } 79 for _, doc := range docs { 80 if err := doc.Compact(ctx); err != nil { 81 return err 82 } 83 } 84 return nil 85 }