github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/log_recycler.go (about) 1 // Copyright 2021 The Bitalosdb author(hustxrb@163.com) and other contributors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package bitalosdb 16 17 import ( 18 "sync" 19 20 "github.com/cockroachdb/errors" 21 ) 22 23 type logRecycler struct { 24 limit int 25 minRecycleLogNum FileNum 26 27 mu struct { 28 sync.Mutex 29 logs []fileInfo 30 maxLogNum FileNum 31 } 32 } 33 34 func (r *logRecycler) add(logInfo fileInfo) bool { 35 if logInfo.fileNum < r.minRecycleLogNum { 36 return false 37 } 38 39 r.mu.Lock() 40 defer r.mu.Unlock() 41 42 if logInfo.fileNum <= r.mu.maxLogNum { 43 return true 44 } 45 r.mu.maxLogNum = logInfo.fileNum 46 if len(r.mu.logs) >= r.limit { 47 return false 48 } 49 r.mu.logs = append(r.mu.logs, logInfo) 50 return true 51 } 52 53 func (r *logRecycler) peek() (fileInfo, bool) { 54 r.mu.Lock() 55 defer r.mu.Unlock() 56 57 if len(r.mu.logs) == 0 { 58 return fileInfo{}, false 59 } 60 return r.mu.logs[0], true 61 } 62 63 func (r *logRecycler) stats() (count int, size uint64) { 64 r.mu.Lock() 65 defer r.mu.Unlock() 66 count = len(r.mu.logs) 67 for i := 0; i < count; i++ { 68 size += r.mu.logs[i].fileSize 69 } 70 return count, size 71 } 72 73 func (r *logRecycler) pop(logNum FileNum) error { 74 r.mu.Lock() 75 defer r.mu.Unlock() 76 77 if len(r.mu.logs) == 0 { 78 return errors.New("bitalosdb: log recycler empty") 79 } 80 if r.mu.logs[0].fileNum != logNum { 81 return errors.Errorf("bitalosdb: log recycler invalid %d vs %d", errors.Safe(logNum), errors.Safe(fileInfoNums(r.mu.logs))) 82 } 83 r.mu.logs = r.mu.logs[1:] 84 return nil 85 } 86 87 func fileInfoNums(finfos []fileInfo) []FileNum { 88 if len(finfos) == 0 { 89 return nil 90 } 91 nums := make([]FileNum, len(finfos)) 92 for i := range finfos { 93 nums[i] = finfos[i].fileNum 94 } 95 return nums 96 }