github.com/petermattis/pebble@v0.0.0-20190905164901-ab51a2166067/log_recycler.go (about) 1 // Copyright 2019 The LevelDB-Go and Pebble Authors. All rights reserved. Use 2 // of this source code is governed by a BSD-style license that can be found in 3 // the LICENSE file. 4 5 package pebble 6 7 import ( 8 "fmt" 9 "sync" 10 ) 11 12 type logRecycler struct { 13 limit int 14 mu struct { 15 sync.Mutex 16 logNums []uint64 17 maxLogNum uint64 18 } 19 } 20 21 // add attempts to recycle the log file specified by logNum. Returns true if 22 // the log file should not be deleted (i.e. the log is being recycled), and 23 // false otherwise. 24 func (r *logRecycler) add(logNum uint64) bool { 25 r.mu.Lock() 26 defer r.mu.Unlock() 27 28 if logNum <= r.mu.maxLogNum { 29 // The log file number was already considered for recycling. Don't consider 30 // it again. This avoids a race between adding the same log file for 31 // recycling multiple times, and removing the log file for actual 32 // reuse. Note that we return true because the log was already considered 33 // for recycling and either it was deleted on the previous attempt (which 34 // means we shouldn't get here) or it was recycled and thus the file 35 // shouldn't be deleted. 36 return true 37 } 38 r.mu.maxLogNum = logNum 39 if len(r.mu.logNums) >= r.limit { 40 return false 41 } 42 r.mu.logNums = append(r.mu.logNums, logNum) 43 return true 44 } 45 46 // peek returns the log number at the head of the recycling queue, or zero if 47 // the queue is empty. 48 func (r *logRecycler) peek() uint64 { 49 r.mu.Lock() 50 defer r.mu.Unlock() 51 52 if len(r.mu.logNums) == 0 { 53 return 0 54 } 55 return r.mu.logNums[0] 56 } 57 58 func (r *logRecycler) count() int { 59 r.mu.Lock() 60 defer r.mu.Unlock() 61 return len(r.mu.logNums) 62 } 63 64 // pop removes the log number at the head of the recycling queue, enforcing 65 // that it matches the specifed logNum. An error is returned of the recycling 66 // queue is empty or the head log number does not match the specified one. 67 func (r *logRecycler) pop(logNum uint64) error { 68 r.mu.Lock() 69 defer r.mu.Unlock() 70 71 if len(r.mu.logNums) == 0 { 72 return fmt.Errorf("pebble: log recycler empty") 73 } 74 if r.mu.logNums[0] != logNum { 75 return fmt.Errorf("pebble: log recycler invalid %d vs %d", logNum, r.mu.logNums) 76 } 77 r.mu.logNums = r.mu.logNums[1:] 78 return nil 79 }