<commit_before>#include "consoleui.h"
#include <iostream>
#include <iomanip>
using namespace std;

consoleUI::consoleUI()
{

}

consoleUI::consoleUI(int chooseNumber)
{
    _chooseNumber = chooseNumber;
}

void consoleUI::run()
{
    int chooseNumber = 0;

    cout << "------------------------------------------------------------------" << endl;
    cout << "*------ Database for Scientist ----------*--------Glossary-------*" << endl;
    cout << "* 1:  Display entire list.               * Y.O.D = date of death *" << endl;
    cout << "* 2:  Search by name.                    * Y.O.B = date of birth *"<< endl;
    cout << "* 3:  Search if alive.                   * Y.O.A = year of award *" << endl;
    cout << "* 4:  Sort by award year.                *                       *" << endl;
    cout << "* 5:  Add new scientist.                 *                       *" << endl;
    cout << "* 6:  Search for birth year.             *                       *" << endl;
    cout << "* 7:  Enter Function.                    *                       *" << endl;
    cout << "* 8:  Sort by birthyear.                 *                       *" << endl;
    cout << "* 9:  Search for Turing award winner.    *                       *" << endl;
    cout << "* 10: Chuck Norris.                      *                       *" << endl;
    cout << "*----------------------------------------*-----------------------*" << endl;
    cout << "-----------------------------------------------------------------" << endl;
    cout << "Enter number: ";

    cin >> chooseNumber;

    //This function sends you (from the number you pick) to the right corresponding case
    switch (chooseNumber)
    {
        //This function displays a list of all the scientists (that is there full names, dob, dod and year of award)
        case 1:
        {
            listServices scientists;
            cout << "***List of all scientists***" << endl;
            print();
            printNames(scientists);
        }
            break;

        //This function let's you search from either the first or last name
        case 2:
            {
                listServices scientists;
                //listServices searchName2;
                string searchTerm;
                cout << "Enter a single name to search: ";
                cin >> searchTerm;
                scientists.changeTo(_scientist.searchName(searchTerm));
                print();
                printNames(scientists);

            }
            break;
        case 3:
            //sortAlive
            {
                listServices scientists;
                string searchTerm;
                scientists.changeTo(_scientist.searchAlive());
                cout << "An organized list starting with the oldest living scientist" << endl;
                print();
                printNames(scientists);
             }
              break;
        case 4:
            //sortAward
            {
                listServices scientistsByAward;
                scientistsByAward.changeTo(_scientist.sortByAward());
                cout << "An organized list of scientists in order of when they received the Turing award." << endl;
                print();
                printNames(scientistsByAward);
             }
            break;

        case 5:
            {
                //addNew
                string firstName;
                string lastName;
                char gender;
                int birthYear;
                char isAlive;
                int deathYear;
                char isWinner;
                int awardYear;

                cout << "Please enter the scientist's first name: ";
                cin >> firstName;
                cout << "Please enter the scientist's last name: ";
                cin >> lastName;
                cout << "Enter the scientist's gender (m/f) : ";
                cin >> gender;
                cout << "Enter the scientist's birth year: ";
                cin >> birthYear;
                cout << "Is the scientist still alive? (y/n) ";
                cin >> isAlive;
                if(isAlive == 'n')
                {
                    cout << "Enter the scientist's year of death: ";
                    cin >>  deathYear;
                }
                else if(isAlive == 'y')
                {
                    deathYear = 0;
                }
                else
                {
                    cout << "Invalid entry.  Please enter either y (yes) or n (no)";
                }
                cout << "Did the scientist win a Turing award? (y/n)";
                cin >> isWinner;
                if(isWinner == 'y')
                {
                    cout << "Enter the year the scientist won: ";
                    cin >>  awardYear;
                }
                else if(isWinner == 'n')
                {
                    awardYear = 0;
                }
                else
                {
                    cout << "Invalid entry.  Please enter either y (yes) or n (no)";
                }

                _scientist.addNew(firstName, lastName, gender, birthYear, deathYear, awardYear);
            }
            break;
    case 6:
        //searchBirth
        {
            int year;
            cout << "Enter year: ";
            cin >> year;
            listServices scientistsBirth;
            scientistsBirth.changeTo(scientistsBirth.searchBirth(year));
            cout << "A list of scientists born in your year of choice" << endl;
            print();
            printNames(scientistsBirth);
         }
          break;
    case 7:
        //sort by name
    {
        listServices sort;
        sort.changeTo(_scientist.sortByName());
        cout << "A list of scinetists in alphabetical order" << endl;
        print();
        printNames(sort);

    }
        break;

    case 8:
        //sortByBirth

            _scientist.changeTo(_scientist.sortByBirth());
            cout << "An organized list starting with the oldest scientist" << endl;
            print();
            printNames(_scientist);
        break;

    case 9:
        //sortByAward
            _scientist.changeTo(_scientist.sortByAward());
            cout << "An organized list of scientists in order of when they received a Turing award." << endl;
            print();
            printNames(_scientist);
         break;

    case 10:
    {
        listServices norris;
 /* for(int i = 0; i < _scientist.chuckNorris(); i++){
       _scientist.chu
  }*/

        norris.changeTo(_scientist.chuckNorris());
        //print();
        printNames(norris);

        break;
    }
}
}
void consoleUI::print()
{
    listServices scientists;

    cout.width(4);
    cout << left << "No.";
    cout.width(scientists.searchLongestName());
    cout << "Firstname" << left;
    cout.width(10);
    cout << "Lastname" << left;
    cout.width(10);
    cout << "gender" << left;
    cout.width(10);
    cout << "D.O.B" << left;
    cout.width(10);
    cout << "D.O.D" << left;
    cout.width(scientists.searchLongestName());
    cout << "Y.O.A." << left << endl;
    for(int i = 0 ; i < 9 ; i++)
    {
        cout << "--------";
    }
    cout << endl;
}

void consoleUI::printNames (listServices scientistsToPrint)
{
    int counter = 1;
    for(int i = 0; i < scientistsToPrint.getSize() ; i++)
    {
        string sex;
        string isDead;
        if(scientistsToPrint.getSexFromList(i) == 'm')
        {
            sex = "male";
        }
        else
        {
            sex = "female";
        }
        cout.width(5);
        cout << left << counter;
        counter++;
        cout.width(10);
        cout << scientistsToPrint.getFirstNameFromList(i) << left;
        cout.width(10);
        cout << scientistsToPrint.getLastNameFromList(i) << left;
        cout.width(10);
        cout << sex << left;
        cout.width(10);
        cout << scientistsToPrint.dobFromList(i) << left;
        if(scientistsToPrint.dodFromList(i) == 0)
        {
            isDead = "Alive";
            cout.width(10);
            cout << isDead << left;
        }
        else
        {
            cout.width(10);
            cout << scientistsToPrint.dodFromList(i) << left;
        }
        cout.width(10);
        cout << scientistsToPrint.getAwardsFromList(i) << left;;
        cout << "   *" << endl;

    }
    for(int i = 0 ; i < 9 ; i++)
    {
        cout << "--------";
    }
    cout << endl;
}
<commit_msg>still fixin<commit_after>#include "consoleui.h"
#include <iostream>
#include <iomanip>
using namespace std;

consoleUI::consoleUI()
{

}

consoleUI::consoleUI(int chooseNumber)
{
    _chooseNumber = chooseNumber;
}

