github.com/matrixorigin/matrixone@v1.2.0/pkg/pb/lock/lock.go (about)

     1  // Copyright 2023 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 lock
    16  
    17  import (
    18  	"bytes"
    19  	"context"
    20  	"encoding/hex"
    21  	"fmt"
    22  
    23  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    24  )
    25  
    26  // SetID implement morpc Messgae
    27  func (m *Request) SetID(id uint64) {
    28  	m.RequestID = id
    29  }
    30  
    31  // GetID implement morpc Messgae
    32  func (m *Request) GetID() uint64 {
    33  	return m.RequestID
    34  }
    35  
    36  // DebugString returns the debug string
    37  func (m *Request) DebugString() string {
    38  	var buffer bytes.Buffer
    39  	buffer.WriteString(fmt.Sprintf("%d: ", m.RequestID))
    40  	buffer.WriteString(m.Method.String())
    41  	buffer.WriteString("/")
    42  	if m.LockTable.Table > 0 {
    43  		buffer.WriteString(m.LockTable.DebugString())
    44  		buffer.WriteString("/")
    45  	}
    46  	switch m.Method {
    47  	case Method_Lock:
    48  		buffer.WriteString(m.Lock.DebugString())
    49  	case Method_Unlock:
    50  		buffer.WriteString(m.Unlock.DebugString())
    51  	case Method_GetBind:
    52  		buffer.WriteString(m.GetBind.DebugString())
    53  	case Method_GetTxnLock:
    54  		buffer.WriteString(m.GetTxnLock.DebugString())
    55  	case Method_GetWaitingList:
    56  		buffer.WriteString(m.GetWaitingList.DebugString())
    57  	case Method_KeepLockTableBind:
    58  		buffer.WriteString(m.KeepLockTableBind.DebugString())
    59  	case Method_KeepRemoteLock:
    60  		buffer.WriteString(m.KeepRemoteLock.DebugString())
    61  	}
    62  	return buffer.String()
    63  }
    64  
    65  // SetID implement morpc Messgae
    66  func (m *Response) SetID(id uint64) {
    67  	m.RequestID = id
    68  }
    69  
    70  // GetID implement morpc Messgae
    71  func (m *Response) GetID() uint64 {
    72  	return m.RequestID
    73  }
    74  
    75  // DebugString returns the debug string
    76  func (m *Response) DebugString() string {
    77  	var buffer bytes.Buffer
    78  	buffer.WriteString(fmt.Sprintf("%d: ", m.RequestID))
    79  	buffer.WriteString(m.Method.String())
    80  	buffer.WriteString("/")
    81  	switch m.Method {
    82  	case Method_Lock:
    83  		buffer.WriteString(m.Lock.DebugString())
    84  	case Method_Unlock:
    85  		buffer.WriteString(m.Unlock.DebugString())
    86  	case Method_GetBind:
    87  		buffer.WriteString(m.GetBind.DebugString())
    88  	case Method_GetTxnLock:
    89  		buffer.WriteString(m.GetTxnLock.DebugString())
    90  	case Method_GetWaitingList:
    91  		buffer.WriteString(m.GetWaitingList.DebugString())
    92  	case Method_KeepLockTableBind:
    93  		buffer.WriteString(m.KeepLockTableBind.DebugString())
    94  	case Method_KeepRemoteLock:
    95  		buffer.WriteString(m.KeepRemoteLock.DebugString())
    96  	}
    97  	return buffer.String()
    98  }
    99  
   100  // Changed returns true if LockTable bind changed
   101  func (m LockTable) Changed(v LockTable) bool {
   102  	return m.Version != v.Version ||
   103  		m.ServiceID != v.ServiceID
   104  }
   105  
   106  // Equal return true means same bind
   107  func (m LockTable) Equal(v LockTable) bool {
   108  	return m.Table == v.Table && m.Version == v.Version
   109  }
   110  
   111  // DebugString returns the debug string
   112  func (m LockTable) DebugString() string {
   113  	return fmt.Sprintf("%d-%s-%d", m.Table, m.ServiceID, m.Version)
   114  }
   115  
   116  // WithGranularity set rows granularity, the default granularity is Row.
   117  func (m LockOptions) WithGranularity(granularity Granularity) LockOptions {
   118  	m.Granularity = granularity
   119  	return m
   120  }
   121  
   122  // WithMode set lock mode, the default mode is Exclusive.
   123  func (m LockOptions) WithMode(mode LockMode) LockOptions {
   124  	m.Mode = mode
   125  	return m
   126  }
   127  
   128  // WithWaitPolicy set wait policy, the default policy is Wait.
   129  func (m LockOptions) WithWaitPolicy(policy WaitPolicy) LockOptions {
   130  	m.Policy = policy
   131  	return m
   132  }
   133  
   134  // WrapError wrapper error to TxnError
   135  func (m *Response) WrapError(err error) {
   136  	me := moerr.ConvertGoError(context.TODO(), err).(*moerr.Error)
   137  	data, e := me.MarshalBinary()
   138  	if e != nil {
   139  		panic(e)
   140  	}
   141  	m.Error = data
   142  }
   143  
   144  // UnwrapError unwrap the moerr from the error bytes
   145  func (m Response) UnwrapError() error {
   146  	if len(m.Error) == 0 {
   147  		return nil
   148  	}
   149  
   150  	err := &moerr.Error{}
   151  	if e := err.UnmarshalBinary(m.Error); e != nil {
   152  		panic(e)
   153  	}
   154  	return err
   155  }
   156  
   157  // DebugString debug string
   158  func (m LockOptions) DebugString() string {
   159  	return fmt.Sprintf("%s-%s-%s",
   160  		m.Mode.String(),
   161  		m.Granularity.String(),
   162  		m.Policy.String())
   163  }
   164  
   165  func (m *LockRequest) DebugString() string {
   166  	return fmt.Sprintf("%s-%s-%s-%s",
   167  		hex.EncodeToString(m.TxnID),
   168  		m.ServiceID,
   169  		bytesArrayString(m.Rows),
   170  		m.Options.DebugString())
   171  }
   172  
   173  func (m *LockResponse) DebugString() string {
   174  	return ""
   175  }
   176  
   177  func (m *UnlockRequest) DebugString() string {
   178  	return hex.EncodeToString(m.TxnID)
   179  }
   180  
   181  func (m *UnlockResponse) DebugString() string {
   182  	return ""
   183  }
   184  
   185  func (m *GetBindRequest) DebugString() string {
   186  	return fmt.Sprintf("%s-%d", m.ServiceID, m.Table)
   187  }
   188  
   189  func (m *GetBindResponse) DebugString() string {
   190  	return m.LockTable.DebugString()
   191  }
   192  
   193  func (m *GetTxnLockRequest) DebugString() string {
   194  	return fmt.Sprintf("%s-%s",
   195  		hex.EncodeToString(m.TxnID),
   196  		hex.EncodeToString(m.Row))
   197  }
   198  
   199  func (m *GetTxnLockResponse) DebugString() string {
   200  	return fmt.Sprintf("%d-%s",
   201  		m.Value,
   202  		waitTxnArrayString(m.WaitingList))
   203  }
   204  
   205  func (m *GetWaitingListRequest) DebugString() string {
   206  	return m.Txn.DebugString()
   207  }
   208  
   209  func (m *GetWaitingListResponse) DebugString() string {
   210  	return waitTxnArrayString(m.WaitingList)
   211  }
   212  
   213  func (m *KeepLockTableBindRequest) DebugString() string {
   214  	return m.ServiceID
   215  }
   216  
   217  func (m *KeepLockTableBindResponse) DebugString() string {
   218  	if m.OK {
   219  		return "true"
   220  	}
   221  	return "false"
   222  }
   223  
   224  func (m *KeepRemoteLockRequest) DebugString() string {
   225  	return m.ServiceID
   226  }
   227  
   228  func (m *KeepRemoteLockResponse) DebugString() string {
   229  	if m.OK {
   230  		return "true"
   231  	}
   232  	return "false"
   233  }
   234  
   235  func bytesArrayString(values [][]byte) string {
   236  	var buffer bytes.Buffer
   237  	for idx, v := range values {
   238  		buffer.WriteString(hex.EncodeToString(v))
   239  		if idx != len(values)-1 {
   240  			buffer.WriteString(",")
   241  		}
   242  	}
   243  	return buffer.String()
   244  }
   245  
   246  func waitTxnArrayString(values []WaitTxn) string {
   247  	var buffer bytes.Buffer
   248  	for idx, v := range values {
   249  		buffer.WriteString(v.String())
   250  		if idx != len(values)-1 {
   251  			buffer.WriteString(",")
   252  		}
   253  	}
   254  	return buffer.String()
   255  }
   256  
   257  func (m *WaitTxn) DebugString() string {
   258  	return fmt.Sprintf("%s(%s)",
   259  		hex.EncodeToString(m.TxnID),
   260  		m.CreatedOn)
   261  }
   262  
   263  func (m Request) TypeName() string {
   264  	return "lockservice.request"
   265  }
   266  
   267  func (m Response) TypeName() string {
   268  	return "lockservice.response"
   269  }
   270  
   271  func (m LockOptions) Validate(rows [][]byte) {
   272  	if m.Sharding == Sharding_None {
   273  		return
   274  	}
   275  
   276  	if m.Granularity != Granularity_Row {
   277  		panic("cannot lock with sharding without row granularity")
   278  	}
   279  
   280  	if len(rows) != 1 {
   281  		panic("cannot lock with sharding without single row")
   282  	}
   283  }