<commit_before>/**
 * This file defines the `SyncSkeleton` class.
 */

#ifndef D2_SANDBOX_SYNC_SKELETON_HPP
#define D2_SANDBOX_SYNC_SKELETON_HPP

#include <d2/lock_graph.hpp>
#include <d2/sandbox/deadlock_diagnostic.hpp>
#include <d2/segmentation_graph.hpp>
#include <d2/thread_id.hpp>

#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <cstddef>
#include <iosfwd>
#include <iterator>
#include <set>
#include <vector>
#include <string>


namespace d2 {
namespace sandbox {

namespace detail {
    void parse_and_build_seg_graph(std::istream&, SegmentationGraph&);
    void parse_and_build_lock_graph(std::istream&, LockGraph&);
    std::vector<DeadlockDiagnostic>
    analyze_lock_ordering(LockGraph const&, SegmentationGraph const&);
} // end namespace detail

/**
 * Class representing a program stripped down from any other information than
 * the information related to synchronization.
 *
 * @internal We should probably define a very tiny DSEL to query the skeleton
 *           in flexible ways. For example, it is completely redundant to have
 *           a `total_number_of_locks` method AND a `number_of_locks_in`
 *           method. The `number_of_locks_in` method should be able to
 *           accept some kind of query representing a range of `coordinates'
 *           between which the number of locks is to be computed.
 */
template <typename Repository>
class SyncSkeleton {
    // Silence MSVC warning C4512: assignment operator could not be generated
    SyncSkeleton& operator=(SyncSkeleton const&) /*= delete*/;

    Repository& repository_;
    SegmentationGraph segmentation_graph_;
    LockGraph lock_graph_;

    /**
     * Build the lock graph and the segmentation graph from the events inside
     * a repository.
     */
    static void build_graphs(Repository& repo, LockGraph& lg,
                                                    SegmentationGraph& sg) {
        detail::parse_and_build_seg_graph(repo[Repository::process_wide], sg);

        typedef typename Repository::thread_stream_range ThreadStreams;
        ThreadStreams thread_streams = repo.thread_streams();
        typename ThreadStreams::iterator thread(boost::begin(thread_streams)),
                                         last(boost::end(thread_streams));
        for (; thread != last; ++thread)
            detail::parse_and_build_lock_graph(*thread, lg);
    }

#if 0
    /**
     * Structure holding the necessary information to locate a single event
     * within the execution of a program.
     */
    struct Coordinates {
        Process process;
        Thread thread;
        Segment segment;
    };
#endif

public:
    /**
     * Construct a skeleton from the data stored in a repository.
     *
     * @warning This may be a resource intensive operation since we have
     *          to load the content of the whole repository in memory to
     *          build two different graphs.
     */
    explicit SyncSkeleton(Repository& repo) : repository_(repo) {
        build_graphs(repository_, lock_graph_, segmentation_graph_);
    }

    /**
     * Return the number of threads spawned in the part of the program
     * captured by the skeleton.
     */
    std::size_t number_of_threads() const {
        return std::distance(boost::begin(repository_.threads()),
                             boost::end(repository_.threads()));
    }

    /**
     * Return the number of unique locks created in the part of the program
     * captured by the skeleton.
     */
    std::size_t number_of_locks() const {
        return num_vertices(lock_graph_);
    }

private:
    typedef typename Repository::template
                const_key_view<ThreadId>::type unspecified_range_of_threads;
    typedef std::vector<DeadlockDiagnostic> unspecified_range_of_diagnostics;

public:
    unspecified_range_of_threads threads() const {
        return repository_.template key_view<ThreadId>();
    }
<commit_msg>Fix compilation errors in the SyncSkeleton.<commit_after>/**
 * This file defines the `SyncSkeleton` class.
 */

#ifndef D2_SANDBOX_SYNC_SKELETON_HPP
#define D2_SANDBOX_SYNC_SKELETON_HPP

#include <d2/lock_graph.hpp>
#include <d2/sandbox/deadlock_diagnostic.hpp>
#include <d2/segmentation_graph.hpp>
#include <d2/thread_id.hpp>

#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <cstddef>
#include <iosfwd>
#include <iterator>
#include <set>
#include <vector>
#include <string>


namespace d2 {
namespace sandbox {

namespace detail {
    void parse_and_build_seg_graph(std::istream&, SegmentationGraph&);
    void parse_and_build_lock_graph(std::istream&, LockGraph&);
    std::vector<DeadlockDiagnostic>
    analyze_lock_ordering(LockGraph const&, SegmentationGraph const&);
} // end namespace detail

/**
 * Class representing a program stripped down from any other information than
 * the information related to synchronization.
 *
 * @internal We should probably define a very tiny DSEL to query the skeleton
 *           in flexible ways. For example, it is completely redundant to have
 *           a `total_number_of_locks` method AND a `number_of_locks_in`
 *           method. The `number_of_locks_in` method should be able to
 *           accept some kind of query representing a range of `coordinates'
 *           between which the number of locks is to be computed.
 */
template <typename Repository>
class SyncSkeleton {
    // Silence MSVC warning C4512: assignment operator could not be generated
    SyncSkeleton& operator=(SyncSkeleton const&) /*= delete*/;

    Repository& repository_;
    SegmentationGraph segmentation_graph_;
    LockGraph lock_graph_;

    /**
     * Build the lock graph and the segmentation graph from the events inside
     * a repository.
     */
    static void build_graphs(Repository& repo, LockGraph& lg,
                                                    SegmentationGraph& sg) {
        detail::parse_and_build_seg_graph(repo[Repository::process_wide], sg);

        typedef typename Repository::thread_stream_range ThreadStreams;
        ThreadStreams thread_streams = repo.thread_streams();
        typename ThreadStreams::iterator thread(boost::begin(thread_streams)),
                                         last(boost::end(thread_streams));
        for (; thread != last; ++thread)
            detail::parse_and_build_lock_graph(*thread, lg);
    }

#if 0
    /**
     * Structure holding the necessary information to locate a single event
     * within the execution of a program.
     */
    struct Coordinates {
        Process process;
        Thread thread;
        Segment segment;
    };
#endif

public:
    /**
     * Construct a skeleton from the data stored in a repository.
     *
     * @warning This may be a resource intensive operation since we have
     *          to load the content of the whole repository in memory to
     *          build two different graphs.
     */
    explicit SyncSkeleton(Repository& repo) : repository_(repo) {
        build_graphs(repository_, lock_graph_, segmentation_graph_);
    }

    /**
     * Return the number of threads spawned in the part of the program
     * captured by the skeleton.
     */
    std::size_t number_of_threads() const {
        return std::distance(boost::begin(threads()), boost::end(threads()));
    }

    /**
     * Return the number of unique locks created in the part of the program
     * captured by the skeleton.
     */
    std::size_t number_of_locks() const {
        return num_vertices(lock_graph_);
    }

private:
    typedef typename Repository::template
                const_key_view<ThreadId>::type unspecified_range_of_threads;
    typedef std::vector<DeadlockDiagnostic> unspecified_range_of_diagnostics;

public:
    unspecified_range_of_threads threads() const {
        return repository_.template keys<ThreadId>();
    }

{'fraction_non_alphanumeric': 0.08408829909404109, 'fraction_numerical': 0.00306239632512441, 'mean_word_length': 3.0485537190082646, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6066809', 'n_tokens_mistral': 2227, 'n_tokens_neox': 2115, 'n_words': 657}