void consoleUI::run()
{
    int chooseNumber = 0;

    cout << "------------------------------------------------------------------" << endl;
    cout << "*------ Database for Scientist ----------*--------Glossary-------*" << endl;
    cout << "* 1:  Display entire list.               * Y.O.D = date of death *" << endl;
    cout << "* 2:  Search by name.                    * Y.O.B = date of birth *"<< endl;
    cout << "* 3:  Search if alive.                   * Y.O.A = year of award *" << endl;
    cout << "* 4:  Sort by award year.                *                       *" << endl;
    cout << "* 5:  Add new scientist.                 *                       *" << endl;
    cout << "* 6:  Search for birth year.             *                       *" << endl;
    cout << "* 7:  Disply list in alphabetical order  *                       *" << endl;
    cout << "* 8:  Sort by birthyear.                 *                       *" << endl;
    cout << "* 9:  Search for Turing award winner.    *                       *" << endl;
    cout << "* 10: Chuck Norris.                      *                       *" << endl;
    cout << "*----------------------------------------*-----------------------*" << endl;
    cout << "-----------------------------------------------------------------" << endl;
    cout << "Enter number: ";

    cin >> chooseNumber;

    //This function sends you (from the number you pick) to the right corresponding case
    switch (chooseNumber)
    {
        //This function displays a list of all the scientists (that is there full names, dob, dod and year of award)
        case 1:
        {
            listServices scientists;
            cout << "***List of all scientists***" << endl;
            print();
            printNames(scientists);
        }
            break;

        //This function let's you search from either the first or last name
        case 2:
            {
                listServices scientists;
                //listServices searchName2;
                string searchTerm;
                cout << "Enter a single name to search: ";
                cin >> searchTerm;
                scientists.changeTo(_scientist.searchName(searchTerm));
                print();
                printNames(scientists);

            }
            break;
        case 3:
            //sortAlive
            {
                listServices scientists;
                string searchTerm;
                scientists.changeTo(_scientist.searchAlive());
                cout << "An organized list starting with the oldest living scientist" << endl;
                print();
                printNames(scientists);
             }
              break;
        case 4:
            //sortAward
            {
                listServices scientistsByAward;
                scientistsByAward.changeTo(_scientist.sortByAward());
                cout << "An organized list of scientists in order of when they received the Turing award." << endl;
                print();
                printNames(scientistsByAward);
             }
            break;

        case 5:
            {
                //addNew
                string firstName;
                string lastName;
                char gender;
                int birthYear;
                char isAlive;
                int deathYear;
                char isWinner;
                int awardYear;

                cout << "Please enter the scientist's first name: ";
                cin >> firstName;
                cout << "Please enter the scientist's last name: ";
                cin >> lastName;
                cout << "Enter the scientist's gender (m/f) : ";
                cin >> gender;
                cout << "Enter the scientist's birth year: ";
                cin >> birthYear;
                cout << "Is the scientist still alive? (y/n) ";
                cin >> isAlive;
                if(isAlive == 'n')
                {
                    cout << "Enter the scientist's year of death: ";
                    cin >>  deathYear;
                }
                else if(isAlive == 'y')
                {
                    deathYear = 0;
                }
                else
                {
                    cout << "Invalid entry.  Please enter either y (yes) or n (no)";
                }
                cout << "Did the scientist win a Turing award? (y/n)";
                cin >> isWinner;
                if(isWinner == 'y')
                {
                    cout << "Enter the year the scientist won: ";
                    cin >>  awardYear;
                }
                else if(isWinner == 'n')
                {
                    awardYear = 0;
                }
                else
                {
                    cout << "Invalid entry.  Please enter either y (yes) or n (no)";
                }

                _scientist.addNew(firstName, lastName, gender, birthYear, deathYear, awardYear);
            }
            break;
    case 6:
        //searchBirth
        {
            int year;
            cout << "Enter year: ";
            cin >> year;
            listServices scientistsBirth;
            scientistsBirth.changeTo(scientistsBirth.searchBirth(year));
            cout << "A list of scientists born in your year of choice" << endl;
            print();
            printNames(scientistsBirth);
         }
          break;
    case 7:
        //sort by name
    {
        listServices sort;
        sort.changeTo(_scientist.sortByName());
        cout << "A list of scinetists in alphabetical order" << endl;
        print();
        printNames(sort);

    }
        break;

    case 8:
        //sortByBirth

            _scientist.changeTo(_scientist.sortByBirth());
            cout << "An organized list starting with the oldest scientist" << endl;
            print();
            printNames(_scientist);
        break;

    case 9:
        //sortByAward
            _scientist.changeTo(_scientist.sortByAward());
            cout << "An organized list of scientists in order of when they received a Turing award." << endl;
            print();
            printNames(_scientist);
         break;

    case 10:
    {
        listServices norris;
 /* for(int i = 0; i < _scientist.chuckNorris(); i++){
       _scientist.chu
  }*/

        norris.changeTo(_scientist.chuckNorris());
        print();
        printNames(norris);

        break;
    }
}
}
void consoleUI::print()
{
    listServices scientists;

    cout.width(4);
    cout << left << "No.";
    cout.width(scientists.searchLongestName());
    cout << "Firstname" << left;
    cout.width(10);
    cout << "Lastname" << left;
    cout.width(10);
    cout << "gender" << left;
    cout.width(10);
    cout << "Y.O.B" << left;
    cout.width(10);
    cout << "Y.O.D" << left;
    cout.width(scientists.searchLongestName());
    cout << "Y.O.A" << left << endl;
    for(int i = 0 ; i < 9 ; i++)
    {
        cout << "--------";
    }
    cout << endl;
}

void consoleUI::printNames (listServices scientistsToPrint)
{
    int counter = 1;
    for(int i = 0; i < scientistsToPrint.getSize() ; i++)
    {
        string sex;
        string isDead;
        if(scientistsToPrint.getSexFromList(i) == 'm')
        {
            sex = "male";
        }
        else
        {
            sex = "female";
        }
        cout.width(5);
        cout << left << counter;
        counter++;
        cout.width(10);
        cout << scientistsToPrint.getFirstNameFromList(i) << left;
        cout.width(10);
        cout << scientistsToPrint.getLastNameFromList(i) << left;
        cout.width(10);
        cout << sex << left;
        cout.width(10);
        cout << scientistsToPrint.dobFromList(i) << left;
        if(scientistsToPrint.dodFromList(i) == 0)
        {
            isDead = "Alive";
            cout.width(10);
            cout << isDead << left;
        }
        else
        {
            cout.width(10);
            cout << scientistsToPrint.dodFromList(i) << left;
        }
        cout.width(10);
        cout << scientistsToPrint.getAwardsFromList(i) << left;;
        cout << "   *" << endl;

    }
    for(int i = 0 ; i < 9 ; i++)
    {
        cout << "--------";
    }
    cout << endl;
}
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/app_modal_dialog_queue.h"

#include "chrome/browser/browser_list.h"

void AppModalDialogQueue::AddDialog(AppModalDialog* dialog) {
  if (!active_dialog_) {
    ShowModalDialog(dialog);
    return;
  }
  app_modal_dialog_queue_.push(dialog);
}

void AppModalDialogQueue::ShowNextDialog() {
  AppModalDialog* dialog = GetNextDialog();
  if (dialog)
    ShowModalDialog(dialog);
  else
    active_dialog_ = NULL;
}

void AppModalDialogQueue::ActivateModalDialog() {
  if (showing_modal_dialog_) {
    // As part of showing a modal dialog we may end up back in this method
    // (showing a dialog activates the TabContents, which can trigger a call
    // to ActivateModalDialog). We ignore such a request as after the call to
    // activate the tab contents the dialog is shown.
    return;
  }
  if (active_dialog_)
    active_dialog_->ActivateModalDialog();
}

void AppModalDialogQueue::ShowModalDialog(AppModalDialog* dialog) {
  // Be sure and set the active_dialog_ field first, otherwise if
  // ShowModalDialog triggers a call back to the queue they'll get the old
  // dialog. Also, if the dialog calls |ShowNextDialog()| before returning, that
  // would write NULL into |active_dialog_| and this function would then undo
  // that.
  active_dialog_ = dialog;
  showing_modal_dialog_ = true;
  dialog->ShowModalDialog();
  showing_modal_dialog_ = false;
}

AppModalDialog* AppModalDialogQueue::GetNextDialog() {
  while (!app_modal_dialog_queue_.empty()) {
    AppModalDialog* dialog = app_modal_dialog_queue_.front();
    app_modal_dialog_queue_.pop();
    if (dialog->IsValid())
      return dialog;
    delete dialog;
  }
  return NULL;
}
<commit_msg>Copyright change to force builders to rebuild.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/app_modal_dialog_queue.h"

#include "chrome/browser/browser_list.h"

void AppModalDialogQueue::AddDialog(AppModalDialog* dialog) {
  if (!active_dialog_) {
    ShowModalDialog(dialog);
    return;
  }
  app_modal_dialog_queue_.push(dialog);
}

void AppModalDialogQueue::ShowNextDialog() {
  AppModalDialog* dialog = GetNextDialog();
  if (dialog)
    ShowModalDialog(dialog);
  else
    active_dialog_ = NULL;
}

void AppModalDialogQueue::ActivateModalDialog() {
  if (showing_modal_dialog_) {
    // As part of showing a modal dialog we may end up back in this method
    // (showing a dialog activates the TabContents, which can trigger a call
    // to ActivateModalDialog). We ignore such a request as after the call to
    // activate the tab contents the dialog is shown.
    return;
  }
  if (active_dialog_)
    active_dialog_->ActivateModalDialog();
}

void AppModalDialogQueue::ShowModalDialog(AppModalDialog* dialog) {
  // Be sure and set the active_dialog_ field first, otherwise if
  // ShowModalDialog triggers a call back to the queue they'll get the old
  // dialog. Also, if the dialog calls |ShowNextDialog()| before returning, that
  // would write NULL into |active_dialog_| and this function would then undo
  // that.
  active_dialog_ = dialog;
  showing_modal_dialog_ = true;
  dialog->ShowModalDialog();
  showing_modal_dialog_ = false;
}

