diff --git a/src/overpass_api/core/basic_types.h b/src/overpass_api/core/basic_types.h index be44195d2..48c865ac3 100644 --- a/src/overpass_api/core/basic_types.h +++ b/src/overpass_api/core/basic_types.h @@ -48,20 +48,10 @@ struct Uint32_Index bool leq(void* rhs) const { return value <= *(uint32*)rhs; } bool equal(void* rhs) const { return value == *(uint32*)rhs; } - uint32 size_of() const - { - return 4; - } - - static uint32 max_size_of() - { - return 4; - } - - static uint32 size_of(void* data) - { - return 4; - } + uint32 size_of() const { return 4; } + static constexpr uint32 const_size() { return 4; } + static uint32 max_size_of() { return 4; } + static uint32 size_of(void* data) { return 4; } void to_data(void* data) const { @@ -187,6 +177,7 @@ struct Uint64 bool equal(void* rhs) const { return value == *(uint32*)rhs; } uint32 size_of() const { return 8; } + static constexpr uint32 const_size() { return 8; } static uint32 max_size_of() { return 8; } static uint32 size_of(void* data) { return 8; } diff --git a/src/overpass_api/core/datatypes.h b/src/overpass_api/core/datatypes.h index 9bbd794ec..0b44ecc73 100644 --- a/src/overpass_api/core/datatypes.h +++ b/src/overpass_api/core/datatypes.h @@ -693,15 +693,9 @@ struct Timestamp bool equal(void* rhs) const { return (timestamp>>32) == *(((uint8*)rhs) + 4) && (timestamp & 0xffffffffull) == *(uint32*)rhs; } - uint32 size_of() const - { - return 5; - } - - static uint32 size_of(void* data) - { - return 5; - } + uint32 size_of() const { return 5; } + static constexpr uint32 const_size() { return 5; } + static uint32 size_of(void* data) { return 5; } void to_data(void* data) const { diff --git a/src/overpass_api/core/type_tags.h b/src/overpass_api/core/type_tags.h index f033ac246..a4d6b4d0f 100644 --- a/src/overpass_api/core/type_tags.h +++ b/src/overpass_api/core/type_tags.h @@ -125,6 +125,8 @@ struct Tag_Index_Local return 7 + key.length() + value.length(); } + static constexpr uint32 const_size() { return 0; } + static uint32 size_of(void* data) { return (*((uint16*)data) + *((uint16*)data + 1) + 7); @@ -303,6 +305,8 @@ struct Tag_Index_Global return 4 + key.length() + value.length(); } + static constexpr uint32 const_size() { return 0; } + static uint32 size_of(void* data) { return (*((uint16*)data) + *((uint16*)data + 1) + 4); diff --git a/src/template_db/block_backend.test.cc b/src/template_db/block_backend.test.cc index 93b315a4d..d171004e8 100644 --- a/src/template_db/block_backend.test.cc +++ b/src/template_db/block_backend.test.cc @@ -46,15 +46,9 @@ struct IntIndex bool leq(void* rhs) const { return value <= *(uint32*)rhs; } bool equal(void* rhs) const { return value == *(uint32*)rhs; } - uint32 size_of() const - { - return 4; - } - - static uint32 size_of(void* data) - { - return 4; - } + uint32 size_of() const { return 4; } + static constexpr uint32 const_size() { return 4; } + static uint32 size_of(void* data) { return 4; } void to_data(void* data) const { diff --git a/src/template_db/dispatcher.test.cc b/src/template_db/dispatcher.test.cc index 078c64565..4ac471ed8 100644 --- a/src/template_db/dispatcher.test.cc +++ b/src/template_db/dispatcher.test.cc @@ -44,20 +44,10 @@ struct IntIndex bool leq(void* rhs) const { return value <= *(uint32*)rhs; } bool equal(void* rhs) const { return value == *(uint32*)rhs; } - uint32 size_of() const - { - return 4; - } - - static uint32 size_of(void* data) - { - return 4; - } - - static uint32 max_size_of() - { - return 4; - } + uint32 size_of() const { return 4; } + static constexpr uint32 const_size() { return 4; } + static uint32 size_of(void* data) { return 4; } + static uint32 max_size_of() { return 4; } void to_data(void* data) const { diff --git a/src/template_db/file_blocks.test.cc b/src/template_db/file_blocks.test.cc index e56de219e..415a65b4e 100644 --- a/src/template_db/file_blocks.test.cc +++ b/src/template_db/file_blocks.test.cc @@ -43,6 +43,7 @@ struct IntIndex bool equal(void* rhs) const { return value == *(uint32*)rhs; } uint32 size_of() const { return (value < 24 ? 12 : value-12); } + static constexpr uint32 const_size() { return 0; } static uint32 size_of(void* data) { return ((*(uint32*)data) < 24 ? 12 : (*(uint32*)data)-12); } void to_data(void* data) const diff --git a/src/template_db/file_blocks_index.h b/src/template_db/file_blocks_index.h index a5beda9bf..4ef279203 100644 --- a/src/template_db/file_blocks_index.h +++ b/src/template_db/file_blocks_index.h @@ -325,11 +325,39 @@ inline uint64 file_size_of(const std::string& data_file_name) } +template< typename Index > +const uint8* binary_seek(const uint8* begin, const uint8* end, const Index& target) +{ + auto min = begin; + auto max = end; + while (max - min > 2*(Index::const_size() + 12)) + { + auto middle = min + ((max - min)/(Index::const_size() + 12)/2*(Index::const_size() + 12)); + if (target.less((void*)(middle+12))) + max = middle; + else + min = middle; + } + return min; +} + + template< typename Index > void File_Blocks_Index_Iterator< Index >::seek(const Index& target) { if (ptr == end || target.less((void*)(ptr+12))) return; + if (Index::const_size() && ((end - ptr) > 32*(Index::const_size() + 12)) + && !target.less((void*)(ptr + 32*(Index::const_size() + 12) + 12))) + { + decltype(ptr) next = binary_seek(ptr, end, target); + if (next != end) + { + while (ptr < next && target.equal((void*)(next+12))) + next -= (Index::const_size() + 12); + } + ptr = next; + } while (!target.equal((void*)(ptr+12))) { decltype(ptr) next = ptr+12;