summaryrefslogtreecommitdiff
path: root/util/lruishmap.h
blob: f8e39e572f58f00bb0612cfa0277e923ea9c948b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// lru-ish map.h

/**
*    Copyright (C) 2008 10gen Inc.
*  
*    This program is free software: you can redistribute it and/or  modify
*    it under the terms of the GNU Affero General Public License, version 3,
*    as published by the Free Software Foundation.
*  
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU Affero General Public License for more details.
*  
*    You should have received a copy of the GNU Affero General Public License
*    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "../stdafx.h"
#include "../util/goodies.h"

/* Your K object must define:
	 int hash() - must always return > 0.
	 operator==
*/

template <class K, class V, int MaxChain>
class LRUishMap { 
public:
	LRUishMap(int _n) { 
		n = nextPrime(_n);
		keys = new K[n];
		hashes = new int[n];
		for( int i = 0; i < n; i++ ) hashes[i] = 0;
	}
	~LRUishMap() {
		delete[] keys;
		delete[] hashes;
	}

	int _find(const K& k, bool& found) {
		int h = k.hash(); 
		assert( h > 0 );
		int j = h % n;
		int first = j;
		for( int i = 0; i < MaxChain; i++ ) { 
			if( hashes[j] == h ) { 
				if( keys[j] == k ) { 
					found = true;
					return j;
				}
			}
			else if( hashes[j] == 0 ) { 
				found = false;
				return j;
			}
		}
		found = false;
		return first;
	}

	V* find(const K& k) { 
		bool found;
		int j = _find(k, found);
		return found ? &values[j] : 0;
	}

private:
	int n;
	K *keys;
	int *hashes;
	V *values;
};