golang hashmap

wallywl / 2023-05-07 / 原文

package main

import (
    "fmt"
)

const HASH_BUCKET_SIZE = 3 //1023

type hash_node struct {
    key  interface{}
    val  interface{}
    next *hash_node
}

//hash bucket to save node address
var hash_bucket [HASH_BUCKET_SIZE]*hash_node

func hash(key interface{}) int {
    hash := 5381
    switch x := key.(type) {
    case string:
        // Time 33 hash
        for _, k := range x {
            hash += (hash << 5) + int(k)
        }

        return (hash % HASH_BUCKET_SIZE)

    case int:

        hash += (hash << 5) + x

        return (hash % HASH_BUCKET_SIZE)
    default:

        _ = x
        return 0
    }
}

//insert new node addr in the head of linklist func hash_insert(node *hash_node) { hash := hash(node.key) head := hash_bucket[hash] node.next = head hash_bucket[hash] = node } func key_cmp(a interface{}, b interface{}) bool { typ := fmt.Sprintf("%T", a) switch x := b.(type) { case string: if typ == "string" { if b == a { return true } } case int: if typ == "int" { if b == a { return true } } default: _ = x return false } return false } func hash_del(item *hash_node) bool { hash := hash(item.key) cur := hash_bucket[hash] if cur == nil { return false } if key_cmp(cur.key, item.key) { hash_bucket[hash] = cur.next return true } for node := cur.next; node != nil; node = node.next { if key_cmp(node.key, item.key) { cur.next = node.next return true } cur = node } return false } func hash_iterate() { for i := 0; i < HASH_BUCKET_SIZE; i++ { fmt.Printf("i %d ----------> \n", i) for node := hash_bucket[i]; node != nil; node = node.next { fmt.Println(node.key, node.val) } } } func hash_get(key interface{}) interface{} { hash := hash(key) for node := hash_bucket[hash]; node != nil; node = node.next { if key_cmp(node.key, key) { return node.val } } return nil } func main() { for i := 0; i < 5; i++ { hash_insert(&hash_node{i, i + 1, nil}) hash_insert(&hash_node{fmt.Sprintf("key%d", i), fmt.Sprintf("val%d", i+1), nil}) } hash_iterate() fmt.Println("---------------after del------------") hash_del(&hash_node{"key4", nil, nil}) hash_del(&hash_node{2, nil, nil}) hash_iterate() fmt.Println(hash_get(4)) }

 output :

i 0 ---------->  

key3 val4

3 4

key0 val1

0 1

i 1 ---------->  

key4 val5

4 5

key1 val2

1 2

i 2 ---------->  

key2 val3

2 3

---------------after del------------

i 0 ---------->  

key3 val4

3 4

key0 val1

0 1

i 1 ---------->  

4 5

key1 val2

1 2

i 2 ---------->  

key2 val3

5