github.com/matrixorigin/matrixone@v1.2.0/pkg/gossip/base_item.go (about)

     1  // Copyright 2021 - 2024 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 gossip
    16  
    17  import (
    18  	"sync"
    19  
    20  	"github.com/matrixorigin/matrixone/pkg/pb/gossip"
    21  )
    22  
    23  const (
    24  	defaultQueueSize = 100
    25  	maxItemCount     = 8192 * 2000
    26  )
    27  
    28  type BaseStore[K comparable] struct {
    29  	// cacheServerAddr is the service address of cache server. The items
    30  	// with it are added to the queue, and then the items are sent to other
    31  	// nodes. Then other nodes will try to send RPC request with this address
    32  	// to this node to get item info.
    33  	cacheServerAddr string
    34  
    35  	queueMu struct {
    36  		sync.Mutex
    37  		// When local service updates item, it pushes item to this queue.
    38  		// And gossip worker takes items from the queue and send to other nodes.
    39  		itemQueue []gossip.CommonItem
    40  	}
    41  
    42  	mu struct {
    43  		sync.Mutex
    44  		// keyTarget is the map that local service searches remote keys
    45  		// when the item does not exist in local service.
    46  		keyTarget map[K]string // key => cn address
    47  	}
    48  }
    49  
    50  func newBaseStore[K comparable](addr string) *BaseStore[K] {
    51  	s := &BaseStore[K]{
    52  		cacheServerAddr: addr,
    53  	}
    54  	s.mu.keyTarget = make(map[K]string)
    55  	s.queueMu.itemQueue = make([]gossip.CommonItem, 0, defaultQueueSize)
    56  	return s
    57  }
    58  
    59  // Target implements the client.KeyRouter interface.
    60  func (s *BaseStore[K]) Target(k K) string {
    61  	s.mu.Lock()
    62  	defer s.mu.Unlock()
    63  	if target, ok := s.mu.keyTarget[k]; ok && target != s.cacheServerAddr {
    64  		return target
    65  	}
    66  	return ""
    67  }
    68  
    69  // AddItem implements the client.KeyRouter interface.
    70  func (s *BaseStore[K]) AddItem(item gossip.CommonItem) {
    71  	if s.cacheServerAddr == "" {
    72  		return
    73  	}
    74  	s.queueMu.Lock()
    75  	defer s.queueMu.Unlock()
    76  	if len(s.queueMu.itemQueue) >= maxItemCount {
    77  		return
    78  	}
    79  	item.TargetAddress = s.cacheServerAddr
    80  	s.queueMu.itemQueue = append(s.queueMu.itemQueue, item)
    81  }
    82  
    83  // Data implements the Module interface.
    84  func (s *BaseStore[K]) Data(limit int) ([]gossip.CommonItem, int) {
    85  	var items []gossip.CommonItem
    86  	s.queueMu.Lock()
    87  	count := len(s.queueMu.itemQueue)
    88  	if count == 0 {
    89  		s.queueMu.Unlock()
    90  		return nil, limit
    91  	}
    92  	sz := s.queueMu.itemQueue[0].Size()
    93  	limitCount := limit / sz
    94  	var leftSize int
    95  	if count < limitCount {
    96  		items = s.queueMu.itemQueue
    97  		s.queueMu.itemQueue = make([]gossip.CommonItem, 0, defaultQueueSize)
    98  		leftSize = limit - count*sz
    99  		s.queueMu.Unlock()
   100  	} else {
   101  		items = s.queueMu.itemQueue[:limitCount]
   102  		s.queueMu.itemQueue = s.queueMu.itemQueue[limitCount:]
   103  		s.queueMu.Unlock()
   104  	}
   105  	return items, leftSize
   106  }
   107  
   108  func (s *BaseStore[K]) update(target string, ks []K) {
   109  	s.mu.Lock()
   110  	defer s.mu.Unlock()
   111  	for _, k := range ks {
   112  		s.mu.keyTarget[k] = target
   113  	}
   114  }