AppModalDialog* AppModalDialogQueue::GetNextDialog() {
  while (!app_modal_dialog_queue_.empty()) {
    AppModalDialog* dialog = app_modal_dialog_queue_.front();
    app_modal_dialog_queue_.pop();
    if (dialog->IsValid())
      return dialog;
    delete dialog;
  }
  return NULL;
}
<|endoftext|>


<commit_before>/*
Resembla
https://github.com/tuem/resembla

Copyright 2017 Takashi Uemura

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.
*/

#ifndef RESEMBLA_ELIMINATOR_HPP
#define RESEMBLA_ELIMINATOR_HPP

#include <string>
#include <vector>
#include <map>
#include <algorithm>

#ifdef DEBUG
#include <iostream>
#include "string_util.hpp"
#endif

namespace resembla {

template<
    typename string_type = std::string,
    typename bitvector_type = uint64_t,
    typename distance_type = long long
>
struct Eliminator
{
    using size_type = typename string_type::size_type;
    using symbol_type = typename string_type::value_type;

    Eliminator(const string_type& pattern)
    {
        this->pattern = pattern;
        if(pattern.empty()){
            return;
        }

        pattern_length = pattern.size();
        block_size = ((pattern_length - 1) >> bitOffset<bitvector_type>()) + 1;
        rest_bits = pattern_length - (block_size - 1) * bitWidth<bitvector_type>();
        sink = bitvector_type{1} << (rest_bits - 1);
        VP0 = (bitvector_type{1} << rest_bits) - 1;

        constructPM();
        zeroes.resize(block_size, 0);
        work.resize(block_size);
    }

    void operator()(std::vector<string_type>& candidates, size_type k, bool keep_tie = true)
    {
        using index_distance = std::pair<size_type, distance_type>;

        // calculate scores
        std::vector<index_distance> work(candidates.size());
        for(size_type i = 0; i < work.size(); ++i){
            work[i].first = i;
            work[i].second = distance(candidates[i]);
        }

        if(keep_tie){
            // sort partially to obtain top-k elements
            std::nth_element(std::begin(work), std::begin(work) + k, std::end(work),
                [](const index_distance& a, const index_distance& b) -> bool{
                    return a.second < b.second;
                });
        }
        else{
            std::sort(std::begin(work), std::end(work),
                [](const index_distance& a, const index_distance& b) -> bool{
                    return a.second < b.second;
                });
            // expand k so that work[l] < work[k] for all l > k
            while(k < work.size() - 1 && work[k] == work[k + 1]){
                ++k;
            }
        }

        // ensure that work[i].first < work[j].first if i < j < k
        std::sort(std::begin(work), std::begin(work) + k,
            [](const index_distance& a, const index_distance& b) -> bool{
                return a.first < b.first;
            });
#ifdef DEBUG
        std::cerr << "DEBUG: " << "eliminate " << work.size() << " strings" << std::endl;
        for(size_type i = 0; i < k; ++i){
            std::cerr << "DEBUG: " << cast_string<std::string>(candidates[work[i].first]) << ": " << work[i].second << std::endl;
        }
#endif

        // sort original list
        for(size_type i = 0; i < k; ++i){
            std::swap(candidates[i], candidates[work[i].first]);
        }
        candidates.erase(std::begin(candidates) + k, std::end(candidates));
    }

protected:
    string_type pattern;
    size_type pattern_length;
    symbol_type c_min, c_max;
    size_type block_size;
    size_type rest_bits;
    bitvector_type sink;
    bitvector_type VP0;

    std::vector<std::pair<symbol_type, std::vector<bitvector_type>>> PM;
    std::vector<bitvector_type> zeroes;

    struct WorkData
    {
        bitvector_type D0;
        bitvector_type HP;
        bitvector_type HN;
        bitvector_type VP;
        bitvector_type VN;

        void reset()
        {
            D0 = HP = HN = VN = 0;
            VP = ~(bitvector_type{0});
        }
    };
    std::vector<WorkData> work;

    template<typename Integer> static constexpr int bitWidth()
    {
        return 8 * sizeof(Integer);
    }

    static constexpr int bitOffset(int w)
    {
        return w < 2 ? 0 : (bitOffset(w >> 1) + 1);
    }

    template<typename Integer> static constexpr int bitOffset()
    {
        return bitOffset(bitWidth<Integer>());
    }

    template<typename key_type, typename value_type>
    const value_type& findValue(const std::vector<std::pair<key_type, value_type>>& data,
            const key_type c, const value_type& default_value) const
    {
        if(c < c_min || c_max < c){
            return default_value;
        }
        else if(c == c_min){
            return PM.front().second;
        }
        else if(c == c_max){
            return PM.back().second;
        }

        size_type l = 1, r = data.size() - 1;
        while(r - l > 8){
            auto i = (l + r) / 2;
            if(data[i].first < c){
                l = i + 1;
            }
            else if(data[i].first > c){
                r = i;
            }
            else{
                return data[i].second;
            }
        }

        for(size_type i = l; i < r; ++i){
            if(data[i].first == c){
                return data[i].second;
            }
        }

        return default_value;
    }

    void constructPM()
    {
        std::map<symbol_type, std::vector<bitvector_type>> PM_work;
        for(size_type i = 0; i < block_size - 1; ++i){
            for(size_type j = 0; j < bitWidth<bitvector_type>(); ++j){
                if(PM_work[pattern[i * bitWidth<bitvector_type>() + j]].empty()){
                    PM_work[pattern[i * bitWidth<bitvector_type>() + j]].resize(block_size, 0);
                }
                PM_work[pattern[i * bitWidth<bitvector_type>() + j]][i] |= bitvector_type{1} << j;
            }
        }
        for(size_type i = 0; i < rest_bits; ++i){
            if(PM_work[pattern[(block_size - 1) * bitWidth<bitvector_type>() + i]].empty()){
                PM_work[pattern[(block_size - 1) * bitWidth<bitvector_type>() + i]].resize(block_size, 0);
            }
            PM_work[pattern[(block_size - 1) * bitWidth<bitvector_type>() + i]].back() |= bitvector_type{1} << i;
        }

        PM.resize(PM_work.size());
        std::copy(std::begin(PM_work), std::end(PM_work), std::begin(PM));
        c_min = PM.front().first;
        c_max = PM.back().first;
    }

    distance_type distance_sp(const string_type& text)
    {
        auto& w = work.front();
        w.reset();
        w.VP = VP0;

        distance_type D = pattern_length;
        for(auto c: text){
            auto X = findValue(PM, c, zeroes).front() | w.VN;

            w.D0 = ((w.VP + (X & w.VP)) ^ w.VP) | X;
            w.HP = w.VN | ~(w.VP | w.D0);
            w.HN = w.VP & w.D0;

            X = (w.HP << 1) | 1;
            w.VP = (w.HN << 1) | ~(X | w.D0);
            w.VN = X & w.D0;

            if(w.HP & sink){
                ++D;
            }
            else if(w.HN & sink){
                --D;
            }
        }
        return D;
    }

    distance_type distance_lp(const string_type& text)
    {
        constexpr bitvector_type msb = bitvector_type{1} << (bitWidth<bitvector_type>() - 1);

        for(auto& w: work){
            w.reset();
        }
        work.back().VP = VP0;

        distance_type D = pattern_length;
        for(auto c: text){
            const auto& PMc = findValue(PM, c, zeroes);
            for(size_type r = 0; r < block_size; ++r){
                auto& w = work[r];
                auto X = PMc[r];
                if(r > 0 && (work[r - 1].HN & msb)){
                    X |= 1;
                }

                w.D0 = ((w.VP + (X & w.VP)) ^ w.VP) | X | w.VN;
                w.HP = w.VN | ~(w.VP | w.D0);
                w.HN = w.VP & w.D0;

                X = w.HP << 1;
                if(r == 0 || work[r - 1].HP & msb){
                    X |= 1;
                }
                w.VP = (w.HN << 1) | ~(X | w.D0);
                if(r > 0 && (work[r - 1].HN & msb)){
                    w.VP |= 1;
                }
                w.VN = X & w.D0;
            }

            if(work.back().HP & sink){
                ++D;
            }
            else if(work.back().HN & sink){
                --D;
            }
        }
        return D;
    }

    distance_type distance(const string_type& text)
    {
        if(text.empty()){
            return pattern_length;
        }
        else if(pattern_length == 0){
            return text.size();
        }

        if(block_size == 1){
            return distance_sp(text);
        }
        else{
            return distance_lp(text);
        }
    }
};

}
#endif
<commit_msg>use member initializer list<commit_after>/*
Resembla
https://github.com/tuem/resembla

Copyright 2017 Takashi Uemura

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.
*/

#ifndef RESEMBLA_ELIMINATOR_HPP
#define RESEMBLA_ELIMINATOR_HPP

#include <string>
#include <vector>
#include <map>
#include <algorithm>

