@@ -21,7 +21,7 @@ type BufferMgr struct {
2121 numAvailable int
2222 availableCh chan struct {}
2323
24- // LRU/ Access tracking fields
24+ // Access tracking fields (for LRU or similar).
2525 accessCounter uint64
2626
2727 // Optional statistics.
@@ -39,68 +39,73 @@ func NewBufferMgr(fm *kfile.FileMgr, numBuffs int, policy EvictionPolicy) *Buffe
3939 }
4040}
4141
42- // Pin retrieves (or creates) a Buffer for the given block, possibly blocking until one is available.
43- // The block is looked up (or allocated) using the provided eviction policy .
42+ // Pin attempts to retrieve a buffer for the given block, possibly blocking until a buffer becomes available.
43+ // If no buffers become available within MaxTime, an error is returned .
4444func (bm * BufferMgr ) Pin (blk * kfile.BlockId ) (* Buffer , error ) {
4545 startTime := time .Now ()
4646
47- // Main loop: try to obtain a buffer until success or timeout.
47+ // Main loop: retry until success or timeout.
4848 for {
4949 bm .mu .Lock ()
5050
51- // Try to get the buffer from the policy.
52- buff , err := bm .Policy .Get (* blk ) // returns pinned buffer if found.
53- if err != nil {
54- // Log the error (here we simply print it).
55- fmt .Printf ("warning: error getting buffer from policy: %v\n " , err )
56- } else {
51+ buff , getErr := bm .Policy .Get (* blk )
52+ switch {
53+ case getErr != nil :
54+ // Log the error from Policy.Get but don’t necessarily return unless it's critical.
55+ // The 'not found' scenario might not be an error per se; it could simply return (nil, nil).
56+ fmt .Printf ("debug: Policy.Get returned an error: %v\n " , getErr )
57+
58+ case buff != nil :
59+ // We found the buffer in the policy -> It's a "hit".
5760 bm .hitCounter ++
61+ bm .mu .Unlock ()
62+ return buff , nil
5863 }
59- // If not found and there is availability, allocate a new buffer.
64+
65+ // Not found in the policy, so we need a new buffer if one is available.
6066 if buff == nil && bm .numAvailable > 0 {
6167 bm .missCounter ++
62- buff , err = bm .Policy .AllocateBufferForBlock (* blk )
63- if err != nil {
68+ newBuff , allocErr : = bm .Policy .AllocateBufferForBlock (* blk )
69+ if allocErr != nil {
6470 bm .mu .Unlock ()
65- return nil , fmt .Errorf ("failed to allocate buffer: %w" , err )
71+ return nil , fmt .Errorf ("failed to allocate buffer: %w" , allocErr )
6672 }
6773 bm .numAvailable --
68- }
69- if buff != nil {
7074 bm .mu .Unlock ()
71- return buff , nil
75+ return newBuff , nil
7276 }
7377
74- // Calculate remaining wait time.
78+ // If we reach here, it means buff == nil and bm.numAvailable == 0.
79+
80+ // Check if we’ve timed out.
7581 remaining := MaxTime - time .Since (startTime )
7682 if remaining <= 0 {
7783 bm .mu .Unlock ()
7884 return nil , fmt .Errorf ("no buffers available after waiting %v" , MaxTime )
7985 }
80- // Release lock and wait for a buffer to become free.
86+
87+ // Wait for a buffer to become free. Unlock while waiting.
8188 bm .mu .Unlock ()
8289 select {
8390 case <- bm .availableCh :
84- // A signal indicates a buffer is available; retry .
91+ // A buffer might have been freed; loop again .
8592 case <- time .After (remaining ):
8693 return nil , fmt .Errorf ("no buffers available after waiting %v" , MaxTime )
8794 }
8895 }
8996}
9097
91- // Unpin decrements the pin count of the given buffer. If the buffer becomes unpinned,
92- // it increments bm.numAvailable and signals availableCh that a buffer is free .
98+ // Unpin decrements the pin count of the given buffer. If it becomes unpinned,
99+ // bm.numAvailable is incremented, and a signal is sent on bm.availableCh to notify waiters .
93100func (bm * BufferMgr ) Unpin (buff * Buffer ) {
94101 bm .mu .Lock ()
95102 defer bm .mu .Unlock ()
96103
97- // Unpin the buffer.
98104 if err := buff .Unpin (); err != nil {
99105 // Log a warning rather than panicking.
100106 fmt .Printf ("warning: Unpin called on an unpinned buffer: %v\n " , err )
101107 return
102108 }
103- // If the buffer is now unpinned, update availability.
104109 if ! buff .Pinned () {
105110 bm .numAvailable ++
106111 select {
@@ -110,13 +115,14 @@ func (bm *BufferMgr) Unpin(buff *Buffer) {
110115 }
111116}
112117
113- // updateAccessTime updates a buffer's last access time using the global access counter.
118+ // updateAccessTime sets a buffer’s lastAccessTime using a global counter,
119+ // which can be used by LRU or other replacement policies.
114120func (bm * BufferMgr ) updateAccessTime (buff * Buffer ) {
115121 bm .accessCounter ++
116122 buff .lastAccessTime = bm .accessCounter
117123}
118124
119- // available returns the number of available (unpinned) buffers.
125+ // available returns the current count of available (unpinned) buffers.
120126func (bm * BufferMgr ) available () int {
121127 bm .mu .RLock ()
122128 defer bm .mu .RUnlock ()
0 commit comments