github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/simulator/mcp/uk.go (about) 1 // Copyright 2022 PingCAP, 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 mcp 15 16 import ( 17 "fmt" 18 "sort" 19 "strings" 20 "sync" 21 ) 22 23 // UniqueKey is the data structure describing a unique key. 24 type UniqueKey struct { 25 // It inherits a RWMutex, which is used to modify the metadata inside the UK struct. 26 sync.RWMutex 27 // rowID is an integer describing the row ID of the unique key. 28 // The row ID is a virtual concept, not the real row ID for a DB table. 29 // Usually it is used to locate the index in an MCP. 30 rowID int 31 // value is the real value of all the UK columns. 32 // The key is the column name, the value is the real value. 33 value map[string]interface{} 34 } 35 36 // NewUniqueKey creates a new unique key instance. 37 // the map values are cloned into the new UK instance, 38 // so that the further changes in the value map won't affect the values inside the UK. 39 func NewUniqueKey(rowID int, value map[string]interface{}) *UniqueKey { 40 result := &UniqueKey{ 41 rowID: rowID, 42 value: make(map[string]interface{}), 43 } 44 for k, v := range value { 45 result.value[k] = v 46 } 47 return result 48 } 49 50 // GetRowID gets the row ID of the unique key. 51 // The row ID is a virtual concept, not the real row ID for a DB table. 52 // Usually it is used to locate the index in an MCP. 53 func (uk *UniqueKey) GetRowID() int { 54 uk.RLock() 55 defer uk.RUnlock() 56 return uk.rowID 57 } 58 59 // SetRowID sets the row ID of the unique key. 60 func (uk *UniqueKey) SetRowID(rowID int) { 61 uk.Lock() 62 defer uk.Unlock() 63 uk.rowID = rowID 64 } 65 66 // GetValue gets the UK value map of a unique key. 67 // The returned value is cloned, so that further modifications won't affect the value inside the UK. 68 func (uk *UniqueKey) GetValue() map[string]interface{} { 69 uk.RLock() 70 defer uk.RUnlock() 71 result := make(map[string]interface{}) 72 for k, v := range uk.value { 73 result[k] = v 74 } 75 return result 76 } 77 78 // GetValueHash return hash for values. 79 func (uk *UniqueKey) GetValueHash() string { 80 uk.RLock() 81 defer uk.RUnlock() 82 83 keys := make([]string, 0) 84 for k := range uk.value { 85 keys = append(keys, k) 86 } 87 sort.Strings(keys) 88 var b strings.Builder 89 for _, k := range keys { 90 v := uk.value[k] 91 fmt.Fprintf(&b, "%s = %v; ", k, v) 92 } 93 return b.String() 94 } 95 96 // SetValue sets the UK value map. 97 // The input values are cloned into the UK, 98 // and further modifications on the input map won't affect the values inside the UK. 99 func (uk *UniqueKey) SetValue(value map[string]interface{}) { 100 uk.Lock() 101 defer uk.Unlock() 102 uk.value = make(map[string]interface{}) 103 for k, v := range value { 104 uk.value[k] = v 105 } 106 } 107 108 // Clone is to clone a UK into a new one. 109 // So that two UK objects are not interfered with each other. 110 func (uk *UniqueKey) Clone() *UniqueKey { 111 uk.RLock() 112 defer uk.RUnlock() 113 result := &UniqueKey{ 114 rowID: uk.rowID, 115 value: map[string]interface{}{}, 116 } 117 for k, v := range uk.value { 118 result.value[k] = v 119 } 120 return result 121 } 122 123 // String returns the string representation of a UK. 124 func (uk *UniqueKey) String() string { 125 uk.RLock() 126 defer uk.RUnlock() 127 var b strings.Builder 128 fmt.Fprintf(&b, "%p: { RowID: %d, ", uk, uk.rowID) 129 fmt.Fprintf(&b, "Keys: ( ") 130 for k, v := range uk.value { 131 fmt.Fprintf(&b, "%s = %v; ", k, v) 132 } 133 fmt.Fprintf(&b, ") }") 134 return b.String() 135 } 136 137 // IsValueEqual tests whether two UK's value parts are equal. 138 func (uk *UniqueKey) IsValueEqual(otherUK *UniqueKey) bool { 139 if uk == nil || otherUK == nil { 140 return false 141 } 142 uk.RLock() 143 defer uk.RUnlock() 144 otherUK.RLock() 145 defer otherUK.RUnlock() 146 if len(uk.value) != len(otherUK.value) { 147 return false 148 } 149 for k, v := range uk.value { 150 otherV, ok := otherUK.value[k] 151 if !ok { 152 return false 153 } 154 if v != otherV { 155 return false 156 } 157 } 158 return true 159 }