github.com/rohankumardubey/proxyfs@v0.0.0-20210108201508-653efa9ab00e/inode/cache.go (about)

     1  package inode
     2  
     3  import (
     4  	"fmt"
     5  	"time"
     6  
     7  	"github.com/swiftstack/ProxyFS/conf"
     8  	"github.com/swiftstack/ProxyFS/logger"
     9  	"github.com/swiftstack/ProxyFS/platform"
    10  )
    11  
    12  func adoptVolumeGroupReadCacheParameters(confMap conf.ConfMap) (err error) {
    13  	var (
    14  		readCacheLineCount     uint64
    15  		readCacheMemSize       uint64
    16  		readCacheQuotaFraction float64
    17  		readCacheTotalSize     uint64
    18  		readCacheWeightSum     uint64
    19  		totalMemSize           uint64
    20  		volumeGroup            *volumeGroupStruct
    21  	)
    22  
    23  	readCacheWeightSum = 0
    24  
    25  	for _, volumeGroup = range globals.volumeGroupMap {
    26  		if 0 < volumeGroup.numServed {
    27  			readCacheWeightSum += volumeGroup.readCacheWeight
    28  		}
    29  	}
    30  
    31  	readCacheQuotaFraction, err = confMap.FetchOptionValueFloat64("Peer:"+globals.whoAmI, "ReadCacheQuotaFraction")
    32  	if nil != err {
    33  		return
    34  	}
    35  	if (0 > readCacheQuotaFraction) || (1 < readCacheQuotaFraction) {
    36  		err = fmt.Errorf("%s.ReadCacheQuotaFraction (%v) must be between 0 and 1", globals.whoAmI, readCacheQuotaFraction)
    37  		return
    38  	}
    39  
    40  	totalMemSize = platform.MemSize()
    41  
    42  	readCacheMemSize = uint64(float64(totalMemSize) * readCacheQuotaFraction / platform.GoHeapAllocationMultiplier)
    43  
    44  	logger.Infof("Adopting ReadCache Parameters...")
    45  	logger.Infof("...ReadCacheQuotaFraction(%v) of memSize(0x%016X) totals 0x%016X",
    46  		readCacheQuotaFraction,
    47  		totalMemSize,
    48  		readCacheMemSize)
    49  
    50  	for _, volumeGroup = range globals.volumeGroupMap {
    51  		if 0 < volumeGroup.numServed {
    52  			readCacheTotalSize = readCacheMemSize * volumeGroup.readCacheWeight / readCacheWeightSum
    53  
    54  			readCacheLineCount = readCacheTotalSize / volumeGroup.readCacheLineSize
    55  			if 0 == readCacheLineCount {
    56  				logger.Infof("Computed 0 ReadCacheLines for Volume Group %v; increasing to 1",
    57  					volumeGroup.name)
    58  				readCacheLineCount = 1
    59  			}
    60  
    61  			volumeGroup.Lock()
    62  			volumeGroup.readCacheLineCount = readCacheLineCount
    63  			volumeGroup.capReadCacheWhileLocked()
    64  			volumeGroup.Unlock()
    65  
    66  			logger.Infof("...0x%08X cache lines (each of size 0x%08X) totalling 0x%016X for Volume Group %v",
    67  				volumeGroup.readCacheLineCount,
    68  				volumeGroup.readCacheLineSize,
    69  				volumeGroup.readCacheLineCount*volumeGroup.readCacheLineSize,
    70  				volumeGroup.name)
    71  		}
    72  	}
    73  
    74  	err = nil
    75  	return
    76  }
    77  
    78  func startInodeCacheDiscard(confMap conf.ConfMap, volume *volumeStruct, volumeSectionName string) (err error) {
    79  	var (
    80  		LRUCacheMaxBytes       uint64
    81  		LRUDiscardTimeInterval time.Duration
    82  	)
    83  
    84  	LRUCacheMaxBytes, err = confMap.FetchOptionValueUint64(volumeSectionName, "MaxBytesInodeCache")
    85  	if nil != err {
    86  		LRUCacheMaxBytes = 10485760 // TODO - Remove setting a default value
    87  		err = nil
    88  	}
    89  	volume.inodeCacheLRUMaxBytes = LRUCacheMaxBytes
    90  
    91  	LRUDiscardTimeInterval, err = confMap.FetchOptionValueDuration(volumeSectionName, "InodeCacheEvictInterval")
    92  	if nil != err {
    93  		LRUDiscardTimeInterval = 1 * time.Second // TODO - Remove setting a default value
    94  		err = nil
    95  	}
    96  
    97  	if LRUDiscardTimeInterval != 0 {
    98  		volume.inodeCacheLRUTickerInterval = LRUDiscardTimeInterval
    99  		volume.inodeCacheLRUTicker = time.NewTicker(volume.inodeCacheLRUTickerInterval)
   100  
   101  		logger.Infof("Inode cache discard ticker for 'volume: %v' is: %v MaxBytesInodeCache: %v",
   102  			volume.volumeName, volume.inodeCacheLRUTickerInterval, volume.inodeCacheLRUMaxBytes)
   103  
   104  		// Start ticker for inode cache discard thread
   105  		volume.inodeCacheWG.Add(1)
   106  		go func() {
   107  			for {
   108  				select {
   109  				case _ = <-volume.inodeCacheLRUTicker.C:
   110  					_, _, _, _ = volume.inodeCacheDiscard()
   111  				case _, _ = <-volume.inodeCacheStopChan:
   112  					volume.inodeCacheWG.Done()
   113  					return
   114  				}
   115  			}
   116  		}()
   117  	} else {
   118  		logger.Infof("Inode cache discard ticker for 'volume: %v' is disabled.",
   119  			volume.volumeName)
   120  		return
   121  	}
   122  
   123  	return
   124  }
   125  
   126  func stopInodeCacheDiscard(volume *volumeStruct) {
   127  	if volume.inodeCacheLRUTicker != nil {
   128  		volume.inodeCacheLRUTicker.Stop()
   129  		close(volume.inodeCacheStopChan)
   130  		volume.inodeCacheWG.Wait()
   131  		logger.Infof("Inode cache discard ticker for 'volume: %v' stopped.",
   132  			volume.volumeName)
   133  	}
   134  }