github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/lib/objectserver/cachingreader/new.go (about)

     1  package cachingreader
     2  
     3  import (
     4  	"sync"
     5  	"syscall"
     6  	"time"
     7  
     8  	"github.com/Cloud-Foundations/Dominator/lib/hash"
     9  	"github.com/Cloud-Foundations/Dominator/lib/log"
    10  	"github.com/Cloud-Foundations/Dominator/lib/objectserver/filesystem/scan"
    11  )
    12  
    13  func newObjectServer(baseDir string, maxCachedBytes uint64,
    14  	objectServerAddress string, logger log.DebugLogger) (*ObjectServer, error) {
    15  	startTime := time.Now()
    16  	var rusageStart, rusageStop syscall.Rusage
    17  	syscall.Getrusage(syscall.RUSAGE_SELF, &rusageStart)
    18  	var mutex sync.Mutex
    19  	objects := make(map[hash.Hash]*objectType)
    20  	var cachedBytes uint64
    21  	err := scan.ScanTree(baseDir, func(hashVal hash.Hash, size uint64) {
    22  		mutex.Lock()
    23  		cachedBytes += size
    24  		objects[hashVal] = &objectType{hash: hashVal, size: size}
    25  		mutex.Unlock()
    26  	})
    27  	if err != nil {
    28  		return nil, err
    29  	}
    30  	plural := ""
    31  	if len(objects) != 1 {
    32  		plural = "s"
    33  	}
    34  	syscall.Getrusage(syscall.RUSAGE_SELF, &rusageStop)
    35  	userTime := time.Duration(rusageStop.Utime.Sec)*time.Second +
    36  		time.Duration(rusageStop.Utime.Usec)*time.Microsecond -
    37  		time.Duration(rusageStart.Utime.Sec)*time.Second -
    38  		time.Duration(rusageStart.Utime.Usec)*time.Microsecond
    39  	logger.Printf("Scanned %d object%s in %s (%s user CPUtime)\n",
    40  		len(objects), plural, time.Since(startTime), userTime)
    41  	lruUpdateNotifier := make(chan struct{}, 1)
    42  	objSrv := &ObjectServer{
    43  		baseDir:             baseDir,
    44  		flushTimer:          time.NewTimer(time.Minute),
    45  		logger:              logger,
    46  		lruUpdateNotifier:   lruUpdateNotifier,
    47  		maxCachedBytes:      maxCachedBytes,
    48  		objectServerAddress: objectServerAddress,
    49  		cachedBytes:         cachedBytes,
    50  		objects:             objects,
    51  	}
    52  	objSrv.flushTimer.Stop()
    53  	if err := objSrv.loadLru(); err != nil {
    54  		return nil, err
    55  	}
    56  	// Link orphaned entries.
    57  	for _, object := range objSrv.objects {
    58  		if objSrv.newest == nil { // Empty list: initialise it.
    59  			objSrv.newest = object
    60  			objSrv.oldest = object
    61  			objSrv.lruBytes += object.size
    62  		} else if object.newer == nil && objSrv.newest != object {
    63  			// Orphaned object: make it the newest.
    64  			object.older = objSrv.newest
    65  			objSrv.newest.newer = object
    66  			objSrv.newest = object
    67  			objSrv.lruBytes += object.size
    68  		}
    69  	}
    70  	go objSrv.flusher(lruUpdateNotifier)
    71  	return objSrv, nil
    72  }