Skip to content

Commit 4586c4c

Browse files
committed
Check tile_id order
1 parent 2c520c7 commit 4586c4c

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

src/writer.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,14 +212,17 @@ impl<W: Write + Seek> PmTilesStreamWriter<W> {
212212
/// Add tile to writer.
213213
///
214214
/// Tiles are deduplicated and written to output.
215-
/// `tile_id` should be increasing.
215+
/// `tile_id` should be increasing for best read performance.
216216
pub fn add_tile(&mut self, tile_id: u64, data: &[u8]) -> PmtResult<()> {
217217
if data.is_empty() {
218218
// Ignore empty tiles, since the spec does not allow storing them
219219
return Ok(());
220220
}
221221

222222
let is_first = self.entries.is_empty();
223+
if is_first && tile_id > 0 {
224+
self.header.clustered = false;
225+
}
223226
let mut first_entry = DirEntry {
224227
tile_id: 0,
225228
offset: 0,
@@ -241,6 +244,9 @@ impl<W: Write + Seek> PmTilesStreamWriter<W> {
241244
data.write_compressed_to_counted(&mut self.out, self.header.tile_compression)?;
242245
let length = into_u32(len)?;
243246
self.n_tile_contents += 1;
247+
if tile_id != last_entry.tile_id + u64::from(last_entry.run_length) {
248+
self.header.clustered = false;
249+
}
244250

245251
self.entries.push(DirEntry {
246252
tile_id,
@@ -259,6 +265,11 @@ impl<W: Write + Seek> PmTilesStreamWriter<W> {
259265
/// Leaf directories are written to output.
260266
/// The root directory is returned.
261267
fn build_directories(&mut self) -> PmtResult<Directory> {
268+
if !self.header.clustered {
269+
// Spec does only say that leaf directories *should* be in ascending order,
270+
// but sorted directories are better for readers anyway.
271+
self.entries.sort_by_key(|entry| entry.tile_id);
272+
}
262273
let (root_dir, num_leaves) = self.optimize_directories(MAX_INITIAL_BYTES - HEADER_SIZE)?;
263274
if num_leaves > 0 {
264275
// Write leaf directories
@@ -466,4 +477,16 @@ mod tests {
466477
assert_eq!(num_leaves, 5);
467478
assert_eq!(root_dir.entries().len(), num_leaves);
468479
}
480+
481+
#[test]
482+
fn unclustered() {
483+
let fname = get_temp_file_path("pmtiles").unwrap();
484+
let file = File::create(fname).unwrap();
485+
let mut writer = PmTilesWriter::new(TileType::Png).create(file).unwrap();
486+
writer.add_tile(0, &[0, 1, 2, 3]).unwrap();
487+
assert!(writer.header.clustered);
488+
writer.add_tile(2, &[0, 1, 2, 3]).unwrap();
489+
assert!(!writer.header.clustered);
490+
writer.finish().unwrap();
491+
}
469492
}

0 commit comments

Comments
 (0)