/*
 *
 * Copyright 2019 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package primitives_test

import (
	"sync"
	"sync/atomic"
	"testing"
)

type incrementUint64Map interface {
	increment(string)
	result(string) uint64
}

type mapWithLock struct {
	mu sync.Mutex
	m  map[string]uint64
}

func newMapWithLock() incrementUint64Map {
	return &mapWithLock{
		m: make(map[string]uint64),
	}
}

func (mwl *mapWithLock) increment(c string) {
	mwl.mu.Lock()
	mwl.m[c]++
	mwl.mu.Unlock()
}

func (mwl *mapWithLock) result(c string) uint64 {
	return mwl.m[c]
}

type mapWithAtomicFastpath struct {
	mu sync.RWMutex
	m  map[string]*uint64
}

func newMapWithAtomicFastpath() incrementUint64Map {
	return &mapWithAtomicFastpath{
		m: make(map[string]*uint64),
	}
}

func (mwaf *mapWithAtomicFastpath) increment(c string) {
	mwaf.mu.RLock()
	if p, ok := mwaf.m[c]; ok {
		atomic.AddUint64(p, 1)
		mwaf.mu.RUnlock()
		return
	}
	mwaf.mu.RUnlock()

	mwaf.mu.Lock()
	if p, ok := mwaf.m[c]; ok {
		atomic.AddUint64(p, 1)
		mwaf.mu.Unlock()
		return
	}
	var temp uint64 = 1
	mwaf.m[c] = &temp
	mwaf.mu.Unlock()
}

func (mwaf *mapWithAtomicFastpath) result(c string) uint64 {
	return atomic.LoadUint64(mwaf.m[c])
}

type mapWithSyncMap struct {
	m sync.Map
}

func newMapWithSyncMap() incrementUint64Map {
	return &mapWithSyncMap{}
}

func (mwsm *mapWithSyncMap) increment(c string) {
	p, ok := mwsm.m.Load(c)
	if !ok {
		tp := new(uint64)
		p, _ = mwsm.m.LoadOrStore(c, tp)
	}
	atomic.AddUint64(p.(*uint64), 1)
}

func (mwsm *mapWithSyncMap) result(c string) uint64 {
	p, _ := mwsm.m.Load(c)
	return atomic.LoadUint64(p.(*uint64))
}

func benchmarkIncrementUint64Map(b *testing.B, f func() incrementUint64Map) {
	const cat = "cat"
	benches := []struct {
		name           string
		goroutineCount int
	}{
		{
			name:           "   1",
			goroutineCount: 1,
		},
		{
			name:           "  10",
			goroutineCount: 10,
		},
		{
			name:           " 100",
			goroutineCount: 100,
		},
		{
			name:           "1000",
			goroutineCount: 1000,
		},
	}
	for _, bb := range benches {
		b.Run(bb.name, func(b *testing.B) {
			m := f()
			var wg sync.WaitGroup
			wg.Add(bb.goroutineCount)
			b.ResetTimer()
			for i := 0; i < bb.goroutineCount; i++ {
				go func() {
					for j := 0; j < b.N; j++ {
						m.increment(cat)
					}
					wg.Done()
				}()
			}
			wg.Wait()
			b.StopTimer()
			if m.result(cat) != uint64(bb.goroutineCount*b.N) {
				b.Fatalf("result is %d, want %d", m.result(cat), b.N)
			}
		})
	}
}

func BenchmarkMapWithSyncMutexContetion(b *testing.B) {
	benchmarkIncrementUint64Map(b, newMapWithLock)
}

func BenchmarkMapWithAtomicFastpath(b *testing.B) {
	benchmarkIncrementUint64Map(b, newMapWithAtomicFastpath)
}

func BenchmarkMapWithSyncMap(b *testing.B) {
	benchmarkIncrementUint64Map(b, newMapWithSyncMap)
}
