<commit_before>/*
 * Copyright 2011 Google Inc.
 *
 * 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.
 */

// Author: jmarantz@google.com (Joshua Marantz)

#include <cstdlib>                     // for getenv
#include <vector>

#include "net/instaweb/rewriter/public/test_rewrite_driver_factory.h"

#include "base/logging.h"
#include "base/scoped_ptr.h"            // for scoped_ptr
#include "net/instaweb/http/public/counting_url_async_fetcher.h"
#include "net/instaweb/http/public/fake_url_async_fetcher.h"
#include "net/instaweb/http/public/mock_url_fetcher.h"
#include "net/instaweb/http/public/url_fetcher.h"  // for UrlFetcher
#include "net/instaweb/http/public/wait_url_async_fetcher.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_driver_factory.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/rewriter/public/test_url_namer.h"
#include "net/instaweb/util/public/basictypes.h"        // for int64
#include "net/instaweb/util/public/delay_cache.h"
#include "net/instaweb/util/public/lru_cache.h"
#include "net/instaweb/util/public/mem_file_system.h"
#include "net/instaweb/util/public/mock_hasher.h"
#include "net/instaweb/util/public/mock_message_handler.h"
#include "net/instaweb/util/public/mock_scheduler.h"
#include "net/instaweb/util/public/mock_timer.h"
#include "net/instaweb/util/public/string.h"
#include "net/instaweb/util/public/string_util.h"  // for StrCat, etc
#include "net/instaweb/util/public/thread_system.h"
#include "net/instaweb/util/public/timer.h"

namespace net_instaweb {

class CacheInterface;
class FileSystem;
class Hasher;
class HtmlFilter;
class MessageHandler;
class RequestHeaders;
class ResponseHeaders;
class RewriteFilter;
class Scheduler;
class UrlAsyncFetcher;
class UrlNamer;
class Writer;

namespace {

const int kCacheSize  = 10*1000*1000;

// This class is used to paper-over an unfortunate design choice in
// RewriteDriverFactory about fetcher ownership.  We'd like to share
// the Mock Fetcher between multiple TestRewriteDriverFactory instances.
// But this results in double-deletion problems on shutdown as each
// factory keeps its fetcher in a scoped_ptr or has equivalent logic.
//
// This should be fixed properly but for now we can introduce the
// right ownership semantics by interposing a transparent ProxyFetcher
// which is allocated per-factory, but references a real fetcher.
class ProxyUrlFetcher : public UrlFetcher {
 public:
  explicit ProxyUrlFetcher(UrlFetcher* fetcher) : fetcher_(fetcher) {}
  virtual ~ProxyUrlFetcher() {}
  virtual bool StreamingFetchUrl(const GoogleString& url,
                                 const RequestHeaders& request_headers,
                                 ResponseHeaders* response_headers,
                                 Writer* response_writer,
                                 MessageHandler* message_handler) {
    return fetcher_->StreamingFetchUrl(url,
                                       request_headers,
                                       response_headers,
                                       response_writer,
                                       message_handler);
  }

 private:
  UrlFetcher* fetcher_;
};

}  // namespace

const int64 TestRewriteDriverFactory::kStartTimeMs =
    MockTimer::kApr_5_2010_ms - 2 * Timer::kMonthMs;

const char TestRewriteDriverFactory::kUrlNamerScheme[] = "URL_NAMER_SCHEME";

TestRewriteDriverFactory::TestRewriteDriverFactory(
    const StringPiece& temp_dir, MockUrlFetcher* mock_fetcher)
  : mock_timer_(NULL),
    mock_scheduler_(NULL),
    lru_cache_(NULL),
    proxy_url_fetcher_(NULL),
    mock_url_fetcher_(mock_fetcher),
    mock_url_async_fetcher_(NULL),
    counting_url_async_fetcher_(NULL),
    mock_time_cache_(mock_timer_, lru_cache_.get()),
    mem_file_system_(NULL),
    mock_hasher_(NULL),
    mock_message_handler_(NULL),
    mock_html_message_handler_(NULL),
    add_platform_specific_decoding_passes_(true) {
  set_filename_prefix(StrCat(temp_dir, "/"));
  use_test_url_namer_ = (getenv(kUrlNamerScheme) != NULL &&
                         strcmp(getenv(kUrlNamerScheme), "test") == 0);
}

TestRewriteDriverFactory::~TestRewriteDriverFactory() {
}

void TestRewriteDriverFactory::SetupWaitFetcher() {
  wait_url_async_fetcher_.reset(new WaitUrlAsyncFetcher(
      mock_url_fetcher_, thread_system()->NewMutex()));
  counting_url_async_fetcher_->set_fetcher(wait_url_async_fetcher_.get());
}

void TestRewriteDriverFactory::CallFetcherCallbacksForDriver(
    RewriteDriver* driver) {
  // Temporarily change the delayed-fetcher's mode so that it calls
  // callbacks immediately.  This is so that any further fetches
  // queued from a Done callback are immediately executed, until the
  // end of this method when we reset the state back to whatever it
  // was previously.
  bool pass_through_mode = wait_url_async_fetcher_->SetPassThroughMode(true);

  // TODO(jmarantz): parameterize whether this is to be used for
  // simulating delayed fetches for a ResourceFetch, in which case
  // we'll want WaitForCompletion, or whether this is to be used for
  // simulation of Rewrites, in which case we can do a TimedWait
  // according to the needs of the simulation.
  driver->WaitForCompletion();
  wait_url_async_fetcher_->SetPassThroughMode(pass_through_mode);
  driver->Clear();
}

UrlFetcher* TestRewriteDriverFactory::DefaultUrlFetcher() {
  DCHECK(proxy_url_fetcher_ == NULL);
  proxy_url_fetcher_ = new ProxyUrlFetcher(mock_url_fetcher_);
  return proxy_url_fetcher_;
}

UrlAsyncFetcher* TestRewriteDriverFactory::DefaultAsyncUrlFetcher() {
  DCHECK(counting_url_async_fetcher_ == NULL);
  mock_url_async_fetcher_.reset(new FakeUrlAsyncFetcher(mock_url_fetcher_));
  counting_url_async_fetcher_ = new CountingUrlAsyncFetcher(
      mock_url_async_fetcher_.get());
  return counting_url_async_fetcher_;
}

FileSystem* TestRewriteDriverFactory::DefaultFileSystem() {
  DCHECK(mem_file_system_ == NULL);
  timer();  // ensures that mock_timer_ is initialized.
  mem_file_system_ = new MemFileSystem(thread_system(), mock_timer_);
  return mem_file_system_;
}

Timer* TestRewriteDriverFactory::DefaultTimer() {
  DCHECK(mock_timer_ == NULL);
  mock_timer_ = new MockTimer(kStartTimeMs);
  return mock_timer_;
}

CacheInterface* TestRewriteDriverFactory::DefaultCacheInterface() {
  DCHECK(lru_cache_ == NULL);
  lru_cache_.reset(new LRUCache(kCacheSize));
  delay_cache_ = new DelayCache(lru_cache_.get());
  return delay_cache_;
}

Hasher* TestRewriteDriverFactory::NewHasher() {
  DCHECK(mock_hasher_ == NULL);
  mock_hasher_ = new MockHasher;
  return mock_hasher_;
}

MessageHandler* TestRewriteDriverFactory::DefaultMessageHandler() {
  DCHECK(mock_message_handler_ == NULL);
  mock_message_handler_ = new MockMessageHandler;
  return mock_message_handler_;
}

MessageHandler* TestRewriteDriverFactory::DefaultHtmlParseMessageHandler() {
  DCHECK(mock_html_message_handler_ == NULL);
  mock_html_message_handler_ = new MockMessageHandler;
  return mock_html_message_handler_;
}

UrlNamer* TestRewriteDriverFactory::DefaultUrlNamer() {
  return (use_test_url_namer_
          ? new TestUrlNamer()
          : RewriteDriverFactory::DefaultUrlNamer());
}

void TestRewriteDriverFactory::SetUseTestUrlNamer(bool x) {
  use_test_url_namer_ = x;
  set_url_namer(DefaultUrlNamer());
}

Scheduler* TestRewriteDriverFactory::CreateScheduler() {
  DCHECK(mock_scheduler_ == NULL);
  timer();  // make sure mock_timer_ is created.
  mock_scheduler_ = new MockScheduler(thread_system(), mock_timer_);
  return mock_scheduler_;
}

RewriteOptions* TestRewriteDriverFactory::NewRewriteOptions() {
  RewriteOptions* options = RewriteDriverFactory::NewRewriteOptions();
  options->set_ajax_rewriting_enabled(false);
  return options;
}

void TestRewriteDriverFactory::AddPlatformSpecificDecodingPasses(
    RewriteDriver* driver) {
  if (add_platform_specific_decoding_passes_) {
    for (std::size_t i = 0; i < rewriter_callback_vector_.size(); i++) {
      RewriteFilter* filter = rewriter_callback_vector_[i]->Done(driver);
      driver->AppendRewriteFilter(filter);
    }
  }
}

void TestRewriteDriverFactory::AddPlatformSpecificRewritePasses(
    RewriteDriver* driver) {
  for (std::size_t i = 0; i < filter_callback_vector_.size(); i++) {
    HtmlFilter* filter = filter_callback_vector_[i]->Done(driver);
    driver->AddOwnedPostRenderFilter(filter);
  }
  for (std::size_t i = 0; i < rewriter_callback_vector_.size(); i++) {
    RewriteFilter* filter = rewriter_callback_vector_[i]->Done(driver);
    driver->AppendRewriteFilter(filter);
  }
}

TestRewriteDriverFactory::CreateFilterCallback::~CreateFilterCallback() {
}

TestRewriteDriverFactory::CreateRewriterCallback::~CreateRewriterCallback() {
}

}  // namespace net_instaweb
<commit_msg>Use a thread-safe cache when testing, as that's expected of the system. Not doing this appeared to have caused some flakiness in css_flatten_imports_filter_test<commit_after>/*
 * Copyright 2011 Google Inc.
 *
 * 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.
 */

// Author: jmarantz@google.com (Joshua Marantz)

#include <cstdlib>                     // for getenv
#include <vector>

#include "net/instaweb/rewriter/public/test_rewrite_driver_factory.h"

