| 571 | void BuildSearchIndex(FilesContainerR & container, Writer & indexWriter); |
| 572 | |
| 573 | bool BuildSearchIndexFromDataFile(std::string const & country, feature::GenerateInfo const & info, bool forceRebuild, |
| 574 | uint32_t threadsCount) |
| 575 | { |
| 576 | Platform & platform = GetPlatform(); |
| 577 | |
| 578 | auto const filename = info.GetTargetFileName(country, DATA_FILE_EXTENSION); |
| 579 | FilesContainerR readContainer(platform.GetReader(filename, "f")); |
| 580 | if (readContainer.IsExist(SEARCH_INDEX_FILE_TAG) && !forceRebuild) |
| 581 | return true; |
| 582 | |
| 583 | auto const indexFilePath = filename + "." + SEARCH_INDEX_FILE_TAG EXTENSION_TMP; |
| 584 | auto const streetsFilePath = filename + "." + FEATURE2STREET_FILE_TAG EXTENSION_TMP; |
| 585 | auto const placesFilePath = filename + "." + FEATURE2PLACE_FILE_TAG EXTENSION_TMP; |
| 586 | SCOPE_GUARD(indexFileGuard, std::bind(&FileWriter::DeleteFileX, indexFilePath)); |
| 587 | SCOPE_GUARD(streetsFileGuard, std::bind(&FileWriter::DeleteFileX, streetsFilePath)); |
| 588 | SCOPE_GUARD(placesFileGuard, std::bind(&FileWriter::DeleteFileX, placesFilePath)); |
| 589 | |
| 590 | try |
| 591 | { |
| 592 | { |
| 593 | FileWriter writer(indexFilePath); |
| 594 | BuildSearchIndex(readContainer, writer); |
| 595 | LOG(LINFO, ("Search index size =", writer.Size())); |
| 596 | } |
| 597 | |
| 598 | if (filename != WORLD_FILE_NAME && filename != WORLD_COASTS_FILE_NAME) |
| 599 | { |
| 600 | FileWriter streetsWriter(streetsFilePath); |
| 601 | FileWriter placesWriter(placesFilePath); |
| 602 | auto const addrsFile = info.GetIntermediateFileName(country + DATA_FILE_EXTENSION, TEMP_ADDR_EXTENSION); |
| 603 | BuildAddressTable(readContainer, addrsFile, streetsWriter, placesWriter, threadsCount); |
| 604 | LOG(LINFO, ("Streets table size:", streetsWriter.Size(), "; Places table size:", placesWriter.Size())); |
| 605 | } |
| 606 | |
| 607 | // Separate scopes because FilesContainerW can't write two sections at once. |
| 608 | { |
| 609 | FilesContainerW writeContainer(readContainer.GetFileName(), FileWriter::OP_WRITE_EXISTING); |
| 610 | auto writer = writeContainer.GetWriter(SEARCH_INDEX_FILE_TAG); |
| 611 | size_t const startOffset = writer->Pos(); |
| 612 | CHECK(coding::IsAlign8(startOffset), ()); |
| 613 | |
| 614 | search::SearchIndexHeader header; |
| 615 | header.Serialize(*writer); |
| 616 | |
| 617 | uint64_t bytesWritten = writer->Pos(); |
| 618 | coding::WritePadding(*writer, bytesWritten); |
| 619 | |
| 620 | header.m_indexOffset = base::asserted_cast<uint32_t>(writer->Pos() - startOffset); |
| 621 | rw_ops::Reverse(FileReader(indexFilePath), *writer); |
| 622 | header.m_indexSize = base::asserted_cast<uint32_t>(writer->Pos() - header.m_indexOffset - startOffset); |
| 623 | |
| 624 | auto const endOffset = writer->Pos(); |
| 625 | writer->Seek(startOffset); |
| 626 | header.Serialize(*writer); |
| 627 | writer->Seek(endOffset); |
| 628 | } |
| 629 | |
| 630 | /// @todo FilesContainerW::Write with section overriding invalidates current container instance |