github.com/GuanceCloud/cliutils@v1.1.21/diskcache/put.go (about)

     1  // Unless explicitly stated otherwise all files in this repository are licensed
     2  // under the MIT License.
     3  // This product includes software developed at Guance Cloud (https://www.guance.com/).
     4  // Copyright 2021-present Guance, Inc.
     5  
     6  package diskcache
     7  
     8  import (
     9  	"encoding/binary"
    10  	"time"
    11  )
    12  
    13  // Put write @data to disk cache, if reached batch size, a new batch is rotated.
    14  // Put is safe to call concurrently with other operations and will
    15  // block until all other operations finish.
    16  func (c *DiskCache) Put(data []byte) error {
    17  	start := time.Now() // count time before lock
    18  
    19  	c.wlock.Lock()
    20  	defer c.wlock.Unlock()
    21  
    22  	defer func() {
    23  		putVec.WithLabelValues(c.path).Inc()
    24  		putBytesVec.WithLabelValues(c.path).Add(float64(len(data)))
    25  		putLatencyVec.WithLabelValues(c.path).Observe(float64(time.Since(start) / time.Microsecond))
    26  		sizeVec.WithLabelValues(c.path).Set(float64(c.size))
    27  	}()
    28  
    29  	if c.capacity > 0 && c.size+int64(len(data)) > c.capacity {
    30  		if err := c.dropBatch(); err != nil {
    31  			return err
    32  		}
    33  	}
    34  
    35  	if c.maxDataSize > 0 && int32(len(data)) > c.maxDataSize {
    36  		return ErrTooLargeData
    37  	}
    38  
    39  	hdr := make([]byte, dataHeaderLen)
    40  
    41  	binary.LittleEndian.PutUint32(hdr, uint32(len(data)))
    42  	if _, err := c.wfd.Write(hdr); err != nil {
    43  		return err
    44  	}
    45  
    46  	if _, err := c.wfd.Write(data); err != nil {
    47  		return err
    48  	}
    49  
    50  	if !c.noSync {
    51  		if err := c.wfd.Sync(); err != nil {
    52  			return err
    53  		}
    54  	}
    55  
    56  	c.curBatchSize += int64(len(data) + dataHeaderLen)
    57  	c.size += int64(len(data) + dataHeaderLen)
    58  	c.wfdLastWrite = time.Now()
    59  
    60  	// rotate new file
    61  	if c.curBatchSize >= c.batchSize {
    62  		if err := c.rotate(); err != nil {
    63  			return err
    64  		}
    65  	}
    66  
    67  	return nil
    68  }