123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- package service
- import (
- "context"
- "fmt"
- "math"
- "strconv"
- "sync"
- "go-common/app/interface/main/dm2/model"
- "go-common/library/ecode"
- "go-common/library/log"
- "go-common/library/sync/errgroup"
- )
- // DM dm list.
- func (s *Service) DM(c context.Context, tp int32, aid, oid int64) (res *model.DMSeg, err error) {
- var (
- total, size int64 = 1, model.DefaultVideoEnd
- mu sync.Mutex
- )
- sub, err := s.subject(c, tp, oid)
- if err != nil {
- return
- }
- res = &model.DMSeg{Elems: make([]*model.Elem, 0, 2*sub.Maxlimit)}
- duration, err := s.videoDuration(c, aid, oid)
- if err != nil {
- return
- }
- if duration != 0 {
- total = int64(math.Ceil(float64(duration) / float64(model.DefaultPageSize)))
- size = model.DefaultPageSize
- }
- g, ctx := errgroup.WithContext(c)
- for i := int64(1); i <= total; i++ {
- num := i
- g.Go(func() (err error) {
- var dmseg *model.DMSeg
- if dmseg, err = s.dao.DMSegCache(ctx, tp, oid, total, num); err != nil {
- return
- }
- if dmseg == nil {
- ps := (num - 1) * size
- pe := num * size
- fmt.Println(ps, pe, total, num)
- if dmseg, err = s.dmSegV2(ctx, sub, total, num, ps, pe); err != nil {
- return
- }
- }
- if dmseg != nil {
- mu.Lock()
- res.Elems = append(res.Elems, dmseg.Elems...)
- mu.Unlock()
- }
- return
- })
- }
- err = g.Wait()
- return
- }
- // DMSegV2 dm segment new.
- func (s *Service) DMSegV2(c context.Context, tp int32, mid, aid, oid, pn int64, plat int32) (res *model.DMSegResp, err error) {
- page, err := s.pageinfo(c, tp, aid, oid, pn)
- if err != nil {
- return
- }
- ps := (page.Num - 1) * page.Size
- pe := page.Num * page.Size
- sub, err := s.subject(c, tp, oid)
- if err != nil {
- return
- }
- res = &model.DMSegResp{
- Flag: model.DefaultFlag,
- }
- if sub.State == model.SubStateClosed {
- return
- }
- flag, err := s.dao.RecFlag(c, mid, aid, oid, 2*sub.Maxlimit, ps, pe, plat)
- if err == nil {
- res.Flag = flag
- }
- dmseg, err := s.dao.DMSegCache(c, tp, oid, page.Total, page.Num)
- if err != nil {
- return
- }
- if dmseg != nil {
- res.Dms = dmseg.Elems
- return
- }
- if dmseg, err = s.dmSegV2(c, sub, page.Total, page.Num, ps, pe); err != nil {
- return
- }
- res.Dms = dmseg.Elems
- s.cache.Do(c, func(ctx context.Context) {
- s.dao.SetDMSegCache(ctx, tp, oid, page.Total, page.Num, dmseg) // add mc cache
- })
- return
- }
- func (s *Service) dmSegV2(c context.Context, sub *model.Subject, total, num, ps, pe int64) (res *model.DMSeg, err error) {
- var (
- cache = true
- limit = 2 * sub.Maxlimit
- dmids = make([]int64, 0, limit)
- )
- res = &model.DMSeg{Elems: make([]*model.Elem, 0, limit)}
- normalIds, err := s.dmNormalIds(c, sub.Type, sub.Oid, total, num, ps, pe, limit)
- if err != nil {
- return
- }
- dmids = append(dmids, normalIds...)
- if sub.Childpool > 0 {
- var subtitleIds []int64
- if subtitleIds, err = s.dmSegSubtitlesIds(c, sub.Type, sub.Oid, ps, pe, limit); err != nil {
- return
- }
- dmids = append(dmids, subtitleIds...)
- }
- if len(dmids) <= 0 {
- return
- }
- elemsCache, missed, err := s.dao.IdxContentCacheV2(c, sub.Type, sub.Oid, dmids)
- if err != nil {
- missed = dmids
- cache = false
- } else {
- res.Elems = append(res.Elems, elemsCache...)
- }
- if len(missed) == 0 {
- return
- }
- dms, err := s.dmsSeg(c, sub.Type, sub.Oid, missed)
- if err != nil {
- return
- }
- for _, dm := range dms {
- if e := dm.ToElem(); e != nil {
- res.Elems = append(res.Elems, e)
- }
- }
- if cache && len(dms) > 0 {
- s.cache.Do(c, func(ctx context.Context) {
- s.dao.AddIdxContentCache(ctx, sub.Type, sub.Oid, dms, false) // add memcache,realname=false
- })
- }
- return
- }
- // pageinfo get page info of oid.
- func (s *Service) pageinfo(c context.Context, tp int32, aid, oid, pn int64) (p *model.Page, err error) {
- var duration int64
- data, ok := s.localCache[keyDuration(tp, oid)]
- if ok {
- duration, err = strconv.ParseInt(string(data), 10, 64)
- } else {
- duration, err = s.videoDuration(c, aid, oid)
- }
- if err != nil {
- return
- }
- if duration == 0 {
- p = &model.Page{
- Num: pn,
- Size: model.DefaultVideoEnd,
- Total: 1,
- }
- } else {
- p = &model.Page{
- Num: pn,
- Size: model.DefaultPageSize,
- Total: int64(math.Ceil(float64(duration) / float64(model.DefaultPageSize))),
- }
- }
- if pn > p.Total {
- log.Warn("oid:%d pn:%d larger than total page:%d", oid, pn, p.Total)
- err = ecode.NotModified
- return
- }
- return
- }
|