1//  Copyright (c) 2014 Couchbase, Inc.
2//  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
3//  except in compliance with the License. You may obtain a copy of the License at
4//    http://www.apache.org/licenses/LICENSE-2.0
5//  Unless required by applicable law or agreed to in writing, software distributed under the
6//  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
7//  either express or implied. See the License for the specific language governing permissions
8//  and limitations under the License.
9
10package util
11
12import (
13	"math"
14
15	atomic "github.com/couchbase/go-couchbase/platform"
16)
17
18// Comparisons
19
20func MinInt(x, y int) int {
21	return int(math.Min(float64(x), float64(y)))
22}
23
24func MaxInt(x, y int) int {
25	return int(math.Max(float64(x), float64(y)))
26}
27
28// Rounding
29
30func Round(f float64) float64 {
31	return math.Floor(f + .5)
32}
33
34func RoundPlaces(f float64, places int) float64 {
35	shift := math.Pow(10, float64(places))
36	return Round(f*shift) / shift
37}
38
39type Tristate int
40
41const (
42	FAILURE = Tristate(iota)
43	NOT_DONE
44	DONE
45)
46
47// atomic test and set
48func TestAndSetUint64(loc *atomic.AlignedUint64, val uint64, test func(locVal, val uint64) bool, limit int) Tristate {
49
50	// This works like Power's store with reservation or ARM's conditional store
51	// except that rather than only allowing an equality comparison, we offer an
52	// arbitrary comparison function
53	// This allows to implement various lockless functions such as Min, Max, etc
54	// We also give the option of trying no more than a specific number of times,
55	// and report a completion status, so that alternative actions can be taken on
56	// failure
57	if limit <= 0 {
58		limit = math.MaxInt32
59	}
60	for limit > 0 {
61		limit--
62		oldVal := uint64(*loc)
63		if test(oldVal, val) {
64			if atomic.CompareAndSwapUint64(loc, oldVal, val) {
65				return DONE
66			}
67		} else {
68			return NOT_DONE
69		}
70	}
71	return FAILURE
72}
73