116 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			116 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Go
		
	
	
package go9p
 | 
						|
 | 
						|
type Log struct {
 | 
						|
	Data  interface{}
 | 
						|
	Owner interface{}
 | 
						|
	Type  int
 | 
						|
}
 | 
						|
 | 
						|
type Logger struct {
 | 
						|
	items   []*Log
 | 
						|
	idx     int
 | 
						|
	logchan chan *Log
 | 
						|
	fltchan chan *flt
 | 
						|
	rszchan chan int
 | 
						|
}
 | 
						|
 | 
						|
type flt struct {
 | 
						|
	owner   interface{}
 | 
						|
	itype   int
 | 
						|
	fltchan chan []*Log
 | 
						|
}
 | 
						|
 | 
						|
func NewLogger(sz int) *Logger {
 | 
						|
	if sz == 0 {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	l := new(Logger)
 | 
						|
	l.items = make([]*Log, sz)
 | 
						|
	l.logchan = make(chan *Log, 16)
 | 
						|
	l.fltchan = make(chan *flt)
 | 
						|
	l.rszchan = make(chan int)
 | 
						|
 | 
						|
	go l.doLog()
 | 
						|
	return l
 | 
						|
}
 | 
						|
 | 
						|
func (l *Logger) Resize(sz int) {
 | 
						|
	if sz == 0 {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	l.rszchan <- sz
 | 
						|
}
 | 
						|
 | 
						|
func (l *Logger) Log(data, owner interface{}, itype int) {
 | 
						|
	l.logchan <- &Log{data, owner, itype}
 | 
						|
}
 | 
						|
 | 
						|
func (l *Logger) Filter(owner interface{}, itype int) []*Log {
 | 
						|
	c := make(chan []*Log)
 | 
						|
	l.fltchan <- &flt{owner, itype, c}
 | 
						|
	return <-c
 | 
						|
}
 | 
						|
 | 
						|
func (l *Logger) doLog() {
 | 
						|
	for {
 | 
						|
		select {
 | 
						|
		case it := <-l.logchan:
 | 
						|
			if l.idx >= len(l.items) {
 | 
						|
				l.idx = 0
 | 
						|
			}
 | 
						|
 | 
						|
			l.items[l.idx] = it
 | 
						|
			l.idx++
 | 
						|
 | 
						|
		case sz := <-l.rszchan:
 | 
						|
			it := make([]*Log, sz)
 | 
						|
			for i, j := l.idx, 0; j < len(it); j++ {
 | 
						|
				if i >= len(l.items) {
 | 
						|
					i = 0
 | 
						|
				}
 | 
						|
 | 
						|
				it[j] = l.items[i]
 | 
						|
				i++
 | 
						|
				if i == l.idx {
 | 
						|
					break
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			l.items = it
 | 
						|
			l.idx = 0
 | 
						|
 | 
						|
		case flt := <-l.fltchan:
 | 
						|
			n := 0
 | 
						|
			// we don't care about the order while counting
 | 
						|
			for _, it := range l.items {
 | 
						|
				if it == nil {
 | 
						|
					continue
 | 
						|
				}
 | 
						|
 | 
						|
				if (flt.owner == nil || it.Owner == flt.owner) &&
 | 
						|
					(flt.itype == 0 || it.Type == flt.itype) {
 | 
						|
					n++
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			its := make([]*Log, n)
 | 
						|
			for i, m := l.idx, 0; m < len(its); i++ {
 | 
						|
				if i >= len(l.items) {
 | 
						|
					i = 0
 | 
						|
				}
 | 
						|
 | 
						|
				it := l.items[i]
 | 
						|
				if it != nil && (flt.owner == nil || it.Owner == flt.owner) &&
 | 
						|
					(flt.itype == 0 || it.Type == flt.itype) {
 | 
						|
					its[m] = it
 | 
						|
					m++
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			flt.fltchan <- its
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |