// $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.

// To compile: go hashmap.go && gcc -o g.out main.go.c gort0.c && g.out

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";
}