#include "base/logging.h"
#include "base/scoped_ptr.h"            // for scoped_ptr
#include "net/instaweb/http/public/counting_url_async_fetcher.h"
#include "net/instaweb/http/public/fake_url_async_fetcher.h"
#include "net/instaweb/http/public/mock_url_fetcher.h"
#include "net/instaweb/http/public/url_fetcher.h"  // for UrlFetcher
#include "net/instaweb/http/public/wait_url_async_fetcher.h"
#include "net/instaweb/rewriter/public/rewrite_driver.h"
#include "net/instaweb/rewriter/public/rewrite_driver_factory.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "net/instaweb/rewriter/public/test_url_namer.h"
#include "net/instaweb/util/public/basictypes.h"        // for int64
#include "net/instaweb/util/public/delay_cache.h"
#include "net/instaweb/util/public/lru_cache.h"
#include "net/instaweb/util/public/mem_file_system.h"
#include "net/instaweb/util/public/mock_hasher.h"
#include "net/instaweb/util/public/mock_message_handler.h"
#include "net/instaweb/util/public/mock_scheduler.h"
#include "net/instaweb/util/public/mock_timer.h"
#include "net/instaweb/util/public/string.h"
#include "net/instaweb/util/public/string_util.h"  // for StrCat, etc
#include "net/instaweb/util/public/threadsafe_cache.h"
#include "net/instaweb/util/public/thread_system.h"
#include "net/instaweb/util/public/timer.h"

namespace net_instaweb {

class CacheInterface;
class FileSystem;
class Hasher;
class HtmlFilter;
class MessageHandler;
class RequestHeaders;
class ResponseHeaders;
class RewriteFilter;
class Scheduler;
class UrlAsyncFetcher;
class UrlNamer;
class Writer;

namespace {

const int kCacheSize  = 10*1000*1000;

// This class is used to paper-over an unfortunate design choice in
// RewriteDriverFactory about fetcher ownership.  We'd like to share
// the Mock Fetcher between multiple TestRewriteDriverFactory instances.
// But this results in double-deletion problems on shutdown as each
// factory keeps its fetcher in a scoped_ptr or has equivalent logic.
//
// This should be fixed properly but for now we can introduce the
// right ownership semantics by interposing a transparent ProxyFetcher
// which is allocated per-factory, but references a real fetcher.
class ProxyUrlFetcher : public UrlFetcher {
 public:
  explicit ProxyUrlFetcher(UrlFetcher* fetcher) : fetcher_(fetcher) {}
  virtual ~ProxyUrlFetcher() {}
  virtual bool StreamingFetchUrl(const GoogleString& url,
                                 const RequestHeaders& request_headers,
                                 ResponseHeaders* response_headers,
                                 Writer* response_writer,
                                 MessageHandler* message_handler) {
    return fetcher_->StreamingFetchUrl(url,
                                       request_headers,
                                       response_headers,
                                       response_writer,
                                       message_handler);
  }

 private:
  UrlFetcher* fetcher_;
};

}  // namespace

const int64 TestRewriteDriverFactory::kStartTimeMs =
    MockTimer::kApr_5_2010_ms - 2 * Timer::kMonthMs;

const char TestRewriteDriverFactory::kUrlNamerScheme[] = "URL_NAMER_SCHEME";

TestRewriteDriverFactory::TestRewriteDriverFactory(
    const StringPiece& temp_dir, MockUrlFetcher* mock_fetcher)
  : mock_timer_(NULL),
    mock_scheduler_(NULL),
    lru_cache_(NULL),
    proxy_url_fetcher_(NULL),
    mock_url_fetcher_(mock_fetcher),
    mock_url_async_fetcher_(NULL),
    counting_url_async_fetcher_(NULL),
    mock_time_cache_(mock_timer_, lru_cache_.get()),
    mem_file_system_(NULL),
    mock_hasher_(NULL),
    mock_message_handler_(NULL),
    mock_html_message_handler_(NULL),
    add_platform_specific_decoding_passes_(true) {
  set_filename_prefix(StrCat(temp_dir, "/"));
  use_test_url_namer_ = (getenv(kUrlNamerScheme) != NULL &&
                         strcmp(getenv(kUrlNamerScheme), "test") == 0);
}

TestRewriteDriverFactory::~TestRewriteDriverFactory() {
}

void TestRewriteDriverFactory::SetupWaitFetcher() {
  wait_url_async_fetcher_.reset(new WaitUrlAsyncFetcher(
      mock_url_fetcher_, thread_system()->NewMutex()));
  counting_url_async_fetcher_->set_fetcher(wait_url_async_fetcher_.get());
}

void TestRewriteDriverFactory::CallFetcherCallbacksForDriver(
    RewriteDriver* driver) {
  // Temporarily change the delayed-fetcher's mode so that it calls
  // callbacks immediately.  This is so that any further fetches
  // queued from a Done callback are immediately executed, until the
  // end of this method when we reset the state back to whatever it
  // was previously.
  bool pass_through_mode = wait_url_async_fetcher_->SetPassThroughMode(true);

  // TODO(jmarantz): parameterize whether this is to be used for
  // simulating delayed fetches for a ResourceFetch, in which case
  // we'll want WaitForCompletion, or whether this is to be used for
  // simulation of Rewrites, in which case we can do a TimedWait
  // according to the needs of the simulation.
  driver->WaitForCompletion();
  wait_url_async_fetcher_->SetPassThroughMode(pass_through_mode);
  driver->Clear();
}

UrlFetcher* TestRewriteDriverFactory::DefaultUrlFetcher() {
  DCHECK(proxy_url_fetcher_ == NULL);
  proxy_url_fetcher_ = new ProxyUrlFetcher(mock_url_fetcher_);
  return proxy_url_fetcher_;
}

UrlAsyncFetcher* TestRewriteDriverFactory::DefaultAsyncUrlFetcher() {
  DCHECK(counting_url_async_fetcher_ == NULL);
  mock_url_async_fetcher_.reset(new FakeUrlAsyncFetcher(mock_url_fetcher_));
  counting_url_async_fetcher_ = new CountingUrlAsyncFetcher(
      mock_url_async_fetcher_.get());
  return counting_url_async_fetcher_;
}

FileSystem* TestRewriteDriverFactory::DefaultFileSystem() {
  DCHECK(mem_file_system_ == NULL);
  timer();  // ensures that mock_timer_ is initialized.
  mem_file_system_ = new MemFileSystem(thread_system(), mock_timer_);
  return mem_file_system_;
}

Timer* TestRewriteDriverFactory::DefaultTimer() {
  DCHECK(mock_timer_ == NULL);
  mock_timer_ = new MockTimer(kStartTimeMs);
  return mock_timer_;
}

CacheInterface* TestRewriteDriverFactory::DefaultCacheInterface() {
  DCHECK(lru_cache_ == NULL);
  lru_cache_.reset(new LRUCache(kCacheSize));
  delay_cache_ = new DelayCache(lru_cache_.get());
  return new ThreadsafeCache(delay_cache_, thread_system()->NewMutex());
}

Hasher* TestRewriteDriverFactory::NewHasher() {
  DCHECK(mock_hasher_ == NULL);
  mock_hasher_ = new MockHasher;
  return mock_hasher_;
}

MessageHandler* TestRewriteDriverFactory::DefaultMessageHandler() {
  DCHECK(mock_message_handler_ == NULL);
  mock_message_handler_ = new MockMessageHandler;
  return mock_message_handler_;
}

MessageHandler* TestRewriteDriverFactory::DefaultHtmlParseMessageHandler() {
  DCHECK(mock_html_message_handler_ == NULL);
  mock_html_message_handler_ = new MockMessageHandler;
  return mock_html_message_handler_;
}

UrlNamer* TestRewriteDriverFactory::DefaultUrlNamer() {
  return (use_test_url_namer_
          ? new TestUrlNamer()
          : RewriteDriverFactory::DefaultUrlNamer());
}

void TestRewriteDriverFactory::SetUseTestUrlNamer(bool x) {
  use_test_url_namer_ = x;
  set_url_namer(DefaultUrlNamer());
}

Scheduler* TestRewriteDriverFactory::CreateScheduler() {
  DCHECK(mock_scheduler_ == NULL);
  timer();  // make sure mock_timer_ is created.
  mock_scheduler_ = new MockScheduler(thread_system(), mock_timer_);
  return mock_scheduler_;
}

RewriteOptions* TestRewriteDriverFactory::NewRewriteOptions() {
  RewriteOptions* options = RewriteDriverFactory::NewRewriteOptions();
  options->set_ajax_rewriting_enabled(false);
  return options;
}

void TestRewriteDriverFactory::AddPlatformSpecificDecodingPasses(
    RewriteDriver* driver) {
  if (add_platform_specific_decoding_passes_) {
    for (std::size_t i = 0; i < rewriter_callback_vector_.size(); i++) {
      RewriteFilter* filter = rewriter_callback_vector_[i]->Done(driver);
      driver->AppendRewriteFilter(filter);
    }
  }
}

void TestRewriteDriverFactory::AddPlatformSpecificRewritePasses(
    RewriteDriver* driver) {
  for (std::size_t i = 0; i < filter_callback_vector_.size(); i++) {
    HtmlFilter* filter = filter_callback_vector_[i]->Done(driver);
    driver->AddOwnedPostRenderFilter(filter);
  }
  for (std::size_t i = 0; i < rewriter_callback_vector_.size(); i++) {
    RewriteFilter* filter = rewriter_callback_vector_[i]->Done(driver);
    driver->AppendRewriteFilter(filter);
  }
}

TestRewriteDriverFactory::CreateFilterCallback::~CreateFilterCallback() {
}

TestRewriteDriverFactory::CreateRewriterCallback::~CreateRewriterCallback() {
}

}  // namespace net_instaweb
<|endoftext|>


<commit_before>#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN
#define BOOST_TEST_MODULE state

#include <boost/test/unit_test.hpp>

#include "peer.h"

extern "C" {
	int add_io(struct peer *p)
	{
		return 0;
	}

	void remove_io(const struct peer *p)
	{
		return;
	}

	void remove_all_methods_from_peer(struct peer *p)
	{
	}

	void remove_all_fetchers_from_peer(struct peer *p)
	{
	}

	void remove_peer_from_routing_table(const struct peer *p,
		const struct peer *peer_to_remove)
	{
	}

	void remove_routing_info_from_peer(const struct peer *p)
	{
	}

	void remove_all_states_from_peer(struct peer *p)
	{
	}

	void delete_routing_table(struct peer *p)
	{
	}

	int add_routing_table(struct peer *p)
	{
		return 0;
	}
}

BOOST_AUTO_TEST_CASE(number_of_peer)
{
	static const int TEST_FD = 1;

	int peers = get_number_of_peers();
	BOOST_CHECK(peers == 0);

	struct peer *p = alloc_peer(TEST_FD);
	peers = get_number_of_peers();
	BOOST_CHECK(peers == 1);

	free_peer(p);
	peers = get_number_of_peers();
	BOOST_CHECK(peers == 0);
}