#ifdef DEBUG
#include <iostream>
#include "string_util.hpp"
#endif

namespace resembla {

template<
    typename string_type = std::string,
    typename bitvector_type = uint64_t,
    typename distance_type = long long
>
struct Eliminator
{
    using size_type = typename string_type::size_type;
    using symbol_type = typename string_type::value_type;

    Eliminator(const string_type& pattern): pattern(pattern)
    {
        if(pattern.empty()){
            return;
        }

        pattern_length = pattern.size();
        block_size = ((pattern_length - 1) >> bitOffset<bitvector_type>()) + 1;
        rest_bits = pattern_length - (block_size - 1) * bitWidth<bitvector_type>();
        sink = bitvector_type{1} << (rest_bits - 1);
        VP0 = (bitvector_type{1} << rest_bits) - 1;

        constructPM();
        zeroes.resize(block_size, 0);
        work.resize(block_size);
    }

    void operator()(std::vector<string_type>& candidates, size_type k, bool keep_tie = true)
    {
        using index_distance = std::pair<size_type, distance_type>;

        // calculate scores
        std::vector<index_distance> work(candidates.size());
        for(size_type i = 0; i < work.size(); ++i){
            work[i].first = i;
            work[i].second = distance(candidates[i]);
        }

        if(keep_tie){
            // sort partially to obtain top-k elements
            std::nth_element(std::begin(work), std::begin(work) + k, std::end(work),
                [](const index_distance& a, const index_distance& b) -> bool{
                    return a.second < b.second;
                });
        }
        else{
            std::sort(std::begin(work), std::end(work),
                [](const index_distance& a, const index_distance& b) -> bool{
                    return a.second < b.second;
                });
            // expand k so that work[l] < work[k] for all l > k
            while(k < work.size() - 1 && work[k] == work[k + 1]){
                ++k;
            }
        }

        // ensure that work[i].first < work[j].first if i < j < k
        std::sort(std::begin(work), std::begin(work) + k,
            [](const index_distance& a, const index_distance& b) -> bool{
                return a.first < b.first;
            });
#ifdef DEBUG
        std::cerr << "DEBUG: " << "eliminate " << work.size() << " strings" << std::endl;
        for(size_type i = 0; i < k; ++i){
            std::cerr << "DEBUG: " << cast_string<std::string>(candidates[work[i].first]) << ": " << work[i].second << std::endl;
        }
#endif

        // sort original list
        for(size_type i = 0; i < k; ++i){
            std::swap(candidates[i], candidates[work[i].first]);
        }
        candidates.erase(std::begin(candidates) + k, std::end(candidates));
    }

protected:
    string_type pattern;
    size_type pattern_length;
    symbol_type c_min, c_max;
    size_type block_size;
    size_type rest_bits;
    bitvector_type sink;
    bitvector_type VP0;

    std::vector<std::pair<symbol_type, std::vector<bitvector_type>>> PM;
    std::vector<bitvector_type> zeroes;

    struct WorkData
    {
        bitvector_type D0;
        bitvector_type HP;
        bitvector_type HN;
        bitvector_type VP;
        bitvector_type VN;

        void reset()
        {
            D0 = HP = HN = VN = 0;
            VP = ~(bitvector_type{0});
        }
    };
    std::vector<WorkData> work;

    template<typename Integer> static constexpr int bitWidth()
    {
        return 8 * sizeof(Integer);
    }

    static constexpr int bitOffset(int w)
    {
        return w < 2 ? 0 : (bitOffset(w >> 1) + 1);
    }

    template<typename Integer> static constexpr int bitOffset()
    {
        return bitOffset(bitWidth<Integer>());
    }

    template<typename key_type, typename value_type>
    const value_type& findValue(const std::vector<std::pair<key_type, value_type>>& data,
            const key_type c, const value_type& default_value) const
    {
        if(c < c_min || c_max < c){
            return default_value;
        }
        else if(c == c_min){
            return PM.front().second;
        }
        else if(c == c_max){
            return PM.back().second;
        }

        size_type l = 1, r = data.size() - 1;
        while(r - l > 8){
            auto i = (l + r) / 2;
            if(data[i].first < c){
                l = i + 1;
            }
            else if(data[i].first > c){
                r = i;
            }
            else{
                return data[i].second;
            }
        }

        for(size_type i = l; i < r; ++i){
            if(data[i].first == c){
                return data[i].second;
            }
        }

        return default_value;
    }

    void constructPM()
    {
        std::map<symbol_type, std::vector<bitvector_type>> PM_work;
        for(size_type i = 0; i < block_size - 1; ++i){
            for(size_type j = 0; j < bitWidth<bitvector_type>(); ++j){
                if(PM_work[pattern[i * bitWidth<bitvector_type>() + j]].empty()){
                    PM_work[pattern[i * bitWidth<bitvector_type>() + j]].resize(block_size, 0);
                }
                PM_work[pattern[i * bitWidth<bitvector_type>() + j]][i] |= bitvector_type{1} << j;
            }
        }
        for(size_type i = 0; i < rest_bits; ++i){
            if(PM_work[pattern[(block_size - 1) * bitWidth<bitvector_type>() + i]].empty()){
                PM_work[pattern[(block_size - 1) * bitWidth<bitvector_type>() + i]].resize(block_size, 0);
            }
            PM_work[pattern[(block_size - 1) * bitWidth<bitvector_type>() + i]].back() |= bitvector_type{1} << i;
        }

        PM.resize(PM_work.size());
        std::copy(std::begin(PM_work), std::end(PM_work), std::begin(PM));
        c_min = PM.front().first;
        c_max = PM.back().first;
    }

    distance_type distance_sp(const string_type& text)
    {
        auto& w = work.front();
        w.reset();
        w.VP = VP0;

        distance_type D = pattern_length;
        for(auto c: text){
            auto X = findValue(PM, c, zeroes).front() | w.VN;

            w.D0 = ((w.VP + (X & w.VP)) ^ w.VP) | X;
            w.HP = w.VN | ~(w.VP | w.D0);
            w.HN = w.VP & w.D0;

            X = (w.HP << 1) | 1;
            w.VP = (w.HN << 1) | ~(X | w.D0);
            w.VN = X & w.D0;

            if(w.HP & sink){
                ++D;
            }
            else if(w.HN & sink){
                --D;
            }
        }
        return D;
    }

    distance_type distance_lp(const string_type& text)
    {
        constexpr bitvector_type msb = bitvector_type{1} << (bitWidth<bitvector_type>() - 1);

        for(auto& w: work){
            w.reset();
        }
        work.back().VP = VP0;

        distance_type D = pattern_length;
        for(auto c: text){
            const auto& PMc = findValue(PM, c, zeroes);
            for(size_type r = 0; r < block_size; ++r){
                auto& w = work[r];
                auto X = PMc[r];
                if(r > 0 && (work[r - 1].HN & msb)){
                    X |= 1;
                }

                w.D0 = ((w.VP + (X & w.VP)) ^ w.VP) | X | w.VN;
                w.HP = w.VN | ~(w.VP | w.D0);
                w.HN = w.VP & w.D0;

                X = w.HP << 1;
                if(r == 0 || work[r - 1].HP & msb){
                    X |= 1;
                }
                w.VP = (w.HN << 1) | ~(X | w.D0);
                if(r > 0 && (work[r - 1].HN & msb)){
                    w.VP |= 1;
                }
                w.VN = X & w.D0;
            }

            if(work.back().HP & sink){
                ++D;
            }
            else if(work.back().HN & sink){
                --D;
            }
        }
        return D;
    }

    distance_type distance(const string_type& text)
    {
        if(text.empty()){
            return pattern_length;
        }
        else if(pattern_length == 0){
            return text.size();
        }

        if(block_size == 1){
            return distance_sp(text);
        }
        else{
            return distance_lp(text);
        }
    }
};

}
#endif
<|endoftext|>


<commit_before>#include "heap.h"

#include <iostream>

Heap::Heap(size_t timestamp, size_t id, std::string type, std::string name)
    : MemoryObject(timestamp, 0, 0, 0), id_(id), type_(type), name_(name)
{

}

Heap::~Heap() {
    //maps manages themselves
}

void Heap::printContent() const {
    std::cout << "printing content for heap " << id_ << " of type: "<< type_.c_str() << "\n";
    for(auto it = cores_.begin(); it != cores_.end(); ++it) {
        it->second.printContent();
    }
}

Core* Heap::getCore(size_t pointer) {
    auto found = cores_.find(pointer);
    if(found == cores_.end()) {
        return nullptr;
    }
    return (&found->second);
}

Core* Heap::getCoreForAllocation(size_t pointer) {
    auto found = alloc_to_core.find(pointer);
    if(found == alloc_to_core.end()) {
        return nullptr;
    }
    return getCore(found->second);
}

bool Heap::removeCore(size_t timestamp, size_t pointer) {
    auto it = cores_.find(pointer);
    if(it == cores_.end()) {
        std::cout << "remove Core failed in heap " << id_ << std::endl;
        return false;
    }
    size_t managed = it->second.getManagedSize();
    managed_memory_ -= managed;
    cores_.erase(it);
    return true;
}

bool Heap::addCore(size_t timestamp, size_t pointer, size_t managed_size) {
    Core c(timestamp, pointer, managed_size);
    auto emp = cores_.insert(std::make_pair(pointer, c));
    if(!emp.second) {
        std::cout << "tryint to add already existing core: " << std::hex << pointer << std::dec << std::endl;
        return false;
    }
    managed_memory_ += managed_size;
    return true;
}

bool Heap::growCore(size_t timestamp, size_t pointer, size_t size) {
    Core* core = getCore(pointer);
    if(core != nullptr) {
        core->grow(size);
        return true;
    }
    return false;
}

bool Heap::shrinkCore(size_t timestamp, size_t pointer, size_t size) {
    Core* core = getCore(pointer);
    if(core != nullptr) {
        core->shrink(size);
        return true;
    }
    return false;
}

bool Heap::addAllocation(size_t timestamp, size_t pointer, size_t size) {
        for(auto it = cores_.begin(); it != cores_.end(); ++it) {
            if(it->second.addAllocation(timestamp, pointer, size)) {
                alloc_to_core.emplace_hint(alloc_to_core.cend(), pointer,it->second.getPointer());
                used_memory_ += size;
                simple_allocation_events_[timestamp] = heap_usage(used_memory_, managed_memory_);
                return true;
            }
        }
        //does the allocation span over two cores?
        for(auto it = cores_.begin(); it != cores_.end(); ++it) {
            auto next = std::next(it);
            if(next != cores_.end()) {
                if(it->second.pointerInside(pointer) && next->second.pointerInside(pointer + size)) {
                    it->second.addAllocation(timestamp,pointer,size, true);
                    alloc_to_core.emplace_hint(alloc_to_core.cend(), pointer,it->second.getPointer());
                    used_memory_ += size;
                    simple_allocation_events_[timestamp] = heap_usage(used_memory_, managed_memory_);
                    return true;
                }
            }
        }
        std::cout << "did not find a core for allocation in heap: " << id_ << " pointer: " << std::hex << pointer << std::dec << " size: " << size << " at timestamp " << timestamp << "\n";
    return false;
}

bool Heap::removeAllocation(size_t timestamp, size_t pointer) {
    Core* core = getCoreForAllocation(pointer);
    if(core == nullptr) {
        std::cout << "core was null for: " << std::hex << pointer << std::dec << "at " << timestamp << std::endl;
        printContent();
        return false;
    }
    size_t removed_memory = core->removeAllocation(timestamp, pointer);
    alloc_to_core.erase(pointer);
    used_memory_ -= removed_memory;
    simple_allocation_events_[timestamp] = heap_usage(used_memory_, managed_memory_);
    return true;
}

bool Heap::setBackingAllocator(size_t alloc) {
    backing_allocator_ids.push_back(alloc);
    return true;
}

void Heap::printBacking() {
    for(int i = 0; i < backing_allocator_ids.size(); ++i) {
        std::cout << " " << backing_allocator_ids[i];
    }
}<commit_msg>grow and shrink core now properly updates managed_memory<commit_after>#include "heap.h"

#include <iostream>

Heap::Heap(size_t timestamp, size_t id, std::string type, std::string name)
    : MemoryObject(timestamp, 0, 0, 0), id_(id), type_(type), name_(name)
{

}

Heap::~Heap() {
    //maps manages themselves
}

void Heap::printContent() const {
    std::cout << "printing content for heap " << id_ << " of type: "<< type_.c_str() << "\n";
    for(auto it = cores_.begin(); it != cores_.end(); ++it) {
        it->second.printContent();
    }
}

Core* Heap::getCore(size_t pointer) {
    auto found = cores_.find(pointer);
    if(found == cores_.end()) {
        return nullptr;
    }
    return (&found->second);
}

Core* Heap::getCoreForAllocation(size_t pointer) {
    auto found = alloc_to_core.find(pointer);
    if(found == alloc_to_core.end()) {
        return nullptr;
    }
    return getCore(found->second);
}

bool Heap::removeCore(size_t timestamp, size_t pointer) {
    auto it = cores_.find(pointer);
    if(it == cores_.end()) {
        std::cout << "remove Core failed in heap " << id_ << std::endl;
        return false;
    }
    size_t managed = it->second.getManagedSize();
    managed_memory_ -= managed;
    cores_.erase(it);
    return true;
}

bool Heap::addCore(size_t timestamp, size_t pointer, size_t managed_size) {
    Core c(timestamp, pointer, managed_size);
    auto emp = cores_.insert(std::make_pair(pointer, c));
    if(!emp.second) {
        std::cout << "tryint to add already existing core: " << std::hex << pointer << std::dec << std::endl;
        return false;
    }
    managed_memory_ += managed_size;
    return true;
}

bool Heap::growCore(size_t timestamp, size_t pointer, size_t size) {
    Core* core = getCore(pointer);
    if(core != nullptr) {
        core->grow(size);
        managed_memory_ += size;
        return true;
    }
    return false;
}

bool Heap::shrinkCore(size_t timestamp, size_t pointer, size_t size) {
    Core* core = getCore(pointer);
    if(core != nullptr) {
        core->shrink(size);
        managed_memory_ -= size;
        return true;
    }
    return false;
}

bool Heap::addAllocation(size_t timestamp, size_t pointer, size_t size) {
        for(auto it = cores_.begin(); it != cores_.end(); ++it) {
            if(it->second.addAllocation(timestamp, pointer, size)) {
                alloc_to_core.emplace_hint(alloc_to_core.cend(), pointer,it->second.getPointer());
                used_memory_ += size;
                simple_allocation_events_[timestamp] = heap_usage(used_memory_, managed_memory_);
                return true;
            }
        }
        //does the allocation span over two cores?
        for(auto it = cores_.begin(); it != cores_.end(); ++it) {
            auto next = std::next(it);
            if(next != cores_.end()) {
                if(it->second.pointerInside(pointer) && next->second.pointerInside(pointer + size)) {
                    it->second.addAllocation(timestamp,pointer,size, true);
                    alloc_to_core.emplace_hint(alloc_to_core.cend(), pointer,it->second.getPointer());
                    used_memory_ += size;
                    simple_allocation_events_[timestamp] = heap_usage(used_memory_, managed_memory_);
                    return true;
                }
            }
        }
        std::cout << "did not find a core for allocation in heap: " << id_ << " pointer: " << std::hex << pointer << std::dec << " size: " << size << " at timestamp " << timestamp << "\n";
    return false;
}

bool Heap::removeAllocation(size_t timestamp, size_t pointer) {
    Core* core = getCoreForAllocation(pointer);
    if(core == nullptr) {
        std::cout << "core was null for: " << std::hex << pointer << std::dec << "at " << timestamp << std::endl;
        printContent();
        return false;
    }
    size_t removed_memory = core->removeAllocation(timestamp, pointer);
    alloc_to_core.erase(pointer);
    used_memory_ -= removed_memory;
    simple_allocation_events_[timestamp] = heap_usage(used_memory_, managed_memory_);
    return true;
}

bool Heap::setBackingAllocator(size_t alloc) {
    backing_allocator_ids.push_back(alloc);
    return true;
}

void Heap::printBacking() {
    for(int i = 0; i < backing_allocator_ids.size(); ++i) {
        std::cout << " " << backing_allocator_ids[i];
    }
}<|endoftext|>


<commit_before>//===- Printer.cpp - Code for printing data structure graphs nicely -------===//
//
// This file implements the 'dot' graph printer.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/DataStructure.h"
#include "llvm/Analysis/DSGraph.h"
#include "llvm/Analysis/DSGraphTraits.h"
#include "llvm/Module.h"
#include "llvm/Assembly/Writer.h"
#include "Support/CommandLine.h"
#include "Support/GraphWriter.h"
#include "Support/Statistic.h"
#include <fstream>
#include <sstream>

// OnlyPrintMain - The DataStructure printer exposes this option to allow
// printing of only the graph for "main".
//
namespace {
  cl::opt<bool> OnlyPrintMain("only-print-main-ds", cl::ReallyHidden);
  Statistic<> MaxGraphSize   ("dsnode", "Maximum graph size");
  Statistic<> NumFoldedNodes ("dsnode", "Number of folded nodes (in final graph)");
}

void DSNode::dump() const { print(std::cerr, 0); }

