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 }