<commit_msg>Add test to check behaviour if peer allocation failes.<commit_after>#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN
#define BOOST_TEST_MODULE state

#include <boost/test/unit_test.hpp>

#include "peer.h"

enum fds {
	TEST_FD = 0,
	FAILED_ALLOC_PEER_FD
};

extern "C" {
	int add_io(struct peer *p)
	{
		if (p->io.fd == FAILED_ALLOC_PEER_FD) {
			return -1;
		}
		return 0;
	}

	void remove_io(const struct peer *p)
	{
		return;
	}

	void remove_all_methods_from_peer(struct peer *p)
	{
	}

	void remove_all_fetchers_from_peer(struct peer *p)
	{
	}

	void remove_peer_from_routing_table(const struct peer *p,
		const struct peer *peer_to_remove)
	{
	}

	void remove_routing_info_from_peer(const struct peer *p)
	{
	}

	void remove_all_states_from_peer(struct peer *p)
	{
	}

	void delete_routing_table(struct peer *p)
	{
	}

	int add_routing_table(struct peer *p)
	{
		return 0;
	}
}

BOOST_AUTO_TEST_CASE(number_of_peer)
{
	int peers = get_number_of_peers();
	BOOST_CHECK(peers == 0);

	struct peer *p = alloc_peer(TEST_FD);
	peers = get_number_of_peers();
	BOOST_CHECK(peers == 1);

	free_peer(p);
	peers = get_number_of_peers();
	BOOST_CHECK(peers == 0);
}

BOOST_AUTO_TEST_CASE(failed_alloc_peer)
{
	struct peer *p = alloc_peer(FAILED_ALLOC_PEER_FD);
	BOOST_CHECK(p == NULL);
}
<|endoftext|>


<commit_before>#include <algorithm>
#include <fstream>
#include <iostream>
#include <string>

namespace
{
    template <typename T>
    bool subEqual(T lStart, T lEnd, T rStart, T rEnd)
    {
        while((lStart != lEnd) && (rStart != rEnd) && (*lStart == *rStart))
        {
            ++lStart;
            ++rStart;
        }
        return (lStart == lEnd);
    }

    bool isRotation(std::string lhs, std::string rhs)
    {
        if(lhs.length() == rhs.length())
        {
            auto const lStart = std::begin(lhs);
            auto const lEnd = std::end(lhs);

            auto const rEnd = std::end(rhs);
            auto rStart = std::find(std::begin(rhs), rEnd, lhs[0]);
            while(rStart != rEnd)
            {
                auto diff = std::distance(rStart, rEnd);
                auto lMiddle = lStart;
                std::advance(lMiddle, diff);
                if(subEqual(lStart, lMiddle, rStart, rEnd) &&
                   subEqual(lMiddle, lEnd, std::begin(rhs), rStart))
                {
                    return true;
                }
                ++rStart;
                rStart = std::find(rStart, rEnd, lhs[0]);
            }
        }
        return false;
    }
}

int main(int argc, char ** argv)
{
    std::ifstream input{argv[1]};
    std::string line;
    std::getline(input, line);
    while(input)
    {
        auto split = std::find(std::begin(line), std::end(line), ',');
        std::string lhs{std::begin(line), split};
        std::string rhs{++split, std::end(line)};
        if(isRotation(std::move(lhs), std::move(rhs)))
        {
            std::cout << "True\n";
        }
        else
        {
            std::cout << "False\n";
        }
        std::getline(input, line);
    }
}
<commit_msg>Remove redundant check in string comparison<commit_after>#include <algorithm>
#include <fstream>
#include <iostream>
#include <string>

namespace
{
    template <typename T>
    bool subEqual(T lStart, T lEnd, T rStart, T rEnd)
    {
        while((lStart != lEnd) && (*lStart == *rStart))
        {
            ++lStart;
            ++rStart;
        }
        return (lStart == lEnd);
    }

    bool isRotation(std::string lhs, std::string rhs)
    {
        if(lhs.length() == rhs.length())
        {
            auto const lStart = std::begin(lhs);
            auto const lEnd = std::end(lhs);

            auto const rEnd = std::end(rhs);
            auto rStart = std::find(std::begin(rhs), rEnd, lhs[0]);
            while(rStart != rEnd)
            {
                auto diff = std::distance(rStart, rEnd);
                auto lMiddle = lStart;
                std::advance(lMiddle, diff);
                if(subEqual(lStart, lMiddle, rStart, rEnd) &&
                   subEqual(lMiddle, lEnd, std::begin(rhs), rStart))
                {
                    return true;
                }
                ++rStart;
                rStart = std::find(rStart, rEnd, lhs[0]);
            }
        }
        return false;
    }
}

int main(int argc, char ** argv)
{
    std::ifstream input{argv[1]};
    std::string line;
    std::getline(input, line);
    while(input)
    {
        auto split = std::find(std::begin(line), std::end(line), ',');
        std::string lhs{std::begin(line), split};
        std::string rhs{++split, std::end(line)};
        if(isRotation(std::move(lhs), std::move(rhs)))
        {
            std::cout << "True\n";
        }
        else
        {
            std::cout << "False\n";
        }
        std::getline(input, line);
    }
}
<|endoftext|>


<commit_before>/**
 * @file regression_distribution.hpp
 * @author Michael Fox
 *
 * Implementation of conditional Gaussian distribution for HMM regression (HMMR)
 */
#ifndef __MLPACK_METHODS_HMM_DISTRIBUTIONS_REGRESSION_DISTRIBUTION_HPP
#define __MLPACK_METHODS_HMM_DISTRIBUTIONS_REGRESSION_DISTRIBUTION_HPP

#include <mlpack/core.hpp>
#include <mlpack/core/dists/gaussian_distribution.hpp>
#include <mlpack/methods/linear_regression/linear_regression.hpp>

namespace mlpack {
namespace distribution {

/**
 * A class that represents a univariate conditionally Gaussian distribution.
 * Can be used as an emission distribution with the hmm class to implement HMM
 * regression (HMMR) as described in
 * https://www.ima.umn.edu/preprints/January1994/1195.pdf
 * The hmm observations should have the dependent variable in the first row,
 * with the independent variables in the other rows.
 */
class RegressionDistribution
{
 private:
  //! Regression function for representing conditional mean.
  regression::LinearRegression rf;
  //! Error distribution
  GaussianDistribution err;

 public:
  /**
   * Default constructor, which creates a Gaussian with zero dimension.
   */
  RegressionDistribution() { /* nothing to do */ }

  /**
   * Create a Conditional Gaussian distribution with conditional mean function
   * obtained by running RegressionFunction on predictors, responses.
   *
   * @param predictors Matrix of predictors (X).
   * @param responses Vector of responses (y).
   */
  RegressionDistribution(const arma::mat& predictors,
                         const arma::vec& responses) :
      rf(regression::LinearRegression(predictors, responses))
  {
    err = GaussianDistribution(1);
    err.Covariance() = rf.ComputeError(predictors, responses);
  }

  /**
   * Returns a string representation of this object.
   */
  std::string ToString() const;

  // Return regression function
  const regression::LinearRegression& Rf() { return rf; }

  /**
   * Estimate the Gaussian distribution directly from the given observations.
   *
   * @param observations List of observations.
   */
  void Estimate(const arma::mat& observations);

  /**
   * Estimate parameters using provided observation weights
   *
   * @param weights probability that given observation is from distribution
   */
  void Estimate(const arma::mat& observations, const arma::vec& weights);

  /**
  * Evaluate probability density function of given observation
  *
  * @param observation point to evaluate probability at
  */
  double Probability(const arma::vec& observation) const;

  /**
   * Calculate y_i for each data point in points.
   *
   * @param points the data points to calculate with.
   * @param predictions y, will contain calculated values on completion.
   */
  void Predict(const arma::mat& points, arma::vec& predictions) const;

  //! Return the parameters (the b vector).
  const arma::vec& Parameters() const { return rf.Parameters(); }

  //! Return the dimensionality (2) NEED TO FIX THIS
  static size_t Dimensionality() { return 2; }
};

}; // namespace distribution
}; // namespace mlpack

#endif
<commit_msg>Dimensionality() now returns proper values<commit_after>/**
 * @file regression_distribution.hpp
 * @author Michael Fox
 *
 * Implementation of conditional Gaussian distribution for HMM regression (HMMR)
 */
#ifndef __MLPACK_METHODS_HMM_DISTRIBUTIONS_REGRESSION_DISTRIBUTION_HPP
#define __MLPACK_METHODS_HMM_DISTRIBUTIONS_REGRESSION_DISTRIBUTION_HPP

#include <mlpack/core.hpp>
#include <mlpack/core/dists/gaussian_distribution.hpp>
#include <mlpack/methods/linear_regression/linear_regression.hpp>

namespace mlpack {
namespace distribution {

/**
 * A class that represents a univariate conditionally Gaussian distribution.
 * Can be used as an emission distribution with the hmm class to implement HMM
 * regression (HMMR) as described in
 * https://www.ima.umn.edu/preprints/January1994/1195.pdf
 * The hmm observations should have the dependent variable in the first row,
 * with the independent variables in the other rows.
 */
class RegressionDistribution
{
 private:
  //! Regression function for representing conditional mean.
  regression::LinearRegression rf;
  //! Error distribution
  GaussianDistribution err;

 public:
  /**
   * Default constructor, which creates a Gaussian with zero dimension.
   */
  RegressionDistribution() { /* nothing to do */ }

  /**
   * Create a Conditional Gaussian distribution with conditional mean function
   * obtained by running RegressionFunction on predictors, responses.
   *
   * @param predictors Matrix of predictors (X).
   * @param responses Vector of responses (y).
   */
  RegressionDistribution(const arma::mat& predictors,
                         const arma::vec& responses) :
      rf(regression::LinearRegression(predictors, responses))
  {
    err = GaussianDistribution(1);
    err.Covariance() = rf.ComputeError(predictors, responses);
  }

  /**
   * Returns a string representation of this object.
   */
  std::string ToString() const;

  // Return regression function
  const regression::LinearRegression& Rf() { return rf; }

  /**
   * Estimate the Gaussian distribution directly from the given observations.
   *
   * @param observations List of observations.
   */
  void Estimate(const arma::mat& observations);

  /**
   * Estimate parameters using provided observation weights
   *
   * @param weights probability that given observation is from distribution
   */
  void Estimate(const arma::mat& observations, const arma::vec& weights);

  /**
  * Evaluate probability density function of given observation
  *
  * @param observation point to evaluate probability at
  */
  double Probability(const arma::vec& observation) const;

  /**
   * Calculate y_i for each data point in points.
   *
   * @param points the data points to calculate with.
   * @param predictions y, will contain calculated values on completion.
   */
  void Predict(const arma::mat& points, arma::vec& predictions) const;

  //! Return the parameters (the b vector).
  const arma::vec& Parameters() const { return rf.Parameters(); }

  //! Return the dimensionality
    size_t Dimensionality() const { return rf.Parameters().n_elem; }
};

}; // namespace distribution
}; // namespace mlpack

#endif
<|endoftext|>


<commit_before>#include <possumwood_sdk/node_implementation.h>
#include <possumwood_sdk/app.h>
#include <possumwood_sdk/metadata.inl>
#include <possumwood_sdk/gl_renderable.h>
#include <possumwood_sdk/gl.h>

#include <GL/glut.h>

#include <maths/io/vec3.h>

#include "datatypes/constraints.h"

namespace {

dependency_graph::InAttr<anim::Constraints> a_constraints;
dependency_graph::InAttr<Imath::V3f> a_colour;

const std::string& fragmentShaderSource() {
	static const std::string s_source =
	    " \
		#version 150 \n \
		uniform vec3 colour; \n \
		out vec4 out_color; \n \
		\n \
		void main(void) { \n \
		    out_color = vec4(colour, 1.0); \n \
		}";

	return s_source;
}

const std::string& vertexShaderSource() {
	static std::string s_src =
		"#version 130 \n"
		" \n"
		"in vec3 P;                     // position attr from the vbo \n"
		" \n"
		"uniform mat4 in_Projection;      // projection matrix \n"
		"uniform mat4 in_Modelview;       // modelview matrix \n"
		" \n"
		"out vec3 vertexPosition;       // vertex position for the fragment shader \n"
		" \n"
		"void main() {\n"
		"	vec4 pos4 = vec4(P.x, P.y, P.z, 1);\n"
		"\n"
		"	vertexPosition = (in_Modelview * pos4).xyz;\n"
		"   	gl_Position = in_Projection * in_Modelview * pos4;\n"
		"   gl_PointSize = 5;\n"
		"} \n";

	return s_src;
}

class Drawable : public possumwood::Drawable {
  public:
	Drawable(dependency_graph::Values&& vals)
	    : possumwood::Drawable(std::move(vals)), m_points(GL_POINTS, vertexShaderSource(), fragmentShaderSource()), m_lines(GL_LINES, vertexShaderSource(), fragmentShaderSource()) {
	}

	~Drawable() {
	}

	dependency_graph::State draw() {
		GL_CHECK_ERR;

		{
			// possumwood::ScopedEnable sprite(GL_POINT_SPRITE); // removed in 3.2
			possumwood::ScopedEnable point_size(GL_VERTEX_PROGRAM_POINT_SIZE);

			GL_CHECK_ERR;

			const anim::Constraints& constraints = values().get(a_constraints);

			std::size_t pointCount = 0, lineCount = 0;
			for(auto& c : constraints) {
				pointCount += c.second.size();
				for(auto& i : c.second)
					lineCount += i.endFrame() - i.startFrame();
			}

			{
				auto vbo = m_points.updateVertexData();

				if(pointCount > 0) {

					vbo.data.resize(pointCount);

					std::size_t ctr = 0;
					for(auto& c : constraints)
						for(auto& i : c.second) {
							vbo.data[ctr] = i.origin().translation;

							++ctr;
						}
				}
				else
					vbo.data.clear();
			}

			{
				auto vbo = m_lines.updateVertexData();

				if(lineCount > 0) {

					vbo.data.resize(lineCount * 2);

					std::size_t ctr = 0;
					for(auto& c : constraints)
						for(auto& i : c.second)
							for(std::size_t fr=i.startFrame(); fr<i.endFrame(); ++fr) {
								vbo.data[ctr] = c.second.frames()[fr].tr().translation;
								++ctr;
								vbo.data[ctr] = c.second.frames()[fr+1].tr().translation;
								++ctr;
							}
					assert(ctr == lineCount * 2);
				}
				else
					vbo.data.clear();
			}

			GL_CHECK_ERR;

			m_points.setUniform("colour", values().get(a_colour));
			m_lines.setUniform("colour", values().get(a_colour));

			GL_CHECK_ERR;

			m_points.draw(viewport().projection(), viewport().modelview());
			m_lines.draw(viewport().projection(), viewport().modelview());

			GL_CHECK_ERR;
		}

		GL_CHECK_ERR;

		return dependency_graph::State();
	}

  private:
	possumwood::GLRenderable m_points, m_lines;

	boost::signals2::connection m_timeChangedConnection;
};

void init(possumwood::Metadata& meta) {
	meta.addAttribute(a_constraints, "constraints", anim::Constraints(), possumwood::AttrFlags::kVertical);
	meta.addAttribute(a_colour, "colour", Imath::V3f(1,1,1));

	meta.setDrawable<Drawable>();
}

possumwood::NodeImplementation s_impl("anim/constraints/display", init);
}
<commit_msg>Constraints display now has options to display full trajectories, constrained ones, or only the constraints themselves<commit_after>#include <possumwood_sdk/node_implementation.h>
#include <possumwood_sdk/app.h>
#include <possumwood_sdk/metadata.inl>
#include <possumwood_sdk/gl_renderable.h>
#include <possumwood_sdk/gl.h>

#include <GL/glut.h>

#include <maths/io/vec3.h>

#include "datatypes/constraints.h"

namespace {

dependency_graph::InAttr<anim::Constraints> a_constraints;
dependency_graph::InAttr<Imath::V3f> a_colour;
dependency_graph::InAttr<bool> a_showTrajectory, a_showConstrained;

const std::string& fragmentShaderSource() {
	static const std::string s_source =
	    " \
		#version 150 \n \
		uniform vec3 colour; \n \
		out vec4 out_color; \n \
		\n \
		void main(void) { \n \
		    out_color = vec4(colour, 1.0); \n \
		}";

	return s_source;
}

const std::string& vertexShaderSource() {
	static std::string s_src =
		"#version 130 \n"
		" \n"
		"in vec3 P;                     // position attr from the vbo \n"
		" \n"
		"uniform mat4 in_Projection;      // projection matrix \n"
		"uniform mat4 in_Modelview;       // modelview matrix \n"
		" \n"
		"out vec3 vertexPosition;       // vertex position for the fragment shader \n"
		" \n"
		"void main() {\n"
		"	vec4 pos4 = vec4(P.x, P.y, P.z, 1);\n"
		"\n"
		"	vertexPosition = (in_Modelview * pos4).xyz;\n"
		"   	gl_Position = in_Projection * in_Modelview * pos4;\n"
		"   gl_PointSize = 5;\n"
		"} \n";

	return s_src;
}

class Drawable : public possumwood::Drawable {
  public:
	Drawable(dependency_graph::Values&& vals)
	    : possumwood::Drawable(std::move(vals)), m_points(GL_POINTS, vertexShaderSource(), fragmentShaderSource()), m_lines(GL_LINES, vertexShaderSource(), fragmentShaderSource()) {
	}

	~Drawable() {
	}

	dependency_graph::State draw() {
		GL_CHECK_ERR;

		{
			// possumwood::ScopedEnable sprite(GL_POINT_SPRITE); // removed in 3.2
			possumwood::ScopedEnable point_size(GL_VERTEX_PROGRAM_POINT_SIZE);

			GL_CHECK_ERR;

			const anim::Constraints& constraints = values().get(a_constraints);

			std::size_t pointCount = 0, lineCount = 0;
			for(auto& c : constraints) {
				pointCount += c.second.size();

				if(values().get(a_showTrajectory) && !c.second.frames().empty())
					lineCount += c.second.frames().size() - 1;

				else if(values().get(a_showConstrained))
					for(auto& i : c.second)
						lineCount += i.endFrame() - i.startFrame();
			}

			{
				auto vbo = m_points.updateVertexData();

				if(pointCount > 0) {

					vbo.data.resize(pointCount);

					std::size_t ctr = 0;
					for(auto& c : constraints)
						for(auto& i : c.second)
							vbo.data[ctr++] = i.origin().translation;
				}
				else
					vbo.data.clear();
			}

			{
				auto vbo = m_lines.updateVertexData();

				if(lineCount > 0) {
					vbo.data.resize(lineCount * 2);

					std::size_t ctr = 0;
					for(auto& c : constraints)
						if(values().get(a_showTrajectory)) {
							auto it2 = c.second.frames().begin();
							auto it = it2;
							++it2;

							vbo.data[ctr++] = it->tr().translation;
							++it;
							++it2;

							while(it2 != c.second.frames().end()) {
								vbo.data[ctr++] = it->tr().translation;
								vbo.data[ctr++] = it->tr().translation;

								++it;
								++it2;
							}
							vbo.data[ctr++] = it->tr().translation;
						}

						else if(values().get(a_showConstrained))
							for(auto& i : c.second)
								for(std::size_t fr=i.startFrame(); fr<i.endFrame(); ++fr) {
									vbo.data[ctr++] = c.second.frames()[fr].tr().translation;
									vbo.data[ctr++] = c.second.frames()[fr+1].tr().translation;
								}

					assert(ctr == lineCount * 2);
				}
				else
					vbo.data.clear();
			}

			GL_CHECK_ERR;

			m_points.setUniform("colour", values().get(a_colour));
			m_lines.setUniform("colour", values().get(a_colour));

			GL_CHECK_ERR;

			m_points.draw(viewport().projection(), viewport().modelview());
			m_lines.draw(viewport().projection(), viewport().modelview());

			GL_CHECK_ERR;
		}

		GL_CHECK_ERR;

		return dependency_graph::State();
	}

  private:
	possumwood::GLRenderable m_points, m_lines;

