Created
March 6, 2015 09:45
-
-
Save samrat/6026030158dd0d426a46 to your computer and use it in GitHub Desktop.
Quick n' dirty hashtable implementation in Racket
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#lang racket | |
;; USAGE: | |
;; ===== | |
;; (init-hashtable 100) | |
;; (insert ht 13 3) | |
;; (lookup ht 13) | |
;; (delete ht 13) | |
;; list of random integers in [0, num-buckets); used for hashing | |
(define global-rs '()) | |
(define global-num-buckets 0) | |
(define (rand-stream n) | |
(cons (random n) (lambda () (rand-stream n)))) | |
(define (stream-take s n) | |
(if (> n 0) | |
(cons (car s) (stream-take ((cdr s)) (- n 1))) | |
'())) | |
(define (hash num) | |
(define (compute-hash-sum n rs) | |
(if (> n 0) | |
(+ (* (car rs) (bitwise-and 255 num)) | |
(compute-hash-sum (arithmetic-shift n -8) (cdr rs))) | |
0)) | |
(let ([hash-sum (compute-hash-sum num global-rs)]) | |
(modulo hash-sum global-num-buckets))) | |
(define (init-hashtable! num-objects) | |
(let ([num-buckets (* 5 num-objects)]) | |
(set! global-num-buckets num-buckets) | |
(set! global-rs (stream-take (rand-stream num-buckets) 100)) | |
(make-vector num-buckets '()))) | |
(define (insert ht key val) | |
(let* ([hash-value (hash key)] | |
[ht-vals (vector-ref ht hash-value)] | |
[ht-vals-mod (cons (list key val) ht-vals)]) | |
(vector-set! ht hash-value ht-vals-mod))) | |
(define (lookup ht key) | |
(let* ([hash-value (hash key)] | |
[ht-vals (vector-ref ht hash-value)]) | |
(define (compare-val vs) | |
(if (null? vs) | |
#f | |
(if (= (car (first vs)) key) | |
(cadr (first vs)) | |
(compare-val (rest vs))))) | |
(if (not (null? ht-vals)) | |
(compare-val ht-vals) | |
#f))) | |
(define (delete ht key) | |
(let* ([hash-value (hash key)] | |
[ht-vals (vector-ref ht hash-value)]) | |
(define (scan-delete xs ys) | |
(if (null? ys) | |
#f | |
(if (= (car (first ys)) key) | |
(append xs (rest ys)) | |
(scan-delete (cons (first ys) xs) (rest ys))))) | |
(let ([ht-vals* (if (not (null? ht-vals)) | |
(scan-delete '() ht-vals) | |
#f)]) | |
(vector-set! ht hash-value ht-vals*)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment