|
6 | 6 | #include <set> |
7 | 7 | #include <vector> |
8 | 8 | #include <memory> |
9 | | -#include <boost/sort/sort.hpp> |
10 | | -#include "output_object.h" |
11 | 9 | #include "append_vector.h" |
12 | 10 | #include "clip_cache.h" |
13 | 11 | #include "mmap_allocator.h" |
14 | 12 | #include "tile_coordinates_set.h" |
15 | | - |
16 | | -#define TILE_DATA_ID_SIZE 34 |
| 13 | +#include "tile_data_base.h" |
17 | 14 |
|
18 | 15 | typedef std::vector<class TileDataSource *> SourceList; |
19 | 16 |
|
20 | 17 | class TileBbox; |
21 | 18 |
|
22 | | -// We cluster output objects by z6 tile |
23 | | -#define CLUSTER_ZOOM 6 |
24 | | -#define CLUSTER_ZOOM_WIDTH (1 << CLUSTER_ZOOM) |
25 | | -#define CLUSTER_ZOOM_AREA (CLUSTER_ZOOM_WIDTH * CLUSTER_ZOOM_WIDTH) |
26 | | - |
27 | | -// TileDataSource indexes which tiles have objects in them. The indexed zoom |
28 | | -// is at most z14; we'll clamp to z14 if the base zoom is higher than z14. |
29 | | -// |
30 | | -// As a result, we need at most 15 bits to store an X/Y coordinate. For efficiency, |
31 | | -// we bucket the world into 4,096 z6 tiles, which each contain some number of |
32 | | -// z14 objects. This lets us use only 8 bits to store an X/Y coordinate. |
33 | | -// |
34 | | -// Because index zoom is lower than base zoom in the case where base zoom is |
35 | | -// z15+, we'll get false positives when looking up objects in the index, |
36 | | -// since, e.g., a single z14 tile covers 4 z15 tiles. |
37 | | -// |
38 | | -// This is OK: when writing the z15 tile, there's a clipping step that will filter |
39 | | -// out the false positives. |
40 | | -typedef uint8_t Z6Offset; |
41 | | - |
42 | | -struct OutputObjectXY { |
43 | | - OutputObject oo; |
44 | | - Z6Offset x; |
45 | | - Z6Offset y; |
46 | | -}; |
47 | | - |
48 | | -struct OutputObjectXYID { |
49 | | - OutputObject oo; |
50 | | - Z6Offset x; |
51 | | - Z6Offset y; |
52 | | - uint64_t id; |
53 | | -}; |
| 19 | +template<typename OO> void sortOutputObjects( |
| 20 | + const unsigned int indexZoom, |
| 21 | + const size_t threadNum, |
| 22 | + typename AppendVectorNS::AppendVector<OO>::Iterator begin, |
| 23 | + typename AppendVectorNS::AppendVector<OO>::Iterator end |
| 24 | +); |
54 | 25 |
|
55 | 26 | template<typename OO> void finalizeObjects( |
56 | 27 | const std::string& name, |
@@ -88,52 +59,7 @@ template<typename OO> void finalizeObjects( |
88 | 59 | if (objectIt->oo.minZoom < CLUSTER_ZOOM) |
89 | 60 | lowZoom[i].push_back(*objectIt); |
90 | 61 |
|
91 | | - // If the user is doing a a small extract, there are few populated |
92 | | - // entries in `object`. |
93 | | - // |
94 | | - // e.g. Colorado has ~9 z6 tiles, 1 of which has 95% of its output |
95 | | - // objects. |
96 | | - // |
97 | | - // This optimizes for the small extract case by doing: |
98 | | - // - for each vector in objects |
99 | | - // - do a multi-threaded sort of vector |
100 | | - // |
101 | | - // For small extracts, this ensures that all threads are used even if |
102 | | - // only a handful of entries in `objects` are non-empty. |
103 | | - // |
104 | | - // For a global extract, this will have some overhead of repeatedly |
105 | | - // setting up/tearing down threads. In that case, it would be |
106 | | - // better to assign chunks of `objects` to each thread. |
107 | | - // |
108 | | - // That's a future performance improvement, so deferring for now. |
109 | | - boost::sort::block_indirect_sort( |
110 | | - it->begin(), |
111 | | - it->end(), |
112 | | - [indexZoom](const OO& a, const OO& b) { |
113 | | - // Cluster by parent zoom, so that a subsequent search |
114 | | - // can find a contiguous range of entries for any tile |
115 | | - // at zoom 6 or higher. |
116 | | - const size_t aX = a.x; |
117 | | - const size_t aY = a.y; |
118 | | - const size_t bX = b.x; |
119 | | - const size_t bY = b.y; |
120 | | - for (size_t z = CLUSTER_ZOOM; z <= indexZoom; z++) { |
121 | | - const auto aXz = aX / (1 << (indexZoom - z)); |
122 | | - const auto bXz = bX / (1 << (indexZoom - z)); |
123 | | - if (aXz != bXz) |
124 | | - return aXz < bXz; |
125 | | - |
126 | | - const auto aYz = aY / (1 << (indexZoom - z)); |
127 | | - const auto bYz = bY / (1 << (indexZoom - z)); |
128 | | - |
129 | | - if (aYz != bYz) |
130 | | - return aYz < bYz; |
131 | | - } |
132 | | - |
133 | | - return false; |
134 | | - }, |
135 | | - threadNum |
136 | | - ); |
| 62 | + sortOutputObjects<OO>(indexZoom, threadNum, it->begin(), it->end()); |
137 | 63 | } |
138 | 64 |
|
139 | 65 | std::cout << std::endl; |
|
0 commit comments