	boost::signals2::connection m_timeChangedConnection;
};

void init(possumwood::Metadata& meta) {
	meta.addAttribute(a_constraints, "constraints", anim::Constraints(), possumwood::AttrFlags::kVertical);
	meta.addAttribute(a_colour, "colour", Imath::V3f(1,1,1));
	meta.addAttribute(a_showTrajectory, "show_trajectory", false);
	meta.addAttribute(a_showConstrained, "show_constrained", true);

	meta.setDrawable<Drawable>();
}

possumwood::NodeImplementation s_impl("anim/constraints/display", init);
}
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact:  Qt Software Information (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
**************************************************************************/

#include "openeditorsview.h"
#include "editormanager.h"
#include "editorview.h"
#include "icore.h"

#include <coreplugin/coreconstants.h>
#include <coreplugin/filemanager.h>
#include <coreplugin/uniqueidmanager.h>
#include <utils/qtcassert.h>

#include <QtCore/QTimer>
#include <QtGui/QMenu>
#include <QtGui/QPainter>
#include <QtGui/QStyle>
#include <QtGui/QStyleOption>
#include <QtGui/QHeaderView>
#include <QtGui/QKeyEvent>
#ifdef Q_WS_MAC
#include <qmacstyle_mac.h>
#endif

Q_DECLARE_METATYPE(Core::IEditor*)

using namespace Core;
using namespace Core::Internal;

OpenEditorsWidget::OpenEditorsWidget()
{
    m_ui.setupUi(this);
    setWindowTitle(tr("Open Documents"));
    setWindowIcon(QIcon(Constants::ICON_DIR));
    setFocusProxy(m_ui.editorList);
    m_ui.editorList->header()->hide();
    m_ui.editorList->setIndentation(0);
    m_ui.editorList->setSelectionMode(QAbstractItemView::ExtendedSelection);
    m_ui.editorList->setTextElideMode(Qt::ElideMiddle);
    m_ui.editorList->installEventFilter(this);
    m_ui.editorList->setFrameStyle(QFrame::NoFrame);
    m_ui.editorList->setAttribute(Qt::WA_MacShowFocusRect, false);
    EditorManager *em = EditorManager::instance();
    m_ui.editorList->setModel(em->openedEditorsModel());
    connect(em, SIGNAL(currentEditorChanged(Core::IEditor*)),
            this, SLOT(updateCurrentItem(Core::IEditor*)));
    connect(m_ui.editorList, SIGNAL(itemClicked(QTreeWidgetItem*, int)),
            this, SLOT(selectEditor(QTreeWidgetItem*)));
    //updateEditorList();
}

OpenEditorsWidget::~OpenEditorsWidget()
{
}

void OpenEditorsWidget::updateCurrentItem(Core::IEditor *editor)
{
    if (!editor) {
        m_ui.editorList->clearSelection();
        return;
    }
    EditorManager *em = EditorManager::instance();
    m_ui.editorList->clearSelection(); //we are in extended selectionmode
    m_ui.editorList->setCurrentIndex(em->openedEditorsModel()->indexOf(editor));
    m_ui.editorList->scrollTo(m_ui.editorList->currentIndex());
}

void OpenEditorsWidget::selectEditor(const QModelIndex &index)
{
    IEditor *editor = index.data(Qt::UserRole).value<IEditor*>();
    EditorManager::instance()->activateEditor(editor);
}

void OpenEditorsWidget::selectEditor()
{
    selectEditor(m_ui.editorList->currentIndex());
}

void OpenEditorsWidget::closeEditors()
{
    /* ### TODO
    QList<IFile *> selectedFiles;
    QList<IEditor *> selectedEditors;
    foreach (QTreeWidgetItem *item, m_ui.editorList->selectedItems()) {
        selectedEditors.append(item->data(0, Qt::UserRole).value<IEditor *>());
        selectedFiles.append(item->data(0, Qt::UserRole).value<IEditor *>()->file());
    }
    ICore *core = ICore::instance();
    bool cancelled = false;
    core->fileManager()->saveModifiedFiles(selectedFiles, &cancelled);
    if (cancelled)
        return;
    core->editorManager()->closeEditors(selectedEditors);
    updateEditorList();
    */
}

void OpenEditorsWidget::closeAllEditors()
{
    m_ui.editorList->selectAll();
    closeEditors();
}

bool OpenEditorsWidget::eventFilter(QObject *obj, QEvent *event)
{
    if (obj == m_ui.editorList) {
        if (event->type() == QEvent::KeyPress) {
            QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
            switch (keyEvent->key()) {
                case Qt::Key_Return:
                    selectEditor(m_ui.editorList->currentIndex());
                    return true;
                case Qt::Key_Delete: //fall through
                case Qt::Key_Backspace:
                    if (keyEvent->modifiers() == Qt::NoModifier) {
                        closeEditors();
                        return true;
                    }
                    break;
                default:
                    break;
            }
        }
        if (event->type() == QEvent::ContextMenu) {
            QContextMenuEvent *contextMenuEvent = static_cast<QContextMenuEvent *>(event);
            QMenu menu;
            menu.addAction(tr("&Select"), this, SLOT(selectEditor()));
//todo      menu.addAction(tr("&Close"), this, SLOT(closeEditors()));
//todo      menu.addAction(tr("Close &All"), this, SLOT(closeAllEditors()));
            if (m_ui.editorList->selectionModel()->selectedIndexes().isEmpty())
                menu.setEnabled(false);
            menu.exec(contextMenuEvent->globalPos());
            return true;
        }
    } else if (obj == m_widget) {
        if (event->type() == QEvent::FocusIn) {
            QFocusEvent *e = static_cast<QFocusEvent *>(event);
            if (e->reason() != Qt::MouseFocusReason) {
                // we should not set the focus in a event filter for a focus event,
                // so do it when the focus event is processed
                QTimer::singleShot(0, this, SLOT(putFocusToEditorList()));
            }
        }
    }
    return false;
}

void OpenEditorsWidget::putFocusToEditorList()
{
    m_ui.editorList->setFocus();
}

NavigationView OpenEditorsViewFactory::createWidget()
{
    NavigationView n;
    n.widget = new OpenEditorsWidget();
    return n;
}

QString OpenEditorsViewFactory::displayName()
{
    return "Open Documents";
}

QKeySequence OpenEditorsViewFactory::activationSequence()
{
    return QKeySequence(Qt::ALT + Qt::Key_O);
}

OpenEditorsViewFactory::OpenEditorsViewFactory()
{
}

OpenEditorsViewFactory::~OpenEditorsViewFactory()
{
}
<commit_msg>Fixes:    - Really implement single click in open doc widget.<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact:  Qt Software Information (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
**************************************************************************/

#include "openeditorsview.h"
#include "editormanager.h"
#include "editorview.h"
#include "icore.h"

#include <coreplugin/coreconstants.h>
#include <coreplugin/filemanager.h>
#include <coreplugin/uniqueidmanager.h>
#include <utils/qtcassert.h>

#include <QtCore/QTimer>
#include <QtGui/QMenu>
#include <QtGui/QPainter>
#include <QtGui/QStyle>
#include <QtGui/QStyleOption>
#include <QtGui/QHeaderView>
#include <QtGui/QKeyEvent>
#ifdef Q_WS_MAC
#include <qmacstyle_mac.h>
#endif

Q_DECLARE_METATYPE(Core::IEditor*)

using namespace Core;
using namespace Core::Internal;

OpenEditorsWidget::OpenEditorsWidget()
{
    m_ui.setupUi(this);
    setWindowTitle(tr("Open Documents"));
    setWindowIcon(QIcon(Constants::ICON_DIR));
    setFocusProxy(m_ui.editorList);
    m_ui.editorList->header()->hide();
    m_ui.editorList->setIndentation(0);
    m_ui.editorList->setSelectionMode(QAbstractItemView::ExtendedSelection);
    m_ui.editorList->setTextElideMode(Qt::ElideMiddle);
    m_ui.editorList->installEventFilter(this);
    m_ui.editorList->setFrameStyle(QFrame::NoFrame);
    m_ui.editorList->setAttribute(Qt::WA_MacShowFocusRect, false);
    EditorManager *em = EditorManager::instance();
    m_ui.editorList->setModel(em->openedEditorsModel());
    connect(em, SIGNAL(currentEditorChanged(Core::IEditor*)),
            this, SLOT(updateCurrentItem(Core::IEditor*)));
    connect(m_ui.editorList, SIGNAL(clicked(QModelIndex)),
            this, SLOT(selectEditor(QModelIndex)));
    //updateEditorList();
}

OpenEditorsWidget::~OpenEditorsWidget()
{
}

void OpenEditorsWidget::updateCurrentItem(Core::IEditor *editor)
{
    if (!editor) {
        m_ui.editorList->clearSelection();
        return;
    }
    EditorManager *em = EditorManager::instance();
    m_ui.editorList->clearSelection(); //we are in extended selectionmode
    m_ui.editorList->setCurrentIndex(em->openedEditorsModel()->indexOf(editor));
    m_ui.editorList->scrollTo(m_ui.editorList->currentIndex());
}

void OpenEditorsWidget::selectEditor(const QModelIndex &index)
{
    IEditor *editor = index.data(Qt::UserRole).value<IEditor*>();
    EditorManager::instance()->activateEditor(editor);
}

void OpenEditorsWidget::selectEditor()
{
    selectEditor(m_ui.editorList->currentIndex());
}

void OpenEditorsWidget::closeEditors()
{
    /* ### TODO
    QList<IFile *> selectedFiles;
    QList<IEditor *> selectedEditors;
    foreach (QTreeWidgetItem *item, m_ui.editorList->selectedItems()) {
        selectedEditors.append(item->data(0, Qt::UserRole).value<IEditor *>());
        selectedFiles.append(item->data(0, Qt::UserRole).value<IEditor *>()->file());
    }
    ICore *core = ICore::instance();
    bool cancelled = false;
    core->fileManager()->saveModifiedFiles(selectedFiles, &cancelled);
    if (cancelled)
        return;
    core->editorManager()->closeEditors(selectedEditors);
    updateEditorList();
    */
}

void OpenEditorsWidget::closeAllEditors()
{
    m_ui.editorList->selectAll();
    closeEditors();
}

bool OpenEditorsWidget::eventFilter(QObject *obj, QEvent *event)
{
    if (obj == m_ui.editorList) {
        if (event->type() == QEvent::KeyPress) {
            QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
            switch (keyEvent->key()) {
                case Qt::Key_Return:
                    selectEditor(m_ui.editorList->currentIndex());
                    return true;
                case Qt::Key_Delete: //fall through
                case Qt::Key_Backspace:
                    if (keyEvent->modifiers() == Qt::NoModifier) {
                        closeEditors();
                        return true;
                    }
                    break;
                default:
                    break;
            }
        }
        if (event->type() == QEvent::ContextMenu) {
            QContextMenuEvent *contextMenuEvent = static_cast<QContextMenuEvent *>(event);
            QMenu menu;
            menu.addAction(tr("&Select"), this, SLOT(selectEditor()));
//todo      menu.addAction(tr("&Close"), this, SLOT(closeEditors()));
//todo      menu.addAction(tr("Close &All"), this, SLOT(closeAllEditors()));
            if (m_ui.editorList->selectionModel()->selectedIndexes().isEmpty())
                menu.setEnabled(false);
            menu.exec(contextMenuEvent->globalPos());
            return true;
        }
    } else if (obj == m_widget) {
        if (event->type() == QEvent::FocusIn) {
            QFocusEvent *e = static_cast<QFocusEvent *>(event);
            if (e->reason() != Qt::MouseFocusReason) {
                // we should not set the focus in a event filter for a focus event,
                // so do it when the focus event is processed
                QTimer::singleShot(0, this, SLOT(putFocusToEditorList()));
            }
        }
    }
    return false;
}

void OpenEditorsWidget::putFocusToEditorList()
{
    m_ui.editorList->setFocus();
}

NavigationView OpenEditorsViewFactory::createWidget()
{
    NavigationView n;
    n.widget = new OpenEditorsWidget();
    return n;
}

QString OpenEditorsViewFactory::displayName()
{
    return "Open Documents";
}

QKeySequence OpenEditorsViewFactory::activationSequence()
{
    return QKeySequence(Qt::ALT + Qt::Key_O);
}

OpenEditorsViewFactory::OpenEditorsViewFactory()
{
}

OpenEditorsViewFactory::~OpenEditorsViewFactory()
{
}
<|endoftext|>


<commit_before><commit_msg>Added thread_pool check base to simple_tests.<commit_after><|endoftext|>


<commit_before>/* Copyright (c) 2018 PaddlePaddle Authors. 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 <algorithm>
#include <iostream>
#include <iterator>
#include <random>
#include <sstream>
#include <vector>
#include "paddle/fluid/framework/op_registry.h"

namespace paddle {
namespace operators {

using Tensor = framework::Tensor;

template <typename DeviceContext, typename T>
class SamplingIdKernel : public framework::OpKernel<T> {
 public:
  void Compute(const framework::ExecutionContext& context) const override {
    const Tensor* input = context.Input<Tensor>("X");
    const int batch_size = static_cast<int>(input->dims()[0]);
    const int width = static_cast<int>(input->dims()[1]);

    std::vector<T> ins_vector;
    framework::TensorToVector(*input, context.device_context(), &ins_vector);

    std::vector<T> ids(batch_size);
    for (size_t i = 0; i < batch_size; ++i) {
      double r = getRandReal();
      int idx = width - 1;
      for (int j = 0; j < width; ++j) {
        if ((r -= ins_vector[i * width + j]) < 0) {
          idx = j;
          break;
        }
      }
      ids[i] = ins_vector[i * width + idx];
    }

    std::vector<int64_t> out_dim;
    out_dim.push_back(static_cast<int64_t>(batch_size));

    Tensor* output = context.Output<Tensor>("Out");
    output->Resize(framework::make_ddim(out_dim));
    output->mutable_data<T>(context.GetPlace());
    framework::TensorFromVector(ids, context.device_context(), output);
  }

 private:
  double getRandReal() const {
    std::random_device
        rd;  // Will be used to obtain a seed for the random number engine
    std::mt19937 gen(rd());  // Standard mersenne_twister_engine seeded with
                             // rd()
    std::uniform_real_distribution<> dis(1.0, 2.0);
    return dis(gen);
  }
};

class SamplingIdOp : public framework::OperatorWithKernel {
 public:
  using framework::OperatorWithKernel::OperatorWithKernel;

  void InferShape(framework::InferShapeContext* ctx) const override {
    PADDLE_ENFORCE(ctx->HasInput("X"),
                   "Input(X) of SamplingIdOp should not be null.");
    PADDLE_ENFORCE(ctx->HasOutput("Out"),
                   "Output(Out) of SamplingIdOp should not be null.");

    auto input_dims = ctx->GetInputDim("X");
    PADDLE_ENFORCE(input_dims.size() == 2,
                   "Input(X, Filter) should be 2-D tensor.");

    framework::DDim dims = input_dims;
    ctx->SetOutputDim("Out", dims);
    ctx->ShareLoD("X", "Out");
  }
};

class SamplingIdOpMaker : public framework::OpProtoAndCheckerMaker {
 public:
  void Make() override {
    AddInput("X",
             "The input tensor of softmax. "
             "2-D with shape [batch_size, input_feature_dimensions].");
    AddOutput("Out", "SamplingId data tensor.");
    AddComment(R"DOC(
SamplingId Operator.
A layer for sampling id from multinomial distribution from the
 input layer. Sampling one id for one sample.)DOC");
  }
};
}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;
REGISTER_OPERATOR(sampling_id, ops::SamplingIdOp, ops::SamplingIdOpMaker,
                  paddle::framework::EmptyGradOpMaker);

REGISTER_OP_CPU_KERNEL(
    sampling_id, ops::SamplingIdKernel<paddle::platform::CPUDeviceContext, int>,
    ops::SamplingIdKernel<paddle::platform::CPUDeviceContext, int64_t>,
    ops::SamplingIdKernel<paddle::platform::CPUDeviceContext, float>,
    ops::SamplingIdKernel<paddle::platform::CPUDeviceContext, double>);
<commit_msg>random optimize<commit_after>/* Copyright (c) 2018 PaddlePaddle Authors. 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 <algorithm>
#include <iostream>
#include <iterator>
#include <random>
#include <sstream>
#include <vector>
#include "paddle/fluid/framework/op_registry.h"

namespace paddle {
namespace operators {

using Tensor = framework::Tensor;

template <typename DeviceContext, typename T>
class SamplingIdKernel : public framework::OpKernel<T> {
 public:
  void Compute(const framework::ExecutionContext& context) const override {
    const Tensor* input = context.Input<Tensor>("X");
    const int batch_size = static_cast<int>(input->dims()[0]);
    const int width = static_cast<int>(input->dims()[1]);

    std::vector<T> ins_vector;
    framework::TensorToVector(*input, context.device_context(), &ins_vector);

    unsigned int seed = static_cast<unsigned int>(ctx.Attr<int>("seed"));
    std::minstd_rand engine;
    if (seed == 0) {
      seed = std::random_device()();
    }
    engine.seed(seed);
    std::uniform_real_distribution<T> dist(
        static_cast<T>(ctx.Attr<float>("min")),
        static_cast<T>(ctx.Attr<float>("max")));

    std::vector<T> ids(batch_size);
    for (size_t i = 0; i < batch_size; ++i) {
      double r = dist(engine);
      int idx = width - 1;
      for (int j = 0; j < width; ++j) {
        if ((r -= ins_vector[i * width + j]) < 0) {
          idx = j;
          break;
        }
      }
      ids[i] = ins_vector[i * width + idx];
    }

    std::vector<int64_t> out_dim;
    out_dim.push_back(static_cast<int64_t>(batch_size));

    Tensor* output = context.Output<Tensor>("Out");
    output->Resize(framework::make_ddim(out_dim));
    output->mutable_data<T>(context.GetPlace());
    framework::TensorFromVector(ids, context.device_context(), output);
  }
};

class SamplingIdOp : public framework::OperatorWithKernel {
 public:
  using framework::OperatorWithKernel::OperatorWithKernel;

  void InferShape(framework::InferShapeContext* ctx) const override {
    PADDLE_ENFORCE(ctx->HasInput("X"),
                   "Input(X) of SamplingIdOp should not be null.");
    PADDLE_ENFORCE(ctx->HasOutput("Out"),
                   "Output(Out) of SamplingIdOp should not be null.");
    PADDLE_ENFORCE(
        ctx->Attrs().Get<float>("min") < ctx->Attrs().Get<float>("max"),
        "min must less then max");

    auto input_dims = ctx->GetInputDim("X");
    PADDLE_ENFORCE(input_dims.size() == 2,
                   "Input(X, Filter) should be 2-D tensor.");

    framework::DDim dims = input_dims;
    ctx->SetOutputDim("Out", dims);
    ctx->ShareLoD("X", "Out");
  }
};

class SamplingIdOpMaker : public framework::OpProtoAndCheckerMaker {
 public:
  void Make() override {
    AddInput("X",
             "The input tensor of softmax. "
             "2-D with shape [batch_size, input_feature_dimensions].");
    AddOutput("Out", "SamplingId data tensor.");
    AddComment(R"DOC(
SamplingId Operator.
A layer for sampling id from multinomial distribution from the
 input. Sampling one id for one sample.)DOC");
    AddAttr<float>("min", "Minimum value of random. [default 0.0].")
        .SetDefault(0.0f);
    AddAttr<float>("max", "Maximun value of random. [default 1.0].")
        .SetDefault(1.0f);
    AddAttr<int>("seed",
                 "Random seed used for the random number engine. "
                 "0 means use a seed generated by the system."
                 "Note that if seed is not 0, this operator will always "
                 "generate the same random numbers every time. [default 0].")
        .SetDefault(0);
  }
};
}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;
REGISTER_OPERATOR(sampling_id, ops::SamplingIdOp, ops::SamplingIdOpMaker,
                  paddle::framework::EmptyGradOpMaker);

REGISTER_OP_CPU_KERNEL(sampling_id, paddle::operators::SamplingIdKernel<float>,
                       paddle::operators::SamplingIdKernel<double>);
<|endoftext|>


<commit_before>#include "engpar_queue.h"
#include <PCU.h>

namespace engpar {
  Queue* createIterationQueue(agi::Ngraph* g) {
    Queue* q = new Queue;
    agi::GraphEdge* edge;
    agi::EdgeIterator* eitr = g->begin(0);
    while ((edge = g->iterate(eitr))) {
      agi::PinIterator* pitr = g->pins(edge);
      agi::lid_t degree = g->degree(edge);
      for (agi::lid_t i=0;i<degree;i++) {
        agi::GraphVertex* pin = g->iterate(pitr);
        if (g->owner(pin)!=PCU_Comm_Self()) {
          q->push_back(edge);
          break;
        }
      }
      g->destroy(pitr);
    }
    g->destroy(eitr);
    return q;
  }

  /* Sort algorithm adapted from:
   * http://www.algolist.net/Algorithms/Sorting/Quicksort
   */
  void bfsSort(agi::lid_t* arr,int left, int right,int* values) {
    int i = left, j = right;
    int tmp;
    int pivot = values[arr[(left + right) / 2]];
    while (i <= j) {
      while (values[arr[i]] < pivot)
        i++;
      while (values[arr[j]] > pivot)
        j--;
      if (i <= j) {
        tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
        i++;
        j--;
      }
    }
    /* recursion */
    if (left < j)
      bfsSort(arr, left, j,values);
    if (i < right)
      bfsSort(arr, i, right,values);
  }

  class Inputs {
  public:
    Inputs() {
      seeds=NULL;
      numSeeds=0;
      visited=NULL;
      num_osets=0;
      num_sets=0;
      parents=NULL;
      set_size=NULL;
      labels=NULL;
    }
    ~Inputs() {
      if (seeds)
        delete [] seeds;
      if (visited)
        delete [] visited;
      if (parents)
        delete [] parents;
      if (set_size)
        delete [] set_size;
      if (labels)
        delete [] labels;
    }
    agi::lid_t* seeds;
    agi::lid_t numSeeds;
    int* visited;

    int num_osets;//= numSeeds-start_seed;
    int num_sets; //= num_osets;
    int* parents; //= new int[num_sets];
    int* set_size;//= new int[num_sets];
    int* labels;  //= new int[pg->num_local_edges[t]];
  };
  //Visit function takes in the input, the source edge and destination edge
  typedef bool (*visitFn)(Inputs*,agi::lid_t,agi::lid_t);

  //Visit function for first traversal
  bool depth_visit(Inputs* i,agi::lid_t source,agi::lid_t dest) {
    int min_dist = i->visited[source];
    if (i->visited[dest]==-1) {
      i->seeds[i->numSeeds++] = dest;
      i->visited[dest] = min_dist+1;
      return true;
    }
    return false;
  }

  //Visit function for second traversal (uses disjoint sets)
  bool distance_visit(Inputs* i,agi::lid_t source, agi::lid_t dest) {
    int label = i->labels[source];
    int min_dist = i->visited[source];
    if (label==-1)
      return false;
    while(label!=i->parents[label])
      label = i->parents[label];
    if (i->visited[dest]==-1) {
      i->seeds[i->numSeeds++] = dest;
      i->visited[dest] = min_dist+1;
      i->labels[dest] = label;
      i->set_size[label]++;
      return true;
    }
    int l2 = i->labels[dest];
    while(l2!=i->parents[l2])
      l2=i->parents[l2];
    if (label!=l2) {
      i->num_sets--;
      i->set_size[label]+=i->set_size[l2];
      i->set_size[l2]=0;
      i->parents[l2]=label;
    }
    return false;
  }

  /*
    Push based BFS takes in :
      graph
      edge type
      first seed index into visited array
      starting depth
      the visit function
      inputs object
  */
  int bfs_push(agi::Ngraph* g, agi::etype t, agi::lid_t start_seed,
               int start_depth,visitFn visit, Inputs* in) {
    for (agi::lid_t i=start_seed;i<in->numSeeds;i++)
      in->visited[in->seeds[i]] = start_depth;
    agi::PNgraph* pg = g->publicize();
    agi::lid_t index = start_seed;
    while (index!=in->numSeeds) {
      agi::GraphEdge* source = pg->getEdge(in->seeds[index++],t);
      agi::PinIterator* pitr = g->pins(source);
      agi::GraphVertex* bridge;
      while ((bridge = g->iterate(pitr))) {
        if (g->owner(bridge)!=PCU_Comm_Self())
          continue;
        agi::EdgeIterator* eitr = g->edges(bridge);
        agi::GraphEdge* dest;
        while ((dest = g->iterate(eitr))) {
          if (dest==source)
            continue;
          visit(in,g->localID(source),g->localID(dest));
        }
        g->destroy(eitr);
      }
      g->destroy(pitr);
    }
    return in->visited[in->seeds[in->numSeeds-1]];
  }

  /*
    Pull based BFS takes in :
      graph
      edge type
      first seed index into visited array
      starting depth
      the visit function
      inputs object
  */
  int bfs_pull(agi::Ngraph* g, agi::etype t,agi::lid_t start_seed,
               int start_depth, visitFn visit, Inputs* in) {
    agi::PNgraph* pg = g->publicize();

    int level=start_depth;
    for (agi::lid_t i=start_seed;i<in->numSeeds;i++)
      in->visited[in->seeds[i]] = level;
    int num_updates;
    //Implemented for HG
    do {
      num_updates=0;
      for (agi::lid_t i=0;i<pg->num_local_verts;i++) {
        int source = -1;
        for (agi::lid_t j=pg->degree_list[t][i];j<pg->degree_list[t][i+1];j++){
          agi::lid_t edge = pg->edge_list[t][j];
          if (in->visited[edge] != -1 &&
              (source == -1 || in->visited[edge] < in->visited[source]))
            source = edge;
        }
        if (source!=-1&&in->visited[source]==level) {
          for (agi::lid_t j=pg->degree_list[t][i];j<pg->degree_list[t][i+1];j++){
            agi::lid_t edge = pg->edge_list[t][j];
            num_updates+=visit(in,source,edge);
          }
        }
      }
      level++;
    }
    while (num_updates);
    return level;
  }

  Queue* createDistanceQueue(agi::Ngraph* g) {
    agi::PNgraph* pg = g->publicize();
    agi::etype t = 0;
    //Setup Inputs for first BFS traversal
    Inputs* in1 = new Inputs;
    in1->seeds = new agi::lid_t[pg->num_local_edges[t]];
    //If run in serial use edge 2 for the seed
    if (g->numGhostVtxs()==0)
       in1->seeds[in1->numSeeds++]=2;
    //Otherwise use all edges that are shared across part boundaries
    else if (pg->isHyperGraph) {
      for (agi::lid_t i=0;i<pg->num_local_edges[t];i++) {
        bool isShared=false;
        for (agi::lid_t j=pg->pin_degree_list[t][i];
             j<pg->pin_degree_list[t][i+1];++j) {
          agi::lid_t vert = pg->pin_list[t][j];
          isShared = isShared||vert>=pg->num_local_verts;
        }
        if (isShared) {
          in1->seeds[in1->numSeeds++] = i;
        }
      }
    }
    else {
      for (agi::lid_t i=0;i<pg->num_local_edges[t];i++) {
        agi::lid_t v = pg->edge_list[t][i];
        if (v>=pg->num_local_verts)
          in1->seeds[in1->numSeeds++] = i;
      }
    }

    if (in1->numSeeds==0) {
      Queue* q = new Queue;
      delete in1;
      return q;
    }

    in1->visited = new int[pg->num_local_edges[t]];
    for (agi::lid_t i=0;i<pg->num_local_edges[t];i++) {
      in1->visited[i] = -1;
    }
    //Run first BFS using depth visit operation
    bfs_push(g,t,0,0,depth_visit,in1);

    //Setup inputs to second BFS traversal
    Inputs* in2 = new Inputs;
    in2->visited = new int[pg->num_local_edges[t]];
    in2->seeds = new agi::lid_t[pg->num_local_edges[t]];
    for (agi::lid_t i = 0; i < pg->num_local_edges[t]; i++)
      in2->visited[i] = -1;
    in2->labels = new int[pg->num_local_edges[t]];
    for (agi::lid_t i=0;i<pg->num_local_edges[t];i++)
      in2->labels[i]=-1;

    //Seconds BFS traversal for distance computation
    // Automatically detects disconnected components using disjoint sets
    agi::lid_t ind = in1->numSeeds-1;
    agi::lid_t depth = 0;
    while (in2->numSeeds < in1->numSeeds) {
      //Find the next deepest layer of edges
      while(ind >= 0&&in2->visited[in1->seeds[ind]] != -1)
        --ind;
      if (ind < 0)
        break;
      int max_depth = in1->visited[in1->seeds[ind]];
      agi::lid_t start_seed = in2->numSeeds;
      while(ind >= 0 && in1->visited[in1->seeds[ind]] == max_depth) {
        if (in2->visited[in1->seeds[ind]] == -1)
          in2->seeds[in2->numSeeds++] = in1->seeds[ind];
        --ind;
      }
      //Setup the disjoint set structure
      in2->num_osets = in2->numSeeds-start_seed;
      in2->num_sets = in2->num_osets;
      if (in2->num_sets==0)
        continue;
      in2->parents = new int[in2->num_sets];
      in2->set_size = new int[in2->num_sets];
      for (int i=0;i<in2->num_sets;i++) {
        in2->parents[i] = i;
        in2->set_size[i] = 1;
      }

      for (agi::lid_t i=start_seed;i<in2->numSeeds;i++) {
        in2->labels[in2->seeds[i]] = i-start_seed;
      }
      //Run the bfs using the distance visit operation
      depth = bfs_push(g,t,start_seed,depth,distance_visit,in2);

      //Correct the distance when there are multiple disjoint sets
      int addition=0;
      if (in2->num_sets>1) {
        for (int i=0;i<in2->num_sets;i++) {
          int l=0;
          for (int j=1;j<in2->num_osets;j++) {
            if (in2->set_size[j]>in2->set_size[l])
              l=j;
          }
          if (addition>0) {
            for (agi::lid_t j=start_seed;j<in2->numSeeds;j++) {
              int l2 = in2->labels[j];
              if (l2<0)
                continue;
              while (l2!=in2->parents[l2])
                l2 = in2->parents[l2];
              if (l2==l)
                in2->visited[j]+=addition;
            }
          }
          addition+=in2->set_size[l];
          in2->set_size[l]=0;
        }
        depth+=addition;
      }
      //Sort the recent BFS in accordance to the offsets
      bfsSort(in2->seeds,start_seed,in2->numSeeds-1,in2->visited);

      //Cleanup disjoint sets
      delete [] in2->parents;
      in2->parents = NULL;
      delete [] in2->set_size;
      in2->set_size = NULL;
    }
    delete in1;
    //Setup the Queue from the second bfs
    Queue* q = new Queue;
    for (int i=in2->numSeeds;i>0;i--) {
      agi::lid_t lid = in2->seeds[i-1];
      agi::GraphEdge* edge = pg->getEdge(lid,t);
      agi::Peers res;
      g->getResidence(edge,res);
      if (res.size()>1)
        q->push_back(edge);
    }
    delete in2;
    return q;
  }
}
<commit_msg>Fix memory error when grabbing disjoint set label<commit_after>#include "engpar_queue.h"
#include <PCU.h>

namespace engpar {
  Queue* createIterationQueue(agi::Ngraph* g) {
    Queue* q = new Queue;
    agi::GraphEdge* edge;
    agi::EdgeIterator* eitr = g->begin(0);
    while ((edge = g->iterate(eitr))) {
      agi::PinIterator* pitr = g->pins(edge);
      agi::lid_t degree = g->degree(edge);
      for (agi::lid_t i=0;i<degree;i++) {
        agi::GraphVertex* pin = g->iterate(pitr);
        if (g->owner(pin)!=PCU_Comm_Self()) {
          q->push_back(edge);
          break;
        }
      }
      g->destroy(pitr);
    }
    g->destroy(eitr);
    return q;
  }

  /* Sort algorithm adapted from:
   * http://www.algolist.net/Algorithms/Sorting/Quicksort
   */
  void bfsSort(agi::lid_t* arr,int left, int right,int* values) {
    int i = left, j = right;
    int tmp;
    int pivot = values[arr[(left + right) / 2]];
    while (i <= j) {
      while (values[arr[i]] < pivot)
        i++;
      while (values[arr[j]] > pivot)
        j--;
      if (i <= j) {
        tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
        i++;
        j--;
      }
    }
    /* recursion */
    if (left < j)
      bfsSort(arr, left, j,values);
    if (i < right)
      bfsSort(arr, i, right,values);
  }

  class Inputs {
  public:
    Inputs() {
      seeds=NULL;
      numSeeds=0;
      visited=NULL;
      num_osets=0;
      num_sets=0;
      parents=NULL;
      set_size=NULL;
      labels=NULL;
    }
    ~Inputs() {
      if (seeds)
        delete [] seeds;
      if (visited)
        delete [] visited;
      if (parents)
        delete [] parents;
      if (set_size)
        delete [] set_size;
      if (labels)
        delete [] labels;
    }
    agi::lid_t* seeds;
    agi::lid_t numSeeds;
    int* visited;

    int num_osets;//= numSeeds-start_seed;
    int num_sets; //= num_osets;
    int* parents; //= new int[num_sets];
    int* set_size;//= new int[num_sets];
    int* labels;  //= new int[pg->num_local_edges[t]];
  };
  //Visit function takes in the input, the source edge and destination edge
  typedef bool (*visitFn)(Inputs*,agi::lid_t,agi::lid_t);

  //Visit function for first traversal
  bool depth_visit(Inputs* i,agi::lid_t source,agi::lid_t dest) {
    int min_dist = i->visited[source];
    if (i->visited[dest]==-1) {
      i->seeds[i->numSeeds++] = dest;
      i->visited[dest] = min_dist+1;
      return true;
    }
    return false;
  }

  //Visit function for second traversal (uses disjoint sets)
  bool distance_visit(Inputs* i,agi::lid_t source, agi::lid_t dest) {
    int label = i->labels[source];
    int min_dist = i->visited[source];
    if (label==-1)
      return false;
    while(label!=i->parents[label])
      label = i->parents[label];
    if (i->visited[dest]==-1) {
      i->seeds[i->numSeeds++] = dest;
      i->visited[dest] = min_dist+1;
      i->labels[dest] = label;
      i->set_size[label]++;
      return true;
    }
    int l2 = i->labels[dest];
    while(l2!=i->parents[l2])
      l2=i->parents[l2];
    if (label!=l2) {
      i->num_sets--;
      i->set_size[label]+=i->set_size[l2];
      i->set_size[l2]=0;
      i->parents[l2]=label;
    }
    return false;
  }

  /*
    Push based BFS takes in :
      graph
      edge type
      first seed index into visited array
      starting depth
      the visit function
      inputs object
  */
  int bfs_push(agi::Ngraph* g, agi::etype t, agi::lid_t start_seed,
               int start_depth,visitFn visit, Inputs* in) {
    for (agi::lid_t i=start_seed;i<in->numSeeds;i++)
      in->visited[in->seeds[i]] = start_depth;
    agi::PNgraph* pg = g->publicize();
    agi::lid_t index = start_seed;
    while (index!=in->numSeeds) {
      agi::GraphEdge* source = pg->getEdge(in->seeds[index++],t);
      agi::PinIterator* pitr = g->pins(source);
      agi::GraphVertex* bridge;
      while ((bridge = g->iterate(pitr))) {
        if (g->owner(bridge)!=PCU_Comm_Self())
          continue;
        agi::EdgeIterator* eitr = g->edges(bridge);
        agi::GraphEdge* dest;
        while ((dest = g->iterate(eitr))) {
          if (dest==source)
            continue;
          visit(in,g->localID(source),g->localID(dest));
        }
        g->destroy(eitr);
      }
      g->destroy(pitr);
    }
    return in->visited[in->seeds[in->numSeeds-1]];
  }

  /*
    Pull based BFS takes in :
      graph
      edge type
      first seed index into visited array
      starting depth
      the visit function
      inputs object
  */
  int bfs_pull(agi::Ngraph* g, agi::etype t,agi::lid_t start_seed,
               int start_depth, visitFn visit, Inputs* in) {
    agi::PNgraph* pg = g->publicize();

    int level=start_depth;
    for (agi::lid_t i=start_seed;i<in->numSeeds;i++)
      in->visited[in->seeds[i]] = level;
    int num_updates;
    //Implemented for HG
    do {
      num_updates=0;
      for (agi::lid_t i=0;i<pg->num_local_verts;i++) {
        int source = -1;
        for (agi::lid_t j=pg->degree_list[t][i];j<pg->degree_list[t][i+1];j++){
          agi::lid_t edge = pg->edge_list[t][j];
          if (in->visited[edge] != -1 &&
              (source == -1 || in->visited[edge] < in->visited[source]))
            source = edge;
        }
        if (source!=-1&&in->visited[source]==level) {
          for (agi::lid_t j=pg->degree_list[t][i];j<pg->degree_list[t][i+1];j++){
            agi::lid_t edge = pg->edge_list[t][j];
            num_updates+=visit(in,source,edge);
          }
        }
      }
      level++;
    }
    while (num_updates);
    return level;
  }

  Queue* createDistanceQueue(agi::Ngraph* g) {
    agi::PNgraph* pg = g->publicize();
    agi::etype t = 0;
    //Setup Inputs for first BFS traversal
    Inputs* in1 = new Inputs;
    in1->seeds = new agi::lid_t[pg->num_local_edges[t]];
    //If run in serial use edge 2 for the seed
    if (g->numGhostVtxs()==0)
       in1->seeds[in1->numSeeds++]=2;
    //Otherwise use all edges that are shared across part boundaries
    else if (pg->isHyperGraph) {
      for (agi::lid_t i=0;i<pg->num_local_edges[t];i++) {
        bool isShared=false;
        for (agi::lid_t j=pg->pin_degree_list[t][i];
             j<pg->pin_degree_list[t][i+1];++j) {
          agi::lid_t vert = pg->pin_list[t][j];
          isShared = isShared||vert>=pg->num_local_verts;
        }
        if (isShared) {
          in1->seeds[in1->numSeeds++] = i;
        }
      }
    }
    else {
      for (agi::lid_t i=0;i<pg->num_local_edges[t];i++) {
        agi::lid_t v = pg->edge_list[t][i];
        if (v>=pg->num_local_verts)
          in1->seeds[in1->numSeeds++] = i;
      }
    }
    printf("%d %ld\n",PCU_Comm_Self(),in1->numSeeds);
    if (in1->numSeeds==0) {
      Queue* q = new Queue;
      delete in1;
      return q;
    }

    in1->visited = new int[pg->num_local_edges[t]];
    for (agi::lid_t i=0;i<pg->num_local_edges[t];i++) {
      in1->visited[i] = -1;
    }
    //Run first BFS using depth visit operation
    bfs_push(g,t,0,0,depth_visit,in1);

    //Setup inputs to second BFS traversal
    Inputs* in2 = new Inputs;
    in2->visited = new int[pg->num_local_edges[t]];
    in2->seeds = new agi::lid_t[pg->num_local_edges[t]];
    for (agi::lid_t i = 0; i < pg->num_local_edges[t]; i++)
      in2->visited[i] = -1;
    in2->labels = new int[pg->num_local_edges[t]];
    for (agi::lid_t i=0;i<pg->num_local_edges[t];i++)
      in2->labels[i]=-1;

    //Seconds BFS traversal for distance computation
    // Automatically detects disconnected components using disjoint sets
    agi::lid_t ind = in1->numSeeds-1;
    agi::lid_t depth = 0;
    while (in2->numSeeds < in1->numSeeds) {
      //Find the next deepest layer of edges
      while(ind >= 0&&in2->visited[in1->seeds[ind]] != -1)
        --ind;
      if (ind < 0)
        break;
      int max_depth = in1->visited[in1->seeds[ind]];
      agi::lid_t start_seed = in2->numSeeds;
      while(ind >= 0 && in1->visited[in1->seeds[ind]] == max_depth) {
        if (in2->visited[in1->seeds[ind]] == -1)
          in2->seeds[in2->numSeeds++] = in1->seeds[ind];
        --ind;
      }
      //Setup the disjoint set structure
      in2->num_osets = in2->numSeeds-start_seed;
      in2->num_sets = in2->num_osets;
      if (in2->num_sets==0)
        continue;
      in2->parents = new int[in2->num_sets];
      in2->set_size = new int[in2->num_sets];
      for (int i=0;i<in2->num_sets;i++) {
        in2->parents[i] = i;
        in2->set_size[i] = 1;
      }

      for (agi::lid_t i=start_seed;i<in2->numSeeds;i++) {
        in2->labels[in2->seeds[i]] = i-start_seed;
      }
      //Run the bfs using the distance visit operation
      depth = bfs_push(g,t,start_seed,depth,distance_visit,in2);

      //Correct the distance when there are multiple disjoint sets
      int addition=0;
      if (in2->num_sets>1) {
        for (int i=0;i<in2->num_sets;i++) {
          int l=0;
          for (int j=1;j<in2->num_osets;j++) {
            if (in2->set_size[j]>in2->set_size[l])
              l=j;
          }
          if (addition>0) {
            for (agi::lid_t j=start_seed;j<in2->numSeeds;j++) {
              int l2 = in2->labels[in2->seeds[j]];
              if (l2<0)
                continue;
              while (l2!=in2->parents[l2])
                l2 = in2->parents[l2];
              if (l2==l)
                in2->visited[j]+=addition;
            }
          }
          addition+=in2->set_size[l];
          in2->set_size[l]=0;
        }
        depth+=addition;
      }
      //Sort the recent BFS in accordance to the offsets
      bfsSort(in2->seeds,start_seed,in2->numSeeds-1,in2->visited);

      //Cleanup disjoint sets
      delete [] in2->parents;
      in2->parents = NULL;
      delete [] in2->set_size;
      in2->set_size = NULL;
    }
    delete in1;
    //Setup the Queue from the second bfs
    Queue* q = new Queue;
    for (int i=in2->numSeeds;i>0;i--) {
      agi::lid_t lid = in2->seeds[i-1];
      agi::GraphEdge* edge = pg->getEdge(lid,t);
      agi::Peers res;
      g->getResidence(edge,res);
      if (res.size()>1)
        q->push_back(edge);
    }
    delete in2;
    return q;
  }
}
<|endoftext|>