github.com/Azareal/Gosora@v0.0.0-20210729070923-553e66b59003/common/counters/langs.go (about)

     1  package counters
     2  
     3  import (
     4  	"database/sql"
     5  	"sync/atomic"
     6  
     7  	c "github.com/Azareal/Gosora/common"
     8  	qgen "github.com/Azareal/Gosora/query_gen"
     9  	"github.com/pkg/errors"
    10  )
    11  
    12  var LangViewCounter *DefaultLangViewCounter
    13  
    14  var langCodes = []string{
    15  	"unknown",
    16  	"",
    17  	"af",
    18  	"ar",
    19  	"az",
    20  	"be",
    21  	"bg",
    22  	"bs",
    23  	"ca",
    24  	"cs",
    25  	"cy",
    26  	"da",
    27  	"de",
    28  	"dv",
    29  	"el",
    30  	"en",
    31  	"eo",
    32  	"es",
    33  	"et",
    34  	"eu",
    35  	"fa",
    36  	"fi",
    37  	"fo",
    38  	"fr",
    39  	"gl",
    40  	"gu",
    41  	"he",
    42  	"hi",
    43  	"hr",
    44  	"hu",
    45  	"hy",
    46  	"id",
    47  	"is",
    48  	"it",
    49  	"ja",
    50  	"ka",
    51  	"kk",
    52  	"kn",
    53  	"ko",
    54  	"kok",
    55  	"kw",
    56  	"ky",
    57  	"lt",
    58  	"lv",
    59  	"mi",
    60  	"mk",
    61  	"mn",
    62  	"mr",
    63  	"ms",
    64  	"mt",
    65  	"nb",
    66  	"nl",
    67  	"nn",
    68  	"ns",
    69  	"pa",
    70  	"pl",
    71  	"ps",
    72  	"pt",
    73  	"qu",
    74  	"ro",
    75  	"ru",
    76  	"sa",
    77  	"se",
    78  	"sk",
    79  	"sl",
    80  	"sq",
    81  	"sr",
    82  	"sv",
    83  	"sw",
    84  	"syr",
    85  	"ta",
    86  	"te",
    87  	"th",
    88  	"tl",
    89  	"tn",
    90  	"tr",
    91  	"tt",
    92  	"ts",
    93  	"uk",
    94  	"ur",
    95  	"uz",
    96  	"vi",
    97  	"xh",
    98  	"zh",
    99  	"zu",
   100  }
   101  
   102  type DefaultLangViewCounter struct {
   103  	//buckets        []*MutexCounterBucket //[OSID]count
   104  	buckets        []int64 //[OSID]count
   105  	codesToIndices map[string]int
   106  
   107  	insert *sql.Stmt
   108  }
   109  
   110  func NewDefaultLangViewCounter(acc *qgen.Accumulator) (*DefaultLangViewCounter, error) {
   111  	codesToIndices := make(map[string]int, len(langCodes))
   112  	for index, code := range langCodes {
   113  		codesToIndices[code] = index
   114  	}
   115  	co := &DefaultLangViewCounter{
   116  		buckets:        make([]int64, len(langCodes)),
   117  		codesToIndices: codesToIndices,
   118  		insert:         acc.Insert("viewchunks_langs").Columns("count,createdAt,lang").Fields("?,UTC_TIMESTAMP(),?").Prepare(),
   119  	}
   120  
   121  	c.Tasks.FifteenMin.Add(co.Tick)
   122  	//c.Tasks.Sec.Add(co.Tick)
   123  	c.Tasks.Shutdown.Add(co.Tick)
   124  	return co, acc.FirstError()
   125  }
   126  
   127  func (co *DefaultLangViewCounter) Tick() error {
   128  	for id := 0; id < len(co.buckets); id++ {
   129  		count := atomic.SwapInt64(&co.buckets[id], 0)
   130  		e := co.insertChunk(count, id) // TODO: Bulk insert for speed?
   131  		if e != nil {
   132  			return errors.Wrap(errors.WithStack(e), "langview counter")
   133  		}
   134  	}
   135  	return nil
   136  }
   137  
   138  func (co *DefaultLangViewCounter) insertChunk(count int64, id int) error {
   139  	if count == 0 {
   140  		return nil
   141  	}
   142  	langCode := langCodes[id]
   143  	if langCode == "" {
   144  		langCode = "none"
   145  	}
   146  	c.DebugLogf("Inserting a vchunk with a count of %d for lang %s (%d)", count, langCode, id)
   147  	_, e := co.insert.Exec(count, langCode)
   148  	return e
   149  }
   150  
   151  func (co *DefaultLangViewCounter) Bump(langCode string) (validCode bool) {
   152  	validCode = true
   153  	id, ok := co.codesToIndices[langCode]
   154  	if !ok {
   155  		// TODO: Tell the caller that the code's invalid
   156  		id = 0 // Unknown
   157  		validCode = false
   158  	}
   159  
   160  	// TODO: Test this check
   161  	c.DebugDetail("buckets ", id, ": ", co.buckets[id])
   162  	if len(co.buckets) <= id || id < 0 {
   163  		return validCode
   164  	}
   165  	atomic.AddInt64(&co.buckets[id], 1)
   166  
   167  	return validCode
   168  }
   169  
   170  func (co *DefaultLangViewCounter) Bump2(id int) {
   171  	// TODO: Test this check
   172  	c.DebugDetail("bucket ", id, ": ", co.buckets[id])
   173  	if len(co.buckets) <= id || id < 0 {
   174  		return
   175  	}
   176  	atomic.AddInt64(&co.buckets[id], 1)
   177  }