github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/gossip/util/misc.go (about) 1 /* 2 Copyright IBM Corp. 2016 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package util 18 19 import ( 20 "fmt" 21 "math/rand" 22 "reflect" 23 "runtime" 24 "sync" 25 "time" 26 27 "github.com/spf13/viper" 28 ) 29 30 // Equals returns whether a and b are the same 31 type Equals func(a interface{}, b interface{}) bool 32 33 func init() { 34 rand.Seed(42) 35 } 36 37 // IndexInSlice returns the index of given object o in array 38 func IndexInSlice(array interface{}, o interface{}, equals Equals) int { 39 arr := reflect.ValueOf(array) 40 for i := 0; i < arr.Len(); i++ { 41 if equals(arr.Index(i).Interface(), o) { 42 return i 43 } 44 } 45 return -1 46 } 47 48 func numbericEqual(a interface{}, b interface{}) bool { 49 return a.(int) == b.(int) 50 } 51 52 // GetRandomIndices returns a slice of random indices 53 // from 0 to given highestIndex 54 func GetRandomIndices(indiceCount, highestIndex int) []int { 55 if highestIndex+1 < indiceCount { 56 return nil 57 } 58 59 indices := make([]int, 0) 60 if highestIndex+1 == indiceCount { 61 for i := 0; i < indiceCount; i++ { 62 indices = append(indices, i) 63 } 64 return indices 65 } 66 67 for len(indices) < indiceCount { 68 n := rand.Intn(highestIndex + 1) 69 if IndexInSlice(indices, n, numbericEqual) != -1 { 70 continue 71 } 72 indices = append(indices, n) 73 } 74 return indices 75 } 76 77 // Set is a generic and thread-safe 78 // set container 79 type Set struct { 80 items map[interface{}]struct{} 81 lock *sync.RWMutex 82 } 83 84 // NewSet returns a new set 85 func NewSet() *Set { 86 return &Set{lock: &sync.RWMutex{}, items: make(map[interface{}]struct{})} 87 } 88 89 // Add adds given item to the set 90 func (s *Set) Add(item interface{}) { 91 s.lock.Lock() 92 defer s.lock.Unlock() 93 s.items[item] = struct{}{} 94 } 95 96 // Exists returns true whether given item is in the set 97 func (s *Set) Exists(item interface{}) bool { 98 s.lock.RLock() 99 defer s.lock.RUnlock() 100 _, exists := s.items[item] 101 return exists 102 } 103 104 // ToArray returns a slice with items 105 // at the point in time the method was invoked 106 func (s *Set) ToArray() []interface{} { 107 s.lock.RLock() 108 defer s.lock.RUnlock() 109 a := make([]interface{}, len(s.items)) 110 i := 0 111 for item := range s.items { 112 a[i] = item 113 i++ 114 } 115 return a 116 } 117 118 // Clear removes all elements from set 119 func (s *Set) Clear() { 120 s.lock.Lock() 121 defer s.lock.Unlock() 122 s.items = make(map[interface{}]struct{}) 123 } 124 125 // Remove removes a given item from the set 126 func (s *Set) Remove(item interface{}) { 127 s.lock.Lock() 128 defer s.lock.Unlock() 129 delete(s.items, item) 130 } 131 132 type goroutine struct { 133 id int64 134 Stack []string 135 } 136 137 // PrintStackTrace prints to stdout 138 // all goroutines 139 func PrintStackTrace() { 140 buf := make([]byte, 1<<16) 141 runtime.Stack(buf, true) 142 fmt.Printf("%s", buf) 143 } 144 145 // GetIntOrDefault returns the int value from config if present otherwise default value 146 func GetIntOrDefault(key string, defVal int) int { 147 if val := viper.GetInt(key); val != 0 { 148 return val 149 } 150 151 return defVal 152 } 153 154 // GetIntOrDefault returns the Duration value from config if present otherwise default value 155 func GetDurationOrDefault(key string, defVal time.Duration) time.Duration { 156 if val := viper.GetDuration(key); val != 0 { 157 return val 158 } 159 160 return defVal 161 }