// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package interp

// Custom hashtable atop map.
// For use when the key's equivalence relation is not consistent with ==.

// The Go specification doesn't address the atomicity of map operations.
// The FAQ states that an implementation is permitted to crash on
// concurrent map access.

import (
	"go/types"
)

type hashable interface {
	hash(t types.Type) int
	eq(t types.Type, x interface{}) bool
}

type entry struct {
	key   hashable
	value value
	next  *entry
}

// A hashtable atop the built-in map.  Since each bucket contains
// exactly one hash value, there's no need to perform hash-equality
// tests when walking the linked list.  Rehashing is done by the
// underlying map.
type hashmap struct {
	keyType types.Type
	table   map[int]*entry
	length  int // number of entries in map
}

// makeMap returns an empty initialized map of key type kt,
// preallocating space for reserve elements.
func makeMap(kt types.Type, reserve int) value {
	if usesBuiltinMap(kt) {
		return make(map[value]value, reserve)
	}
	return &hashmap{keyType: kt, table: make(map[int]*entry, reserve)}
}

// delete removes the association for key k, if any.
func (m *hashmap) delete(k hashable) {
	if m != nil {
		hash := k.hash(m.keyType)
		head := m.table[hash]
		if head != nil {
			if k.eq(m.keyType, head.key) {
				m.table[hash] = head.next
				m.length--
				return
			}
			prev := head
			for e := head.next; e != nil; e = e.next {
				if k.eq(m.keyType, e.key) {
					prev.next = e.next
					m.length--
					return
				}
				prev = e
			}
		}
	}
}

// lookup returns the value associated with key k, if present, or
// value(nil) otherwise.
func (m *hashmap) lookup(k hashable) value {
	if m != nil {
		hash := k.hash(m.keyType)
		for e := m.table[hash]; e != nil; e = e.next {
			if k.eq(m.keyType, e.key) {
				return e.value
			}
		}
	}
	return nil
}

// insert updates the map to associate key k with value v.  If there
// was already an association for an eq() (though not necessarily ==)
// k, the previous key remains in the map and its associated value is
// updated.
func (m *hashmap) insert(k hashable, v value) {
	hash := k.hash(m.keyType)
	head := m.table[hash]
	for e := head; e != nil; e = e.next {
		if k.eq(m.keyType, e.key) {
			e.value = v
			return
		}
	}
	m.table[hash] = &entry{
		key:   k,
		value: v,
		next:  head,
	}
	m.length++
}

// len returns the number of key/value associations in the map.
func (m *hashmap) len() int {
	if m != nil {
		return m.length
	}
	return 0
}

// entries returns a rangeable map of entries.
func (m *hashmap) entries() map[int]*entry {
	if m != nil {
		return m.table
	}
	return nil
}
