github.com/matrixorigin/matrixone@v0.7.0/pkg/frontend/plan_cache.go (about)

     1  // Copyright 2021 Matrix Origin
     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  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package frontend
    16  
    17  import (
    18  	"container/list"
    19  
    20  	"github.com/matrixorigin/matrixone/pkg/sql/parsers/tree"
    21  	"github.com/matrixorigin/matrixone/pkg/sql/plan"
    22  )
    23  
    24  type cachedPlan struct {
    25  	sql   string
    26  	stmts []tree.Statement
    27  	plans []*plan.Plan
    28  }
    29  
    30  // planCache uses LRU to cache plan for the same sql
    31  type planCache struct {
    32  	capacity  int
    33  	lruList   *list.List
    34  	cachePool map[string]*list.Element
    35  }
    36  
    37  func newPlanCache(capacity int) *planCache {
    38  	return &planCache{
    39  		capacity:  capacity,
    40  		lruList:   list.New(),
    41  		cachePool: make(map[string]*list.Element),
    42  	}
    43  }
    44  
    45  func (pc *planCache) cache(sql string, stmts []tree.Statement, plans []*plan.Plan) {
    46  	element := pc.lruList.PushFront(&cachedPlan{sql: sql, stmts: stmts, plans: plans})
    47  	pc.cachePool[sql] = element
    48  	if pc.lruList.Len() > pc.capacity {
    49  		toRemove := pc.lruList.Back()
    50  		pc.lruList.Remove(toRemove)
    51  		delete(pc.cachePool, toRemove.Value.(*cachedPlan).sql)
    52  	}
    53  }
    54  
    55  // get gets a cached plan by its sql
    56  func (pc *planCache) get(sql string) *cachedPlan {
    57  	if element, ok := pc.cachePool[sql]; ok {
    58  		pc.lruList.MoveToFront(element)
    59  		cp := element.Value.(*cachedPlan)
    60  		return cp
    61  	}
    62  	return nil
    63  }
    64  
    65  func (pc *planCache) isCached(sql string) bool {
    66  	_, isCached := pc.cachePool[sql]
    67  	return isCached
    68  }
    69  
    70  func (pc *planCache) clean() {
    71  	pc.lruList = list.New()
    72  	pc.cachePool = make(map[string]*list.Element)
    73  }