github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/milevadb-server/statistics/analyze_jobs.go (about)

     1  // Copyright 2020 WHTCORPS INC, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package statistics
    15  
    16  import (
    17  	"sort"
    18  	"sync"
    19  	"time"
    20  )
    21  
    22  type analyzeJobs struct {
    23  	sync.Mutex
    24  	jobs    map[*AnalyzeJob]struct{}
    25  	history []*AnalyzeJob
    26  }
    27  
    28  var analyzeStatus = analyzeJobs{jobs: make(map[*AnalyzeJob]struct{}), history: make([]*AnalyzeJob, 0, numMaxHistoryJobs)}
    29  
    30  // AnalyzeJob is used to represent the status of one analyze job.
    31  type AnalyzeJob struct {
    32  	sync.Mutex
    33  	DBName        string
    34  	TableName     string
    35  	PartitionName string
    36  	JobInfo       string
    37  	RowCount      int64
    38  	StartTime     time.Time
    39  	State         string
    40  	uFIDelateTime    time.Time
    41  }
    42  
    43  const (
    44  	pending  = "pending"
    45  	running  = "running"
    46  	finished = "finished"
    47  	failed   = "failed"
    48  )
    49  
    50  // AddNewAnalyzeJob adds new analyze job.
    51  func AddNewAnalyzeJob(job *AnalyzeJob) {
    52  	analyzeStatus.Lock()
    53  	job.uFIDelateTime = time.Now()
    54  	job.State = pending
    55  	analyzeStatus.jobs[job] = struct{}{}
    56  	analyzeStatus.Unlock()
    57  }
    58  
    59  const numMaxHistoryJobs = 20
    60  
    61  // MoveToHistory moves the analyze job to history.
    62  func MoveToHistory(job *AnalyzeJob) {
    63  	analyzeStatus.Lock()
    64  	delete(analyzeStatus.jobs, job)
    65  	analyzeStatus.history = append(analyzeStatus.history, job)
    66  	numJobs := len(analyzeStatus.history)
    67  	if numJobs > numMaxHistoryJobs {
    68  		analyzeStatus.history = analyzeStatus.history[numJobs-numMaxHistoryJobs:]
    69  	}
    70  	analyzeStatus.Unlock()
    71  }
    72  
    73  // ClearHistoryJobs clears all history jobs.
    74  func ClearHistoryJobs() {
    75  	analyzeStatus.Lock()
    76  	analyzeStatus.history = analyzeStatus.history[:0]
    77  	analyzeStatus.Unlock()
    78  }
    79  
    80  // GetAllAnalyzeJobs gets all analyze jobs.
    81  func GetAllAnalyzeJobs() []*AnalyzeJob {
    82  	analyzeStatus.Lock()
    83  	jobs := make([]*AnalyzeJob, 0, len(analyzeStatus.jobs)+len(analyzeStatus.history))
    84  	for job := range analyzeStatus.jobs {
    85  		jobs = append(jobs, job)
    86  	}
    87  	jobs = append(jobs, analyzeStatus.history...)
    88  	analyzeStatus.Unlock()
    89  	sort.Slice(jobs, func(i int, j int) bool { return jobs[i].getUFIDelateTime().Before(jobs[j].getUFIDelateTime()) })
    90  	return jobs
    91  }
    92  
    93  // Start marks status of the analyze job as running and uFIDelate the start time.
    94  func (job *AnalyzeJob) Start() {
    95  	job.Mutex.Lock()
    96  	job.State = running
    97  	now := time.Now()
    98  	job.StartTime = now
    99  	job.uFIDelateTime = now
   100  	job.Mutex.Unlock()
   101  }
   102  
   103  // UFIDelate uFIDelates the event count of analyze job.
   104  func (job *AnalyzeJob) UFIDelate(rowCount int64) {
   105  	job.Mutex.Lock()
   106  	job.RowCount += rowCount
   107  	job.uFIDelateTime = time.Now()
   108  	job.Mutex.Unlock()
   109  }
   110  
   111  // Finish uFIDelate the status of analyze job to finished or failed according to `meetError`.
   112  func (job *AnalyzeJob) Finish(meetError bool) {
   113  	job.Mutex.Lock()
   114  	if meetError {
   115  		job.State = failed
   116  	} else {
   117  		job.State = finished
   118  	}
   119  	job.uFIDelateTime = time.Now()
   120  	job.Mutex.Unlock()
   121  }
   122  
   123  func (job *AnalyzeJob) getUFIDelateTime() time.Time {
   124  	job.Mutex.Lock()
   125  	defer job.Mutex.Unlock()
   126  	return job.uFIDelateTime
   127  }