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  }