package main // lazy filled list type listLazy struct { update func(int) []*videoContainer dry bool state int content []*videoContainer par int } // listUpdateChunk concurrently runs the lists update function and // returns a channel, which sends the data when the update is finished. func (l *listLazy) listUpdateChunk(state int) chan []*videoContainer { chn := make(chan []*videoContainer) go func() { chn <- l.update(state) }() return chn } // listNew creates a new lazy list with the given update function and a // parallel update count of 5. func listNew(update func(int) []*videoContainer) *listLazy { return &listLazy{update, false, 0, []*videoContainer{}, 5} } // listPar sets the number of parallel update functions to be executed on each // triggered list update. The count is always >= 1. func (l *listLazy) listPar(count int) { if count < 1 { count = 1 } l.par = count } // listGet returns the element with the given index from the list. If // the list is too short the lists update function will be called until // the requested element is available. If the element could not be acquired // nil is returned. func (l *listLazy) listGet(index int) *videoContainer { for index >= len(l.content) && !l.dry { temp := make([]chan []*videoContainer, l.par) for i, _ := range temp { temp[i] = l.listUpdateChunk(l.state + i) } for _, c := range temp { data := <-c if len(data) == 0 { l.dry = true } l.content = append(l.content, data...) l.state++ } } if index < len(l.content) { return l.content[index] } return nil } // listCached returns all cached entries of the underlying list slice. func (l *listLazy) listCached() []*videoContainer { return l.content } // listSlice tries to return the requested slice from the list. If the // list is too short the lists update function will be called until // the length is sufficient. If the list is too small, a smaller slice // then requested may be returned. func (l *listLazy) listSlice(begin, end int) []*videoContainer { if l.listGet(end) == nil { if l.listGet(begin) == nil { return l.content[0:0] } return l.content[begin:] } return l.content[begin:end] }