Chris Lu
5 years ago
3 changed files with 96 additions and 72 deletions
@ -0,0 +1,92 @@ |
|||||
|
package queue |
||||
|
|
||||
|
import ( |
||||
|
"sync" |
||||
|
"time" |
||||
|
|
||||
|
"github.com/golang/protobuf/proto" |
||||
|
|
||||
|
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb" |
||||
|
"github.com/chrislusf/seaweedfs/weed/util" |
||||
|
) |
||||
|
|
||||
|
type LogBuffer struct { |
||||
|
buf []byte |
||||
|
pos int |
||||
|
startTime time.Time |
||||
|
stopTime time.Time |
||||
|
sizeBuf []byte |
||||
|
flushInterval time.Duration |
||||
|
flushFn func(startTime, stopTime time.Time, buf []byte) |
||||
|
isStopping bool |
||||
|
sync.Mutex |
||||
|
} |
||||
|
|
||||
|
func NewLogBuffer(flushInterval time.Duration, flushFn func(startTime, stopTime time.Time, buf []byte)) *LogBuffer { |
||||
|
lb := &LogBuffer{ |
||||
|
buf: make([]byte, 4*0124*1024), |
||||
|
sizeBuf: make([]byte, 4), |
||||
|
flushInterval: flushInterval, |
||||
|
flushFn: flushFn, |
||||
|
} |
||||
|
go lb.loopFlush() |
||||
|
return lb |
||||
|
} |
||||
|
|
||||
|
func (m *LogBuffer) AddToBuffer(ts time.Time, key, data []byte) { |
||||
|
|
||||
|
logEntry := &filer_pb.LogEntry{ |
||||
|
TsNs: ts.UnixNano(), |
||||
|
PartitionKeyHash: util.HashToInt32(key), |
||||
|
Data: data, |
||||
|
} |
||||
|
|
||||
|
logEntryData, _ := proto.Marshal(logEntry) |
||||
|
|
||||
|
size := len(logEntryData) |
||||
|
|
||||
|
m.Lock() |
||||
|
defer m.Unlock() |
||||
|
|
||||
|
if m.pos == 0 { |
||||
|
m.startTime = ts |
||||
|
} |
||||
|
|
||||
|
if m.startTime.Add(m.flushInterval).Before(ts) || len(m.buf)-m.pos < size+4 { |
||||
|
m.flush() |
||||
|
m.startTime = ts |
||||
|
} |
||||
|
m.stopTime = ts |
||||
|
|
||||
|
util.Uint32toBytes(m.sizeBuf, uint32(size)) |
||||
|
copy(m.buf[m.pos:m.pos+4], m.sizeBuf) |
||||
|
|
||||
|
copy(m.buf[m.pos+4:m.pos+4+size], logEntryData) |
||||
|
m.pos += size + 4 |
||||
|
} |
||||
|
|
||||
|
func (m *LogBuffer) Shutdown() { |
||||
|
if m.isStopping { |
||||
|
return |
||||
|
} |
||||
|
m.isStopping = true |
||||
|
m.Lock() |
||||
|
m.flush() |
||||
|
m.Unlock() |
||||
|
} |
||||
|
|
||||
|
func (m *LogBuffer) loopFlush() { |
||||
|
for !m.isStopping { |
||||
|
m.Lock() |
||||
|
m.flush() |
||||
|
m.Unlock() |
||||
|
time.Sleep(m.flushInterval) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func (m *LogBuffer) flush() { |
||||
|
if m.flushFn != nil && m.pos > 0 { |
||||
|
m.flushFn(m.startTime, m.stopTime, m.buf[:m.pos]) |
||||
|
m.pos = 0 |
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue