gitlab.com/SiaPrime/SiaPrime@v1.4.1/modules/renter/stuckstack.go (about) 1 package renter 2 3 import ( 4 "sync" 5 6 "gitlab.com/SiaPrime/SiaPrime/modules" 7 ) 8 9 type ( 10 // stuckStack contains a LIFO stack of files that have had a stuck chunk 11 // successfully repaired 12 stuckStack struct { 13 stack []modules.SiaPath 14 siaPaths map[modules.SiaPath]struct{} 15 16 mu sync.Mutex 17 } 18 ) 19 20 // callNewStuckStack returns an initialized stuckStack 21 func callNewStuckStack() stuckStack { 22 return stuckStack{ 23 stack: make([]modules.SiaPath, 0, maxSuccessfulStuckRepairFiles), 24 siaPaths: make(map[modules.SiaPath]struct{}), 25 } 26 } 27 28 // managedLen returns the length of the stack 29 func (ss *stuckStack) managedLen() int { 30 ss.mu.Lock() 31 defer ss.mu.Unlock() 32 return len(ss.stack) 33 } 34 35 // managedPop returns the top element in the stack 36 func (ss *stuckStack) managedPop() (sp modules.SiaPath) { 37 ss.mu.Lock() 38 defer ss.mu.Unlock() 39 40 // Check that there are elements to return 41 if len(ss.stack) == 0 { 42 return 43 } 44 45 // Pop top element 46 sp, ss.stack = ss.stack[len(ss.stack)-1], ss.stack[:len(ss.stack)-1] 47 delete(ss.siaPaths, sp) 48 return 49 } 50 51 // managedPush tries to add a file to the stack 52 func (ss *stuckStack) managedPush(siaPath modules.SiaPath) { 53 ss.mu.Lock() 54 defer ss.mu.Unlock() 55 56 // Check if there is room in the stack 57 if len(ss.stack) >= maxSuccessfulStuckRepairFiles { 58 // Prune oldest elements 59 pruneToIndex := len(ss.stack) - maxSuccessfulStuckRepairFiles + 1 60 ss.stack = ss.stack[pruneToIndex:] 61 } 62 63 // Check if the file is already being tracked 64 if _, ok := ss.siaPaths[siaPath]; ok { 65 // Remove the old entry from the array 66 // 67 // NOTE: currently just iterating over the array since the array is 68 // known to be very small. If this changes in the future a heap or 69 // linked list should be used in order to avoid this slow iteration 70 for i, sp := range ss.stack { 71 if !siaPath.Equals(sp) { 72 continue 73 } 74 ss.stack = append(ss.stack[:i], ss.stack[i+1:]...) 75 break 76 } 77 } 78 79 // Add file to the stack 80 ss.stack = append(ss.stack, siaPath) 81 ss.siaPaths[siaPath] = struct{}{} 82 return 83 }