<commit_before>// Copyright 2011 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 "build.h"

#include <stdio.h>
#ifndef WIN32
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/termios.h>
#endif

#include "build_log.h"
#include "graph.h"
#include "ninja.h"
#include "subprocess.h"

/// Tracks the status of a build: completion fraction, printing updates.
struct BuildStatus {
  BuildStatus();
  void PlanHasTotalEdges(int total);
  void BuildEdgeStarted(Edge* edge);
  /// Returns the time the edge took, in ms.
  int BuildEdgeFinished(Edge* edge);

  void PrintStatus(Edge* edge);

  time_t last_update_;
  int finished_edges_, total_edges_;

  typedef map<Edge*, timeval> RunningEdgeMap;
  RunningEdgeMap running_edges_;

  BuildConfig::Verbosity verbosity_;
  /// Whether we can do fancy terminal control codes.
  bool smart_terminal_;
};

BuildStatus::BuildStatus()
    : last_update_(time(NULL)), finished_edges_(0), total_edges_(0),
      verbosity_(BuildConfig::NORMAL) {
#ifndef WIN32
  const char* term = getenv("TERM");
  smart_terminal_ = isatty(1) && term && string(term) != "dumb";
#else
  smart_terminal_ = false;
#endif
}

void BuildStatus::PlanHasTotalEdges(int total) {
  total_edges_ = total;
}

void BuildStatus::BuildEdgeStarted(Edge* edge) {
  timeval now;
  gettimeofday(&now, NULL);
  running_edges_.insert(make_pair(edge, now));

  PrintStatus(edge);
}

int BuildStatus::BuildEdgeFinished(Edge* edge) {
  timeval now;
  gettimeofday(&now, NULL);
  ++finished_edges_;

  if (verbosity_ != BuildConfig::QUIET) {
    if (smart_terminal_ && verbosity_ == BuildConfig::NORMAL) {
      PrintStatus(edge);
      if (finished_edges_ == total_edges_)
        printf("\n");
    } else {
      if (now.tv_sec - last_update_ > 5) {
        printf("%.1f%% %d/%d\n", finished_edges_ * 100 / (float)total_edges_,
               finished_edges_, total_edges_);
        last_update_ = now.tv_sec;
      }
    }
  }

  RunningEdgeMap::iterator i = running_edges_.find(edge);
  timeval delta;
  timersub(&now, &i->second, &delta);
  int ms = (delta.tv_sec * 1000) + (delta.tv_usec / 1000);
  running_edges_.erase(i);

  return ms;
}
<commit_msg>windows: use millis abstraction instead of non-portable gettimeofday<commit_after>// Copyright 2011 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 "build.h"

#include <stdio.h>

#ifdef _WIN32
#include <windows.h>
#else
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/termios.h>
#endif

#include "build_log.h"
#include "graph.h"
#include "ninja.h"
#include "subprocess.h"

namespace {

int64_t GetTimeMillis() {
#ifdef _WIN32
  // GetTickCount64 is only available on Vista or later.
  return GetTickCount();
#else
  timeval now;
  gettimeofday(&now, NULL);
  return ((int64_t)now.tv_sec * 1000) + (now.tv_usec / 1000);
#endif
}

}

/// Tracks the status of a build: completion fraction, printing updates.
struct BuildStatus {
  BuildStatus();
  void PlanHasTotalEdges(int total);
  void BuildEdgeStarted(Edge* edge);
  /// Returns the time the edge took, in ms.
  int BuildEdgeFinished(Edge* edge);

  void PrintStatus(Edge* edge);

  int64_t last_update_millis_;
  int finished_edges_, total_edges_;

  typedef map<Edge*, int64_t> RunningEdgeMap;
  RunningEdgeMap running_edges_;

  BuildConfig::Verbosity verbosity_;
  /// Whether we can do fancy terminal control codes.
  bool smart_terminal_;
};

BuildStatus::BuildStatus()
    : last_update_millis_(GetTimeMillis()),
      finished_edges_(0), total_edges_(0),
      verbosity_(BuildConfig::NORMAL) {
#ifndef WIN32
  const char* term = getenv("TERM");
  smart_terminal_ = isatty(1) && term && string(term) != "dumb";
#else
  smart_terminal_ = false;
#endif
}

void BuildStatus::PlanHasTotalEdges(int total) {
  total_edges_ = total;
}

void BuildStatus::BuildEdgeStarted(Edge* edge) {
  running_edges_.insert(make_pair(edge, GetTimeMillis()));

  PrintStatus(edge);
}

int BuildStatus::BuildEdgeFinished(Edge* edge) {
  int64_t now = GetTimeMillis();
  ++finished_edges_;

  if (verbosity_ != BuildConfig::QUIET) {
    if (smart_terminal_ && verbosity_ == BuildConfig::NORMAL) {
      PrintStatus(edge);
      if (finished_edges_ == total_edges_)
        printf("\n");
    } else {
      if (now - last_update_millis_ > 5*1000) {
        printf("%.1f%% %d/%d\n", finished_edges_ * 100 / (float)total_edges_,
               finished_edges_, total_edges_);
        last_update_millis_ = now;
      }
    }
  }

  RunningEdgeMap::iterator i = running_edges_.find(edge);
  int ms = (int)(now - i->second);
  running_edges_.erase(i);

  return ms;
}

{'fraction_non_alphanumeric': 0.12233386215406311, 'fraction_numerical': 0.013044244667724308, 'mean_word_length': 3.933913043478261, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3568745', 'n_tokens_mistral': 1881, 'n_tokens_neox': 1813, 'n_words': 522}