summaryrefslogtreecommitdiff
path: root/gcc/testsuite/go.test/test/hashmap.go
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/testsuite/go.test/test/hashmap.go
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'gcc/testsuite/go.test/test/hashmap.go')
-rwxr-xr-xgcc/testsuite/go.test/test/hashmap.go181
1 files changed, 181 insertions, 0 deletions
diff --git a/gcc/testsuite/go.test/test/hashmap.go b/gcc/testsuite/go.test/test/hashmap.go
new file mode 100755
index 000000000..096ece0a5
--- /dev/null
+++ b/gcc/testsuite/go.test/test/hashmap.go
@@ -0,0 +1,181 @@
+// $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"
+}