File: geometry_cache.h

package info (click to toggle)
tilemaker 3.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 78,284 kB
  • sloc: cpp: 28,715; ansic: 4,052; makefile: 180; ruby: 77; sh: 6
file content (53 lines) | stat: -rw-r--r-- 1,252 bytes parent folder | download
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
#ifndef _GEOMETRY_CACHE_H
#define _GEOMETRY_CACHE_H

// A small class to map from ID -> geometry, with
// a bounded size and LRU-ish behaviour.
//
// Not safe for multi-threaded use!

#include "coordinates.h"
#include <memory>

#define NUM_BUCKETS 256
// Keep bucket size small so linear search is fast
#define BUCKET_SIZE 32


template <class T>
class GeometryCache {
public:
	GeometryCache():
		offsets(NUM_BUCKETS),
		ids(NUM_BUCKETS * BUCKET_SIZE),
		geometries(NUM_BUCKETS * BUCKET_SIZE) {}

	T* get(NodeID objectID) {
		const size_t bucket = objectID % NUM_BUCKETS;

		for (size_t i = bucket * BUCKET_SIZE; i < (bucket + 1) * BUCKET_SIZE; i++)
			if (ids[i] == objectID)
				return geometries[i].get();

		return nullptr;
	}

	void add(NodeID objectID, std::shared_ptr<T> geom) {
		const size_t bucket = objectID % NUM_BUCKETS;
		size_t offset = bucket * BUCKET_SIZE + offsets[bucket];
		geometries[offset] = geom;
		ids[offset] = objectID;
		offsets[bucket]++;

		if (offsets[bucket] == BUCKET_SIZE)
			offsets[bucket] = 0;
	}

private:
	std::vector<uint8_t> offsets;
	std::vector<NodeID> ids;
	// CONSIDER: we could use a raw pointer - getOrBuildLinestring controls the lifetime
	std::vector<std::shared_ptr<Linestring>> geometries;
};

#endif