| // Copyright 2012 Google Inc. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "syzygy/block_graph/orderers/random_orderer.h" |
| |
| #include <time.h> |
| |
| namespace block_graph { |
| namespace orderers { |
| |
| const char RandomOrderer::kOrdererName[] = "RandomOrderer"; |
| |
| RandomOrderer::RandomOrderer(bool default_shuffle_section) |
| : default_shuffle_section_(default_shuffle_section), |
| rng_(static_cast<uint32>(time(NULL))) { |
| } |
| |
| RandomOrderer::RandomOrderer(bool default_shuffle_section, uint32 seed) |
| : default_shuffle_section_(default_shuffle_section), rng_(seed) { |
| } |
| |
| void RandomOrderer::SetShuffleSection(const BlockGraph::Section* section, |
| bool shuffle) { |
| DCHECK(section != NULL); |
| shuffle_map_[section] = shuffle; |
| } |
| |
| bool RandomOrderer::ShouldShuffleSection( |
| const BlockGraph::Section* section) const { |
| // Look for an overridden value, otherwise use the default. |
| ShuffleMap::const_iterator shuffle_map_it = shuffle_map_.find(section); |
| if (shuffle_map_it != shuffle_map_.end()) |
| return shuffle_map_it->second; |
| return default_shuffle_section_; |
| } |
| |
| bool RandomOrderer::OrderBlockGraph(OrderedBlockGraph* ordered_block_graph, |
| BlockGraph::Block* /* header_block */) { |
| DCHECK(ordered_block_graph != NULL); |
| |
| // Run through the sections shuffling those that we need to. |
| OrderedBlockGraph::SectionList::const_iterator section_it = |
| ordered_block_graph->ordered_sections().begin(); |
| for (; section_it != ordered_block_graph->ordered_sections().end(); |
| ++section_it) { |
| const BlockGraph::Section* section = (*section_it)->section(); |
| |
| // Shuffle the sections. |
| if (ShouldShuffleSection(section)) |
| ShuffleBlocks(*section_it, ordered_block_graph); |
| } |
| |
| return true; |
| } |
| |
| void RandomOrderer::ShuffleBlocks( |
| const OrderedBlockGraph::OrderedSection* section, OrderedBlockGraph* obg) { |
| DCHECK(section != NULL); |
| |
| BlockVector blocks(section->ordered_blocks().begin(), |
| section->ordered_blocks().end()); |
| std::random_shuffle(blocks.begin(), blocks.end(), rng_); |
| |
| for (size_t i = 0; i < blocks.size(); ++i) |
| obg->PlaceAtTail(section->section(), blocks[i]); |
| } |
| |
| } // namespace orderers |
| } // namespace block_graph |