static std::string getCaption(const DSNode *N, const DSGraph *G) {
  std::stringstream OS;
  Module *M = 0;
  // Get the module from ONE of the functions in the graph it is available.
  if (G && !G->getReturnNodes().empty())
    M = G->getReturnNodes().begin()->first->getParent();

  if (N->isNodeCompletelyFolded())
    OS << "FOLDED";
  else {
    WriteTypeSymbolic(OS, N->getType(), M);
    if (N->isArray())
      OS << " array";
  }
  if (unsigned NodeType = N->getNodeFlags()) {
    OS << ": ";
    if (NodeType & DSNode::AllocaNode ) OS << "S";
    if (NodeType & DSNode::HeapNode   ) OS << "H";
    if (NodeType & DSNode::GlobalNode ) OS << "G";
    if (NodeType & DSNode::UnknownNode) OS << "U";
    if (NodeType & DSNode::Incomplete ) OS << "I";
    if (NodeType & DSNode::Modified   ) OS << "M";
    if (NodeType & DSNode::Read       ) OS << "R";
#ifndef NDEBUG
    if (NodeType & DSNode::DEAD       ) OS << "<dead>";
#endif
    OS << "\n";
  }

  for (unsigned i = 0, e = N->getGlobals().size(); i != e; ++i) {
    WriteAsOperand(OS, N->getGlobals()[i], false, true, M);
    OS << "\n";
  }

  return OS.str();
}

template<>
struct DOTGraphTraits<const DSGraph*> : public DefaultDOTGraphTraits {
  static std::string getGraphName(const DSGraph *G) {
    switch (G->getReturnNodes().size()) {
    case 0: return G->getFunctionNames();
    case 1: return "Function " + G->getFunctionNames();
    default: return "Functions: " + G->getFunctionNames();
    }
  }

  static const char *getGraphProperties(const DSGraph *G) {
    return "\tsize=\"10,7.5\";\n"
           "\trotate=\"90\";\n";
  }

  static std::string getNodeLabel(const DSNode *Node, const DSGraph *Graph) {
    return getCaption(Node, Graph);
  }

  static std::string getNodeAttributes(const DSNode *N) {
    return "shape=Mrecord";//fontname=Courier";
  }

  /// addCustomGraphFeatures - Use this graph writing hook to emit call nodes
  /// and the return node.
  ///
  static void addCustomGraphFeatures(const DSGraph *G,
                                     GraphWriter<const DSGraph*> &GW) {
    Module *CurMod = 0;
    if (!G->getReturnNodes().empty())
      CurMod = G->getReturnNodes().begin()->first->getParent();

    // Add scalar nodes to the graph...
    const DSGraph::ScalarMapTy &VM = G->getScalarMap();
    for (DSGraph::ScalarMapTy::const_iterator I = VM.begin(); I != VM.end();++I)
      if (!isa<GlobalValue>(I->first)) {
        std::stringstream OS;
        WriteAsOperand(OS, I->first, false, true, CurMod);
        GW.emitSimpleNode(I->first, "", OS.str());

        // Add edge from return node to real destination
        int EdgeDest = I->second.getOffset() >> DS::PointerShift;
        if (EdgeDest == 0) EdgeDest = -1;
        GW.emitEdge(I->first, -1, I->second.getNode(),
                    EdgeDest, "arrowtail=tee,color=gray63");
      }

    // Output the returned value pointer...
    const DSGraph::ReturnNodesTy &RetNodes = G->getReturnNodes();
    for (DSGraph::ReturnNodesTy::const_iterator I = RetNodes.begin(),
           E = RetNodes.end(); I != E; ++I)
      if (I->second.getNode()) {
        std::string Label;
        if (RetNodes.size() == 1)
          Label = "returning";
        else
          Label = I->first->getName() + " ret node";
        // Output the return node...
        GW.emitSimpleNode((void*)1, "plaintext=circle", Label);

        // Add edge from return node to real destination
        int RetEdgeDest = I->second.getOffset() >> DS::PointerShift;;
        if (RetEdgeDest == 0) RetEdgeDest = -1;
        GW.emitEdge((void*)1, -1, I->second.getNode(),
                    RetEdgeDest, "arrowtail=tee,color=gray63");
      }

    // Output all of the call nodes...
    const std::vector<DSCallSite> &FCs =
      G->shouldPrintAuxCalls() ? G->getAuxFunctionCalls()
      : G->getFunctionCalls();
    for (unsigned i = 0, e = FCs.size(); i != e; ++i) {
      const DSCallSite &Call = FCs[i];
      std::vector<std::string> EdgeSourceCaptions(Call.getNumPtrArgs()+2);
      EdgeSourceCaptions[0] = "r";
      if (Call.isDirectCall())
        EdgeSourceCaptions[1] = Call.getCalleeFunc()->getName();
      else
        EdgeSourceCaptions[1] = "f";

      GW.emitSimpleNode(&Call, "shape=record", "call", Call.getNumPtrArgs()+2,
                        &EdgeSourceCaptions);

      if (DSNode *N = Call.getRetVal().getNode()) {
        int EdgeDest = Call.getRetVal().getOffset() >> DS::PointerShift;
        if (EdgeDest == 0) EdgeDest = -1;
        GW.emitEdge(&Call, 0, N, EdgeDest, "color=gray63,tailclip=false");
      }

      // Print out the callee...
      if (Call.isIndirectCall()) {
        DSNode *N = Call.getCalleeNode();
        assert(N && "Null call site callee node!");
        GW.emitEdge(&Call, 1, N, -1, "color=gray63,tailclip=false");
      }

      for (unsigned j = 0, e = Call.getNumPtrArgs(); j != e; ++j)
        if (DSNode *N = Call.getPtrArg(j).getNode()) {
          int EdgeDest = Call.getPtrArg(j).getOffset() >> DS::PointerShift;
          if (EdgeDest == 0) EdgeDest = -1;
          GW.emitEdge(&Call, j+2, N, EdgeDest, "color=gray63,tailclip=false");
        }
    }
  }
};

void DSNode::print(std::ostream &O, const DSGraph *G) const {
  GraphWriter<const DSGraph *> W(O, G);
  W.writeNode(this);
}

void DSGraph::print(std::ostream &O) const {
  WriteGraph(O, this, "DataStructures");
}

void DSGraph::writeGraphToFile(std::ostream &O,
                               const std::string &GraphName) const {
  std::string Filename = GraphName + ".dot";
  O << "Writing '" << Filename << "'...";
  std::ofstream F(Filename.c_str());

  if (F.good()) {
    print(F);
    unsigned NumCalls = shouldPrintAuxCalls() ?
      getAuxFunctionCalls().size() : getFunctionCalls().size();
    O << " [" << getGraphSize() << "+" << NumCalls << "]\n";
  } else {
    O << "  error opening file for writing!\n";
  }
}

/// viewGraph - Emit a dot graph, run 'dot', run gv on the postscript file,
/// then cleanup.  For use from the debugger.
///
void DSGraph::viewGraph() const {
  std::ofstream F("/tmp/tempgraph.dot");
  if (!F.good()) {
    std::cerr << "Error opening '/tmp/tempgraph.dot' for temporary graph!\n";
    return;
  }
  print(F);
  F.close();
  if (system("dot -Tps /tmp/tempgraph.dot > /tmp/tempgraph.ps"))
    std::cerr << "Error running dot: 'dot' not in path?\n";
  system("gv /tmp/tempgraph.ps");
  system("rm /tmp/tempgraph.dot /tmp/tempgraph.ps");
}

template <typename Collection>
static void printCollection(const Collection &C, std::ostream &O,
                            const Module *M, const std::string &Prefix) {
  if (M == 0) {
    O << "Null Module pointer, cannot continue!\n";
    return;
  }

  unsigned TotalNumNodes = 0, TotalCallNodes = 0;
  for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
    if (C.hasGraph(*I)) {
      DSGraph &Gr = C.getDSGraph((Function&)*I);
      TotalNumNodes += Gr.getGraphSize();
      unsigned NumCalls = Gr.shouldPrintAuxCalls() ?
        Gr.getAuxFunctionCalls().size() : Gr.getFunctionCalls().size();

      TotalCallNodes += NumCalls;
      if (I->getName() == "main" || !OnlyPrintMain)
        Gr.writeGraphToFile(O, Prefix+I->getName());
      else {
        O << "Skipped Writing '" << Prefix+I->getName() << ".dot'... ["
          << Gr.getGraphSize() << "+" << NumCalls << "]\n";
      }

      if (MaxGraphSize < Gr.getNodes().size())
        MaxGraphSize = Gr.getNodes().size();
      for (unsigned i = 0, e = Gr.getNodes().size(); i != e; ++i)
        if (Gr.getNodes()[i]->isNodeCompletelyFolded())
          ++NumFoldedNodes;
    }

  DSGraph &GG = C.getGlobalsGraph();
  TotalNumNodes  += GG.getGraphSize();
  TotalCallNodes += GG.getFunctionCalls().size();
  if (!OnlyPrintMain) {
    GG.writeGraphToFile(O, Prefix+"GlobalsGraph");
  } else {
    O << "Skipped Writing '" << Prefix << "GlobalsGraph.dot'... ["
      << GG.getGraphSize() << "+" << GG.getFunctionCalls().size() << "]\n";
  }

  O << "\nGraphs contain [" << TotalNumNodes << "+" << TotalCallNodes
    << "] nodes total" << std::endl;
}

