// $G $F.go && $L $F.$A && ./$A.out

// Copyright 2009 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 main

// ----------------------------------------------------------------------------
// Helper functions

func ASSERT(p bool) {
  if !p {
    // panic 0;
  }
}


// ----------------------------------------------------------------------------
// Implementation of the HashMap

type KeyType interface {
  Hash() uint32;
  Match(other *KeyType) bool
}


type ValueType interface {
  // empty interface
}


type Entry struct {
  key *KeyType;
  value *ValueType;
}


// Using the Array type below doesn't seem to work
//type Array array [1024] Entry;

type HashMap struct {
  map_ *[1024] Entry;
  log2_capacity_ uint32;
  occupancy_ uint32;
}


func (m *HashMap) capacity() uint32 {
  return 1 << m.log2_capacity_;
}


func (m *HashMap) Clear() {
  // Mark all entries as empty.
  var i uint32 = m.capacity() - 1;
  for i > 0 {
    m.map_[i].key = nil;
    i = i - 1
  }
  m.occupancy_ = 0
}


func (m *HashMap) Initialize (initial_log2_capacity uint32) {
  m.log2_capacity_ = initial_log2_capacity;
  m.map_ = new([1024] Entry);
  m.Clear();
}


func (m *HashMap) Probe (key *KeyType) *Entry {
  ASSERT(key != nil);

  var i uint32 = key.Hash() % m.capacity();
  ASSERT(0 <= i && i < m.capacity());
  
  ASSERT(m.occupancy_ < m.capacity());  // guarantees loop termination
  for m.map_[i].key != nil && !m.map_[i].key.Match(key) {
    i++;
    if i >= m.capacity() {
      i = 0;
    }
  }
  
  return &m.map_[i];
}


func (m *HashMap) Resize();


func (m *HashMap) Lookup (key *KeyType, insert bool) *Entry {
  // Find a matching entry.
  var p *Entry = m.Probe(key);
    if p.key != nil {
    return p;
  }

  // No entry found; insert one if necessary.
  if insert {
    p.key = key;
    p.value = nil;
    m.occupancy_++;
  
    // Grow the map if we reached >= 80% occupancy.
    if m.occupancy_ + m.occupancy_/4 >= m.capacity() {
      m.Resize();
      p = m.Probe(key);
    }
    
    return p;
  }

  // No entry found and none inserted.
  return nil;
}


func (m *HashMap) Resize() {
  var hmap *[1024] Entry = m.map_;
  var n uint32 = m.occupancy_;
  
  // Allocate a new map of twice the current size.
  m.Initialize(m.log2_capacity_ << 1);
  
  // Rehash all current entries.
  var i uint32 = 0;
  for n > 0 {
    if hmap[i].key != nil {
      m.Lookup(hmap[i].key, true).value = hmap[i].value;
      n = n - 1;
    }
    i++;
  }
}


// ----------------------------------------------------------------------------
// Test code

type Number struct {
  x uint32;
}


func (n *Number) Hash() uint32 {
  return n.x * 23;
}


func (n *Number) Match(other *KeyType) bool {
  // var y *Number = other;
  // return n.x == y.x;
  return false;
}


func MakeNumber (x uint32) *Number {
  var n *Number = new(Number);
  n.x = x;
  return n;
}


func main() {
  //f unc (n int) int { return n + 1; }(1);

  //print "HashMap - gri 2/8/2008\n";
  
  var hmap *HashMap = new(HashMap);
  hmap.Initialize(0);
  
  var x1 *Number = MakeNumber(1001);
  var x2 *Number = MakeNumber(2002);
  var x3 *Number = MakeNumber(3003);
  
  // this doesn't work I think...
  //hmap.Lookup(x1, true);
  //hmap.Lookup(x2, true);
  //hmap.Lookup(x3, true);
  
  //print "done\n";
}
