OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [testsuite/] [go.test/] [test/] [hashmap.go] - Rev 700

Compare with Previous | Blame | View Log

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


type Array [1024]Entry

type HashMap struct {
        map_ *Array
        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(Array)
        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) 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 *Array = 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() {
        // func (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)
        _, _, _ = x1, x2, x3

        // this doesn't work I think...
        //hmap.Lookup(x1, true)
        //hmap.Lookup(x2, true)
        //hmap.Lookup(x3, true)

        //print "done\n"
}

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.