// print - Print out the analysis results...
void LocalDataStructures::print(std::ostream &O, const Module *M) const {
  printCollection(*this, O, M, "ds.");
}

void BUDataStructures::print(std::ostream &O, const Module *M) const {
  printCollection(*this, O, M, "bu.");
}

void TDDataStructures::print(std::ostream &O, const Module *M) const {
  printCollection(*this, O, M, "td.");
}
<commit_msg>Dont' print scalar nodes for ConstantPointerRefs<commit_after>//===- Printer.cpp - Code for printing data structure graphs nicely -------===//
//
// This file implements the 'dot' graph printer.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/DataStructure.h"
#include "llvm/Analysis/DSGraph.h"
#include "llvm/Analysis/DSGraphTraits.h"
#include "llvm/Module.h"
#include "llvm/Constants.h"
#include "llvm/Assembly/Writer.h"
#include "Support/CommandLine.h"
#include "Support/GraphWriter.h"
#include "Support/Statistic.h"
#include <fstream>
#include <sstream>

// OnlyPrintMain - The DataStructure printer exposes this option to allow
// printing of only the graph for "main".
//
namespace {
  cl::opt<bool> OnlyPrintMain("only-print-main-ds", cl::ReallyHidden);
  Statistic<> MaxGraphSize   ("dsnode", "Maximum graph size");
  Statistic<> NumFoldedNodes ("dsnode", "Number of folded nodes (in final graph)");
}

void DSNode::dump() const { print(std::cerr, 0); }

static std::string getCaption(const DSNode *N, const DSGraph *G) {
  std::stringstream OS;
  Module *M = 0;
  // Get the module from ONE of the functions in the graph it is available.
  if (G && !G->getReturnNodes().empty())
    M = G->getReturnNodes().begin()->first->getParent();

  if (N->isNodeCompletelyFolded())
    OS << "FOLDED";
  else {
    WriteTypeSymbolic(OS, N->getType(), M);
    if (N->isArray())
      OS << " array";
  }
  if (unsigned NodeType = N->getNodeFlags()) {
    OS << ": ";
    if (NodeType & DSNode::AllocaNode ) OS << "S";
    if (NodeType & DSNode::HeapNode   ) OS << "H";
    if (NodeType & DSNode::GlobalNode ) OS << "G";
    if (NodeType & DSNode::UnknownNode) OS << "U";
    if (NodeType & DSNode::Incomplete ) OS << "I";
    if (NodeType & DSNode::Modified   ) OS << "M";
    if (NodeType & DSNode::Read       ) OS << "R";
#ifndef NDEBUG
    if (NodeType & DSNode::DEAD       ) OS << "<dead>";
#endif
    OS << "\n";
  }

  for (unsigned i = 0, e = N->getGlobals().size(); i != e; ++i) {
    WriteAsOperand(OS, N->getGlobals()[i], false, true, M);
    OS << "\n";
  }

  return OS.str();
}

template<>
struct DOTGraphTraits<const DSGraph*> : public DefaultDOTGraphTraits {
  static std::string getGraphName(const DSGraph *G) {
    switch (G->getReturnNodes().size()) {
    case 0: return G->getFunctionNames();
    case 1: return "Function " + G->getFunctionNames();
    default: return "Functions: " + G->getFunctionNames();
    }
  }

  static const char *getGraphProperties(const DSGraph *G) {
    return "\tsize=\"10,7.5\";\n"
           "\trotate=\"90\";\n";
  }

  static std::string getNodeLabel(const DSNode *Node, const DSGraph *Graph) {
    return getCaption(Node, Graph);
  }

  static std::string getNodeAttributes(const DSNode *N) {
    return "shape=Mrecord";//fontname=Courier";
  }

  /// addCustomGraphFeatures - Use this graph writing hook to emit call nodes
  /// and the return node.
  ///
  static void addCustomGraphFeatures(const DSGraph *G,
                                     GraphWriter<const DSGraph*> &GW) {
    Module *CurMod = 0;
    if (!G->getReturnNodes().empty())
      CurMod = G->getReturnNodes().begin()->first->getParent();

    // Add scalar nodes to the graph...
    const DSGraph::ScalarMapTy &VM = G->getScalarMap();
    for (DSGraph::ScalarMapTy::const_iterator I = VM.begin(); I != VM.end();++I)
      if (!isa<GlobalValue>(I->first) && !isa<ConstantPointerRef>(I->first)) {
        std::stringstream OS;
        WriteAsOperand(OS, I->first, false, true, CurMod);
        GW.emitSimpleNode(I->first, "", OS.str());

        // Add edge from return node to real destination
        int EdgeDest = I->second.getOffset() >> DS::PointerShift;
        if (EdgeDest == 0) EdgeDest = -1;
        GW.emitEdge(I->first, -1, I->second.getNode(),
                    EdgeDest, "arrowtail=tee,color=gray63");
      }

    // Output the returned value pointer...
    const DSGraph::ReturnNodesTy &RetNodes = G->getReturnNodes();
    for (DSGraph::ReturnNodesTy::const_iterator I = RetNodes.begin(),
           E = RetNodes.end(); I != E; ++I)
      if (I->second.getNode()) {
        std::string Label;
        if (RetNodes.size() == 1)
          Label = "returning";
        else
          Label = I->first->getName() + " ret node";
        // Output the return node...
        GW.emitSimpleNode((void*)1, "plaintext=circle", Label);

        // Add edge from return node to real destination
        int RetEdgeDest = I->second.getOffset() >> DS::PointerShift;;
        if (RetEdgeDest == 0) RetEdgeDest = -1;
        GW.emitEdge((void*)1, -1, I->second.getNode(),
                    RetEdgeDest, "arrowtail=tee,color=gray63");
      }

    // Output all of the call nodes...
    const std::vector<DSCallSite> &FCs =
      G->shouldPrintAuxCalls() ? G->getAuxFunctionCalls()
      : G->getFunctionCalls();
    for (unsigned i = 0, e = FCs.size(); i != e; ++i) {
      const DSCallSite &Call = FCs[i];
      std::vector<std::string> EdgeSourceCaptions(Call.getNumPtrArgs()+2);
      EdgeSourceCaptions[0] = "r";
      if (Call.isDirectCall())
        EdgeSourceCaptions[1] = Call.getCalleeFunc()->getName();
      else
        EdgeSourceCaptions[1] = "f";

      GW.emitSimpleNode(&Call, "shape=record", "call", Call.getNumPtrArgs()+2,
                        &EdgeSourceCaptions);

      if (DSNode *N = Call.getRetVal().getNode()) {
        int EdgeDest = Call.getRetVal().getOffset() >> DS::PointerShift;
        if (EdgeDest == 0) EdgeDest = -1;
        GW.emitEdge(&Call, 0, N, EdgeDest, "color=gray63,tailclip=false");
      }

      // Print out the callee...
      if (Call.isIndirectCall()) {
        DSNode *N = Call.getCalleeNode();
        assert(N && "Null call site callee node!");
        GW.emitEdge(&Call, 1, N, -1, "color=gray63,tailclip=false");
      }

      for (unsigned j = 0, e = Call.getNumPtrArgs(); j != e; ++j)
        if (DSNode *N = Call.getPtrArg(j).getNode()) {
          int EdgeDest = Call.getPtrArg(j).getOffset() >> DS::PointerShift;
          if (EdgeDest == 0) EdgeDest = -1;
          GW.emitEdge(&Call, j+2, N, EdgeDest, "color=gray63,tailclip=false");
        }
    }
  }
};

void DSNode::print(std::ostream &O, const DSGraph *G) const {
  GraphWriter<const DSGraph *> W(O, G);
  W.writeNode(this);
}

void DSGraph::print(std::ostream &O) const {
  WriteGraph(O, this, "DataStructures");
}

void DSGraph::writeGraphToFile(std::ostream &O,
                               const std::string &GraphName) const {
  std::string Filename = GraphName + ".dot";
  O << "Writing '" << Filename << "'...";
  std::ofstream F(Filename.c_str());

  if (F.good()) {
    print(F);
    unsigned NumCalls = shouldPrintAuxCalls() ?
      getAuxFunctionCalls().size() : getFunctionCalls().size();
    O << " [" << getGraphSize() << "+" << NumCalls << "]\n";
  } else {
    O << "  error opening file for writing!\n";
  }
}

