Merges entries of "prefix" into the accumulator state "merge". Returns OK iff the merge succeeds.
| 669 | // Merges entries of "prefix" into the accumulator state "merge". |
| 670 | // Returns OK iff the merge succeeds. |
| 671 | static Status MergeOneBundle(Env* env, StringPiece prefix, |
| 672 | MergeState* merge_state) { |
| 673 | VLOG(1) << "Merging bundle:" << prefix; |
| 674 | const string filename = MetaFilename(prefix); |
| 675 | uint64 file_size; |
| 676 | TF_RETURN_IF_ERROR(env->GetFileSize(filename, &file_size)); |
| 677 | std::unique_ptr<RandomAccessFile> file; |
| 678 | TF_RETURN_IF_ERROR(env->NewRandomAccessFile(filename, &file)); |
| 679 | |
| 680 | table::Table* table = nullptr; |
| 681 | TF_RETURN_IF_ERROR( |
| 682 | table::Table::Open(TableBuilderOptions(), file.get(), file_size, &table)); |
| 683 | std::unique_ptr<table::Table> table_deleter(table); |
| 684 | std::unique_ptr<table::Iterator> iter(table->NewIterator()); |
| 685 | |
| 686 | int num_shards; |
| 687 | // Process header. |
| 688 | { |
| 689 | iter->Seek(kHeaderEntryKey); |
| 690 | if (!iter->Valid()) { |
| 691 | return CorruptFileError(iter->status(), filename, |
| 692 | "failed to seek to header entry"); |
| 693 | } |
| 694 | BundleHeaderProto header; |
| 695 | Status s = ParseEntryProto(iter->key(), iter->value(), &header); |
| 696 | if (!s.ok()) return CorruptFileError(s, filename, "unable to parse header"); |
| 697 | |
| 698 | merge_state->num_shards += header.num_shards(); |
| 699 | if (!merge_state->seen_first_bundle) { |
| 700 | merge_state->seen_first_bundle = true; |
| 701 | merge_state->endianness = header.endianness(); |
| 702 | merge_state->version = header.version(); |
| 703 | } else { |
| 704 | // Validates "endianness". |
| 705 | if (merge_state->endianness != header.endianness()) { |
| 706 | return errors::InvalidArgument( |
| 707 | "Merging bundles with conflicting endianness; inputs corrupted?"); |
| 708 | } |
| 709 | // Validates "version". |
| 710 | string curr_version, merge_version; |
| 711 | header.version().SerializeToString(&curr_version); |
| 712 | merge_state->version.SerializeToString(&merge_version); |
| 713 | if (curr_version != merge_version) { |
| 714 | return errors::InvalidArgument( |
| 715 | "Merging bundles with different format versions: merged ", |
| 716 | merge_version, " vs. curr ", curr_version); |
| 717 | } |
| 718 | } |
| 719 | num_shards = header.num_shards(); |
| 720 | iter->Next(); |
| 721 | } |
| 722 | |
| 723 | // Loops through the non-header to-merge entries. |
| 724 | BundleEntryProto to_merge_entry; |
| 725 | for (; iter->Valid(); iter->Next()) { |
| 726 | const string key(iter->key()); |
| 727 | const auto entry_iter = merge_state->entries.find(key); |
| 728 |
no test coverage detected