1 |
rschregle |
2.1 |
/* |
2 |
|
|
======================================================================= |
3 |
|
|
Cache for out-of-core octree. |
4 |
|
|
|
5 |
|
|
Uses an LRU page replacement scheme. Page table nodes are stored in |
6 |
|
|
order of reference in a doubly linked list, with the most recently used |
7 |
|
|
(MRU) page at the head, and the least recently used (LRU) at the tail. |
8 |
|
|
|
9 |
|
|
Nodes are referenced by the page's base address via a hashtable for |
10 |
|
|
constant time access (in the absence of hash collisions). Hash |
11 |
|
|
collisions can be limited by adjusting the hashtable load factor |
12 |
|
|
OOC_CACHE_LOAD; this is the fraction of the number of pages that will |
13 |
|
|
actually be cached. |
14 |
|
|
|
15 |
|
|
Roland Schregle (roland.schregle@{hslu.ch, gmail.com}) |
16 |
|
|
(c) Lucerne University of Applied Sciences and Arts, |
17 |
|
|
supported by the Swiss National Science Foundation (SNSF, #147053) |
18 |
|
|
======================================================================= |
19 |
|
|
|
20 |
greg |
2.2 |
$Id: ooccache.h,v 2.1 2016/05/17 17:39:47 rschregle Exp $ |
21 |
rschregle |
2.1 |
*/ |
22 |
|
|
|
23 |
|
|
|
24 |
|
|
#ifndef OOC_CACHE_H |
25 |
|
|
#define OOC_CACHE_H |
26 |
|
|
|
27 |
|
|
#include <stdio.h> |
28 |
|
|
#include <stdint.h> |
29 |
|
|
|
30 |
greg |
2.2 |
#ifdef __cplusplus |
31 |
|
|
extern "C" { |
32 |
|
|
#endif |
33 |
rschregle |
2.1 |
|
34 |
|
|
/* Hashtable load factor to limit hash collisions */ |
35 |
|
|
#define OOC_CACHE_LOAD 0.75 |
36 |
|
|
|
37 |
|
|
/* Minimum number of cache pages */ |
38 |
|
|
#define OOC_CACHE_MINPAGES 8 |
39 |
|
|
|
40 |
|
|
/* Hashing function for key -> pagetable mapping (assumes n is prime) */ |
41 |
|
|
#define OOC_CACHE_PRIME 19603 |
42 |
|
|
#define OOC_CACHE_HASH(k,n) ((k) * OOC_CACHE_PRIME % (n)) |
43 |
|
|
|
44 |
|
|
/* Next index in pagetable probe sequence for collision resolution */ |
45 |
|
|
#define OOC_CACHE_NEXT(i,n) (((i) + 1) % (n)) |
46 |
|
|
|
47 |
|
|
/* Cache key and index types */ |
48 |
|
|
typedef uint32_t OOC_CacheKey; |
49 |
|
|
typedef uint32_t OOC_CacheIdx; |
50 |
|
|
|
51 |
|
|
/* Undefined value for cache index */ |
52 |
|
|
#define OOC_CACHEIDX_NULL UINT32_MAX |
53 |
|
|
|
54 |
|
|
|
55 |
|
|
|
56 |
|
|
typedef struct { |
57 |
|
|
OOC_CacheKey key; /* Key to resolve hashing collisions */ |
58 |
|
|
OOC_CacheIdx prev, next; /* Previous/next page in history */ |
59 |
|
|
void *data; /* Start of page data */ |
60 |
|
|
} OOC_CacheNode; |
61 |
|
|
|
62 |
|
|
typedef struct { |
63 |
|
|
unsigned recSize, /* Data record size in bytes */ |
64 |
|
|
recPerPage; /* Page size in number of records */ |
65 |
|
|
unsigned long pageSize; /* Page size in bytes (precomp) */ |
66 |
|
|
OOC_CacheIdx pageCnt, /* Num pages used */ |
67 |
|
|
numPages; /* Pagetable size */ |
68 |
|
|
|
69 |
|
|
/* NOTE: The hashtable load factor limits the number of pages actually |
70 |
|
|
* used, such that pageCnt <= OOC_CACHE_LOAD * numPages */ |
71 |
|
|
|
72 |
|
|
OOC_CacheNode *pageTable; /* Pagetable with numPages nodes */ |
73 |
|
|
OOC_CacheIdx mru, lru; /* Most/least recently used page |
74 |
|
|
== head/tail of page history */ |
75 |
|
|
OOC_CacheKey lastKey; /* Previous key to detect repeat lookups */ |
76 |
|
|
OOC_CacheNode *lastPage; /* Previous page for repeat lookups */ |
77 |
|
|
|
78 |
|
|
unsigned long numReads, /* Statistics counters */ |
79 |
|
|
numHits, |
80 |
|
|
numColl, |
81 |
|
|
numRept; |
82 |
|
|
} OOC_Cache; |
83 |
|
|
|
84 |
|
|
|
85 |
|
|
|
86 |
|
|
/* Initialise cache containing up to numPages pages; this is rounded up |
87 |
|
|
* the next prime number to reduce hash clustering and collisions. The |
88 |
|
|
* page size recPerPage is specified in units of records of size recSize |
89 |
|
|
* bytes. Returns 0 on success, else -1. */ |
90 |
|
|
int OOC_CacheInit (OOC_Cache *cache, unsigned numPages, |
91 |
|
|
unsigned recPerPage, unsigned recSize); |
92 |
|
|
|
93 |
|
|
/* Return pointer to cached record with index recIdx, loading from file |
94 |
|
|
* and possibly evicting the LRU page */ |
95 |
|
|
void *OOC_CacheData (OOC_Cache *cache, FILE *file, unsigned long recIdx); |
96 |
|
|
|
97 |
|
|
/* Delete cache and free allocated pages */ |
98 |
|
|
void OOC_DeleteCache (OOC_Cache *cache); |
99 |
greg |
2.2 |
|
100 |
|
|
#ifdef __cplusplus |
101 |
|
|
} |
102 |
|
|
#endif |
103 |
|
|
|
104 |
rschregle |
2.1 |
#endif |