/// viewGraph - Emit a dot graph, run 'dot', run gv on the postscript file,
/// then cleanup.  For use from the debugger.
///
void DSGraph::viewGraph() const {
  std::ofstream F("/tmp/tempgraph.dot");
  if (!F.good()) {
    std::cerr << "Error opening '/tmp/tempgraph.dot' for temporary graph!\n";
    return;
  }
  print(F);
  F.close();
  if (system("dot -Tps /tmp/tempgraph.dot > /tmp/tempgraph.ps"))
    std::cerr << "Error running dot: 'dot' not in path?\n";
  system("gv /tmp/tempgraph.ps");
  system("rm /tmp/tempgraph.dot /tmp/tempgraph.ps");
}

template <typename Collection>
static void printCollection(const Collection &C, std::ostream &O,
                            const Module *M, const std::string &Prefix) {
  if (M == 0) {
    O << "Null Module pointer, cannot continue!\n";
    return;
  }

  unsigned TotalNumNodes = 0, TotalCallNodes = 0;
  for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
    if (C.hasGraph(*I)) {
      DSGraph &Gr = C.getDSGraph((Function&)*I);
      TotalNumNodes += Gr.getGraphSize();
      unsigned NumCalls = Gr.shouldPrintAuxCalls() ?
        Gr.getAuxFunctionCalls().size() : Gr.getFunctionCalls().size();

      TotalCallNodes += NumCalls;
      if (I->getName() == "main" || !OnlyPrintMain)
        Gr.writeGraphToFile(O, Prefix+I->getName());
      else {
        O << "Skipped Writing '" << Prefix+I->getName() << ".dot'... ["
          << Gr.getGraphSize() << "+" << NumCalls << "]\n";
      }

      if (MaxGraphSize < Gr.getNodes().size())
        MaxGraphSize = Gr.getNodes().size();
      for (unsigned i = 0, e = Gr.getNodes().size(); i != e; ++i)
        if (Gr.getNodes()[i]->isNodeCompletelyFolded())
          ++NumFoldedNodes;
    }

  DSGraph &GG = C.getGlobalsGraph();
  TotalNumNodes  += GG.getGraphSize();
  TotalCallNodes += GG.getFunctionCalls().size();
  if (!OnlyPrintMain) {
    GG.writeGraphToFile(O, Prefix+"GlobalsGraph");
  } else {
    O << "Skipped Writing '" << Prefix << "GlobalsGraph.dot'... ["
      << GG.getGraphSize() << "+" << GG.getFunctionCalls().size() << "]\n";
  }

  O << "\nGraphs contain [" << TotalNumNodes << "+" << TotalCallNodes
    << "] nodes total" << std::endl;
}

// print - Print out the analysis results...
void LocalDataStructures::print(std::ostream &O, const Module *M) const {
  printCollection(*this, O, M, "ds.");
}

void BUDataStructures::print(std::ostream &O, const Module *M) const {
  printCollection(*this, O, M, "bu.");
}

void TDDataStructures::print(std::ostream &O, const Module *M) const {
  printCollection(*this, O, M, "td.");
}
<|endoftext|>


<commit_before>//===- TypeHashing.cpp -------------------------------------------*- C++-*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/CodeView/TypeHashing.h"

#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
#include "llvm/Support/SHA1.h"

using namespace llvm;
using namespace llvm::codeview;

LocallyHashedType DenseMapInfo<LocallyHashedType>::Empty{0, {}};
LocallyHashedType DenseMapInfo<LocallyHashedType>::Tombstone{hash_code(-1), {}};

static std::array<uint8_t, 20> EmptyHash;
static std::array<uint8_t, 20> TombstoneHash = {
    0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

GloballyHashedType DenseMapInfo<GloballyHashedType>::Empty{EmptyHash};
GloballyHashedType DenseMapInfo<GloballyHashedType>::Tombstone{TombstoneHash};

LocallyHashedType LocallyHashedType::hashType(ArrayRef<uint8_t> RecordData) {
  return {llvm::hash_value(RecordData), RecordData};
}

GloballyHashedType
GloballyHashedType::hashType(ArrayRef<uint8_t> RecordData,
                             ArrayRef<GloballyHashedType> PreviousTypes,
                             ArrayRef<GloballyHashedType> PreviousIds) {
  SmallVector<TiReference, 4> Refs;
  discoverTypeIndices(RecordData, Refs);
  SHA1 S;
  S.init();
  uint32_t Off = 0;
  RecordData = RecordData.drop_front(sizeof(RecordPrefix));
  for (const auto &Ref : Refs) {
    // Hash any data that comes before this TiRef.
    uint32_t PreLen = Ref.Offset - Off;
    ArrayRef<uint8_t> PreData = RecordData.slice(Off, PreLen);
    S.update(PreData);
    auto Prev = (Ref.Kind == TiRefKind::IndexRef) ? PreviousIds : PreviousTypes;

    auto RefData = RecordData.slice(Ref.Offset, Ref.Count * sizeof(TypeIndex));
    // For each type index referenced, add in the previously computed hash
    // value of that type.
    ArrayRef<TypeIndex> Indices(
        reinterpret_cast<const TypeIndex *>(RefData.data()), Ref.Count);
    for (TypeIndex TI : Indices) {
      ArrayRef<uint8_t> BytesToHash;
      if (TI.isSimple() || TI.isNoneType()) {
        const uint8_t *IndexBytes = reinterpret_cast<const uint8_t *>(&TI);
        BytesToHash = makeArrayRef(IndexBytes, sizeof(TypeIndex));
      } else {
        BytesToHash = Prev[TI.toArrayIndex()].Hash;
      }
      S.update(BytesToHash);
    }

    Off = Ref.Offset + Ref.Count * sizeof(TypeIndex);
  }

  // Don't forget to add in any trailing bytes.
  auto TrailingBytes = RecordData.drop_front(Off);
  S.update(TrailingBytes);

  return {S.final()};
}
<commit_msg>Fix -Wmissing-braces error.<commit_after>//===- TypeHashing.cpp -------------------------------------------*- C++-*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/CodeView/TypeHashing.h"

#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
#include "llvm/Support/SHA1.h"

using namespace llvm;
using namespace llvm::codeview;

LocallyHashedType DenseMapInfo<LocallyHashedType>::Empty{0, {}};
LocallyHashedType DenseMapInfo<LocallyHashedType>::Tombstone{hash_code(-1), {}};

static std::array<uint8_t, 20> EmptyHash;
static std::array<uint8_t, 20> TombstoneHash = {
    {0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};

GloballyHashedType DenseMapInfo<GloballyHashedType>::Empty{EmptyHash};
GloballyHashedType DenseMapInfo<GloballyHashedType>::Tombstone{TombstoneHash};

LocallyHashedType LocallyHashedType::hashType(ArrayRef<uint8_t> RecordData) {
  return {llvm::hash_value(RecordData), RecordData};
}

GloballyHashedType
GloballyHashedType::hashType(ArrayRef<uint8_t> RecordData,
                             ArrayRef<GloballyHashedType> PreviousTypes,
                             ArrayRef<GloballyHashedType> PreviousIds) {
  SmallVector<TiReference, 4> Refs;
  discoverTypeIndices(RecordData, Refs);
  SHA1 S;
  S.init();
  uint32_t Off = 0;
  RecordData = RecordData.drop_front(sizeof(RecordPrefix));
  for (const auto &Ref : Refs) {
    // Hash any data that comes before this TiRef.
    uint32_t PreLen = Ref.Offset - Off;
    ArrayRef<uint8_t> PreData = RecordData.slice(Off, PreLen);
    S.update(PreData);
    auto Prev = (Ref.Kind == TiRefKind::IndexRef) ? PreviousIds : PreviousTypes;

    auto RefData = RecordData.slice(Ref.Offset, Ref.Count * sizeof(TypeIndex));
    // For each type index referenced, add in the previously computed hash
    // value of that type.
    ArrayRef<TypeIndex> Indices(
        reinterpret_cast<const TypeIndex *>(RefData.data()), Ref.Count);
    for (TypeIndex TI : Indices) {
      ArrayRef<uint8_t> BytesToHash;
      if (TI.isSimple() || TI.isNoneType()) {
        const uint8_t *IndexBytes = reinterpret_cast<const uint8_t *>(&TI);
        BytesToHash = makeArrayRef(IndexBytes, sizeof(TypeIndex));
      } else {
        BytesToHash = Prev[TI.toArrayIndex()].Hash;
      }
      S.update(BytesToHash);
    }

    Off = Ref.Offset + Ref.Count * sizeof(TypeIndex);
  }

  // Don't forget to add in any trailing bytes.
  auto TrailingBytes = RecordData.drop_front(Off);
  S.update(TrailingBytes);

  return {S.final()};
}
<|endoftext|>