text:
using ::testing::_;
using ::testing::AtLeast;
using ::testing::InvokeWithoutArgs;
using ::testing::Return;
using ::testing::SaveArg;
using media::MockVideoCaptureEventHandler;

namespace content {

class MockVideoCaptureMessageFilter : public VideoCaptureMessageFilter {
 public:
  MockVideoCaptureMessageFilter() : VideoCaptureMessageFilter() {}

  // Filter implementation.
  MOCK_METHOD1(Send, bool(IPC::Message* message));

 protected:
  virtual ~MockVideoCaptureMessageFilter() {}

 private:
  DISALLOW_COPY_AND_ASSIGN(MockVideoCaptureMessageFilter);
};

class VideoCaptureImplTest : public ::testing::Test {
 public:
  class MockVideoCaptureImpl : public VideoCaptureImpl {
   public:
    MockVideoCaptureImpl(const media::VideoCaptureSessionId id,
                         VideoCaptureMessageFilter* filter)
        : VideoCaptureImpl(id, filter) {
    }
    virtual ~MockVideoCaptureImpl() {}

    // Override Send() to mimic device to send events.
    virtual void Send(IPC::Message* message) OVERRIDE {
      CHECK(message);

      // In this method, messages are sent to the according handlers as if
      // we are the device.
      bool handled = true;
      IPC_BEGIN_MESSAGE_MAP(MockVideoCaptureImpl, *message)
        IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Start, DeviceStartCapture)
        IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Pause, DevicePauseCapture)
        IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Stop, DeviceStopCapture)
        IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_BufferReady,
                            DeviceReceiveEmptyBuffer)
        IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_GetDeviceSupportedFormats,
                            DeviceGetSupportedFormats)
        IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_GetDeviceFormatsInUse,
                            DeviceGetFormatsInUse)
        IPC_MESSAGE_UNHANDLED(handled = false)
      IPC_END_MESSAGE_MAP()
      EXPECT_TRUE(handled);
      delete message;
    }

    void DeviceStartCapture(int device_id,
                            media::VideoCaptureSessionId session_id,
                            const media::VideoCaptureParams& params) {
      OnStateChanged(VIDEO_CAPTURE_STATE_STARTED);
    }

    void DevicePauseCapture(int device_id) {}

    void DeviceStopCapture(int device_id) {
      OnStateChanged(VIDEO_CAPTURE_STATE_STOPPED);
    }

    void DeviceReceiveEmptyBuffer(int device_id,
                                  int buffer_id,
                                  uint32 sync_point) {}

    void DeviceGetSupportedFormats(int device_id,
                                   media::VideoCaptureSessionId session_id) {
      // When the mock message filter receives a request for the device
      // supported formats, replies immediately with an empty format list.
      OnDeviceSupportedFormatsEnumerated(
          media::VideoCaptureFormats());
    }

    void DeviceGetFormatsInUse(int device_id,
                               media::VideoCaptureSessionId session_id) {
      OnDeviceFormatsInUseReceived(media::VideoCaptureFormats());
    }
  };

  VideoCaptureImplTest() {
    params_small_.requested_format = media::VideoCaptureFormat(
        gfx::Size(176, 144), 30, media::PIXEL_FORMAT_I420);

    params_large_.requested_format = media::VideoCaptureFormat(
        gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420);

    child_process_.reset(new ChildProcess());

    message_filter_ = new MockVideoCaptureMessageFilter;
    session_id_ = 1;

    video_capture_impl_ = new MockVideoCaptureImpl(
        session_id_, message_filter_.get());

    video_capture_impl_->device_id_ = 2;
  }

  virtual ~VideoCaptureImplTest() {
    delete video_capture_impl_;
  }

 protected:
  base::MessageLoop message_loop_;
  base::RunLoop run_loop_;
  scoped_ptr<ChildProcess> child_process_;
  scoped_refptr<MockVideoCaptureMessageFilter> message_filter_;
  media::VideoCaptureSessionId session_id_;
  MockVideoCaptureImpl* video_capture_impl_;
  media::VideoCaptureParams params_small_;
  media::VideoCaptureParams params_large_;

 private:
  DISALLOW_COPY_AND_ASSIGN(VideoCaptureImplTest);
};

TEST_F(VideoCaptureImplTest, Simple) {
  // Execute SetCapture() and StopCapture() for one client.
  scoped_ptr<MockVideoCaptureEventHandler> client(
      new MockVideoCaptureEventHandler);

  EXPECT_CALL(*client, OnStarted(_));
  EXPECT_CALL(*client, OnStopped(_));
  EXPECT_CALL(*client, OnRemoved(_));

  video_capture_impl_->StartCapture(client.get(), params_small_);
  video_capture_impl_->StopCapture(client.get());
  video_capture_impl_->DeInit(
      media::BindToCurrentLoop(run_loop_.QuitClosure()));
  run_loop_.Run();
}

TEST_F(VideoCaptureImplTest, TwoClientsInSequence) {
  // Execute SetCapture() and StopCapture() for 2 clients in sequence.
  scoped_ptr<MockVideoCaptureEventHandler> client1(
      new MockVideoCaptureEventHandler);
  scoped_ptr<MockVideoCaptureEventHandler> client2(
      new MockVideoCaptureEventHandler);

  EXPECT_CALL(*client1, OnStarted(_));
  EXPECT_CALL(*client1, OnStopped(_));
  EXPECT_CALL(*client1, OnRemoved(_));
  EXPECT_CALL(*client2, OnStarted(_));
  EXPECT_CALL(*client2, OnStopped(_));
  EXPECT_CALL(*client2, OnRemoved(_));

  video_capture_impl_->StartCapture(client1.get(), params_small_);
  video_capture_impl_->StopCapture(client1.get());
  video_capture_impl_->StartCapture(client2.get(), params_small_);
  video_capture_impl_->StopCapture(client2.get());
  video_capture_impl_->DeInit(
      media::BindToCurrentLoop(run_loop_.QuitClosure()));
  run_loop_.Run();
}

TEST_F(VideoCaptureImplTest, LargeAndSmall) {
  // Execute SetCapture() and StopCapture() for 2 clients simultaneously.
  // The large client starts first and stops first.
  scoped_ptr<MockVideoCaptureEventHandler> client_small(
      new MockVideoCaptureEventHandler);
  scoped_ptr<MockVideoCaptureEventHandler> client_large(
      new MockVideoCaptureEventHandler);

  EXPECT_CALL(*client_large, OnStarted(_));
  EXPECT_CALL(*client_small, OnStarted(_));
  EXPECT_CALL(*client_large, OnStopped(_));
  EXPECT_CALL(*client_large, OnRemoved(_));
  EXPECT_CALL(*client_small, OnStopped(_));
  EXPECT_CALL(*client_small, OnRemoved(_));

  video_capture_impl_->StartCapture(client_large.get(), params_large_);
  video_capture_impl_->StartCapture(client_small.get(), params_small_);
  video_capture_impl_->StopCapture(client_large.get());
  video_capture_impl_->StopCapture(client_small.get());
  video_capture_impl_->DeInit(
      media::BindToCurrentLoop(run_loop_.QuitClosure()));
  run_loop_.Run();
}

TEST_F(VideoCaptureImplTest, SmallAndLarge) {
  // Execute SetCapture() and StopCapture() for 2 clients simultaneously.
  // The small client starts first and stops first.
  scoped_ptr<MockVideoCaptureEventHandler> client_small(
      new MockVideoCaptureEventHandler);
  scoped_ptr<MockVideoCaptureEventHandler> client_large(
      new MockVideoCaptureEventHandler);

  EXPECT_CALL(*client_small, OnStarted(_));
  EXPECT_CALL(*client_large, OnStarted(_));
  EXPECT_CALL(*client_small, OnStopped(_));
  EXPECT_CALL(*client_small, OnRemoved(_));
  EXPECT_CALL(*client_large, OnStopped(_));
  EXPECT_CALL(*client_large, OnRemoved(_));

  video_capture_impl_->StartCapture(client_small.get(), params_small_);
  video_capture_impl_->StartCapture(client_large.get(), params_large_);
  video_capture_impl_->StopCapture(client_small.get());
  video_capture_impl_->StopCapture(client_large.get());
  video_capture_impl_->DeInit(
      media::BindToCurrentLoop(run_loop_.QuitClosure()));
  run_loop_.Run();
}

// Check that a request to GetDeviceSupportedFormats() ends up eventually in the
// provided callback.
TEST_F(VideoCaptureImplTest, GetDeviceFormats) {
  scoped_ptr<MockVideoCaptureEventHandler> client(
      new MockVideoCaptureEventHandler);

  EXPECT_CALL(*client, OnDeviceSupportedFormatsEnumerated(_));

  const base::Callback<void(const media::VideoCaptureFormats&)>
      callback = base::Bind(
          &MockVideoCaptureEventHandler::OnDeviceSupportedFormatsEnumerated,
          base::Unretained(client.get()));
  video_capture_impl_->GetDeviceSupportedFormats(callback);
  video_capture_impl_->DeInit(
      media::BindToCurrentLoop(run_loop_.QuitClosure()));
  run_loop_.Run();
}

// Check that two requests to GetDeviceSupportedFormats() end up eventually
// calling the provided callbacks.
TEST_F(VideoCaptureImplTest, TwoClientsGetDeviceFormats) {
  scoped_ptr<MockVideoCaptureEventHandler> client1(
      new MockVideoCaptureEventHandler);
  scoped_ptr<MockVideoCaptureEventHandler> client2(
      new MockVideoCaptureEventHandler);

  EXPECT_CALL(*client1, OnDeviceSupportedFormatsEnumerated(_));
  EXPECT_CALL(*client2, OnDeviceSupportedFormatsEnumerated(_));

  const base::Callback<void(const media::VideoCaptureFormats&)>
      callback1 = base::Bind(
          &MockVideoCaptureEventHandler::OnDeviceSupportedFormatsEnumerated,
          base::Unretained(client1.get()));
  const base::Callback<void(const media::VideoCaptureFormats&)>
      callback2 = base::Bind(
          &MockVideoCaptureEventHandler::OnDeviceSupportedFormatsEnumerated,
          base::Unretained(client2.get()));

  video_capture_impl_->GetDeviceSupportedFormats(callback1);
  video_capture_impl_->GetDeviceSupportedFormats(callback2);
  video_capture_impl_->DeInit(
      media::BindToCurrentLoop(run_loop_.QuitClosure()));
  run_loop_.Run();
}

// Check that a request to GetDeviceFormatsInUse() ends up eventually in the
// provided callback.
TEST_F(VideoCaptureImplTest, GetDeviceFormatsInUse) {
  scoped_ptr<MockVideoCaptureEventHandler> client(
      new MockVideoCaptureEventHandler);

  media::VideoCaptureFormats formats_in_use;
  EXPECT_CALL(*client, OnDeviceFormatsInUseReceived(_))
      .WillOnce(SaveArg<0>(&formats_in_use));

  const base::Callback<void(const media::VideoCaptureFormats&)> callback =
      base::Bind(&MockVideoCaptureEventHandler::OnDeviceFormatsInUseReceived,
                 base::Unretained(client.get()));
  video_capture_impl_->GetDeviceFormatsInUse(callback);
  video_capture_impl_->DeInit(
      media::BindToCurrentLoop(run_loop_.QuitClosure()));
  run_loop_.Run();

  EXPECT_TRUE(formats_in_use.empty());
}

}  // namespace content


text:
package org.apache.jmeter.protocol.ldap.config.gui;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

public class PackageTest {

        /**
         * Test that adding an argument to the table results in an appropriate
         * TestElement being created.
         *
         * @throws Exception
         *             if an exception occurred during the test
         */
        @Test
        public void testLDAPArgumentCreation() throws Exception {
            LDAPArgumentsPanel gui = new LDAPArgumentsPanel();
            gui.tableModel.addRow(new LDAPArgument());
            gui.tableModel.setValueAt("howdy", 0, 0);
            gui.tableModel.addRow(new LDAPArgument());
            gui.tableModel.setValueAt("doody", 0, 1);

            assertEquals("=", ((LDAPArgument) ((LDAPArguments) gui.createTestElement()).getArguments().get(0)
                    .getObjectValue()).getMetaData());
        }
}

redpajama_set_name: RedPajamaGithub


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<meta http-equiv="content-type" content="text/html; charset=utf-8" >
<title>London 2013
 -  Proposal</title>
<meta name="author" content="Adam Horwich" >

<link rel="alternate" type="application/rss+xml" title="devopsdays RSS Feed" href="http://www.devopsdays.org/feed/" >

<link rel="stylesheet" href="/css/devops.min.css" type="text/css" media="screen, projection">
<link rel="stylesheet" href="/css/blueprint/print.css" type="text/css" media="print">

      Home

      Contact

      Events

      Presentations

      Blog

London 2013
 -  Proposal

Gold sponsors

welcome
propose
program
location
register
sponsor
contact
reactions

Back to proposals overview - program

Monitoring Still Kinda Sucks

Abstract:

The biggest problems with monitoring services come from how selfish they are with data, and how they feel responsible for achieving all the things. A really useful monitoring service is one which allows us to visualise state and metrics. Modern tools are catching onto this though, and, with the right collaboration of components, your monitoring services can start building their own dashboards and form the hub of a much more accessible set of metrics.

I'll be talking about how and why we've transitioned away from old technologies like Naiogs, building a new service comprising of Sensu, Nimrod, Graphite and Tasseo. I'll be covering the dream, the reality, and the path to building a metrics led monitoring service. This talk will be useful for those feeling stuck with poor (or 'enterprise') monitoring solutions, or using disparate, disconnected services to achieve metrics and monitoring. With our new monitoring service, we've been able to graph, monitor, and alert on new deploys in realtime to evaluate the success and impact of new code.

Speaker:

Adam Horwich

Please enable JavaScript to view the comments powered by Disqus.
blog comments powered by Disqus

Gold sponsors

Silver sponsors


text:
package com.paymentwall.java;

import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
import org.junit.runner.RunWith;

@RunWith(Cucumber.class)
@CucumberOptions()
public class RunTests {
}


text:
module Postqueue
  class MissingHandler < RuntimeError
    attr_reader :queue, :op, :entity_ids

    def initialize(queue:, op:, entity_ids:)
      @queue = queue
      @op = op
      @entity_ids = entity_ids
    end

    def to_s
      "#{queue.item_class.table_name}: Unknown operation #{op.inspect} with #{entity_ids.count} entities"
    end
  end

  class Queue
    Timing = Struct.new(:avg_queue_time, :max_queue_time, :total_processing_time, :processing_time)

    def assert_valid_op!(op)
      return if op == :missing_handler
      return if op.is_a?(String)

      raise ArgumentError, "Invalid op #{op.inspect}, must be a string"
    end

    def on(op, batch_size: nil, idempotent: nil, &block)
      assert_valid_op! op
      callbacks[op] = block

      if batch_size
        raise ArgumentError, "Can't set per-op batchsize for op '*'" if op == "*"
        @batch_sizes[op] = batch_size
      end

      unless idempotent.nil?
        raise ArgumentError, "Can't idempotent for default op '*'" if op == "*"
        @idempotent_operations[op] = idempotent
      end

      self
    end

    private

    def callbacks
      @callbacks ||= {}
    end

    def callback_for(op:)
      callbacks[op] || callbacks["*"]
    end

    def run_callback(op:, entity_ids:)
      queue_times = item_class.find_by_sql <<-SQL
        SELECT extract('epoch' from AVG(now() - created_at)) AS avg,
               extract('epoch' from MAX(now() - created_at)) AS max
        FROM #{item_class.table_name} WHERE entity_id IN (#{entity_ids.join(',')})
      SQL
      queue_time = queue_times.first

      total_processing_time = Benchmark.realtime do
        callback = callback_for(op: op) || callbacks.fetch(:missing_handler)
        callback.call(op, entity_ids)
      end

      Timing.new(queue_time.avg, queue_time.max, total_processing_time, total_processing_time / entity_ids.length)
    end
  end
end


text:
import {
  SET_CURRENT_USER,
  LOG_ERROR,
  SIGNOUT_SUCCESS
} from '../constants/ActionTypes';

const initialState = {
  isAuthenticated: false,
  user: {},
  errorMsg: ''
};

export default function authReducer(state = initialState, action) {
  switch (action.type) {
  case SET_CURRENT_USER:
    return {
      ...state,
      isAuthenticated: true,
      user: action.user
    };
  case SIGNOUT_SUCCESS:
    return {
      ...state,
      isAuthenticated: false
    };
  case LOG_ERROR:
    return {
      ...state,
      isAuthenticated: false,
      errorMsg: action.error
    };
  default:
    return state;
  }
}


text:
package au.gov.amsa.detection;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

import com.github.davidmoten.junit.Asserts;

public class StreamsTest {

    @Test
    public void testFromNull() {
        assertEquals(0, Streams.fromNullable(null).count());
    }

    @Test
    public void testFromNotNull() {
        assertEquals(1, Streams.fromNullable("abc").count());
    }

    @Test
    public void testConstructorIsPrivate() {
        Asserts.assertIsUtilityClass(Streams.class);
    }

}


text:
<?php
namespace Dellaert\DCIMBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Dellaert\DCIMBundle\Entity\IncomingInvoice;
use Symfony\Component\HttpFoundation\Response;
use Doctrine\ORM\EntityRepository;

class IncomingInvoiceController extends Controller
{
	public function listAction()
	{
		$this->get("white_october_breadcrumbs")
			->addItem("Home", $this->get("router")->generate("homepage"))
			->addItem("Incoming invoices", $this->get("router")->generate("IncomingInvoiceList"));
		return $this->render('DellaertDCIMBundle:IncomingInvoice:list.html.twig');
	}

	public function listDataAction()
	{
		$request = $this->getRequest();

		$page = 1;
		if( $request->request->get('page') != null && $request->request->get('page') != '' ) {
			$page = $request->request->get('page');
		}

		$sortname = 'invoiceNumber';
		if( $request->request->get('sortname') != null && $request->request->get('sortname') != '' ) {
			$sortname = $request->request->get('sortname');
		}

		$sortorder = 'asc';
		if( $request->request->get('sortorder') != null && $request->request->get('sortorder') != '' ) {
			$sortorder = $request->request->get('sortorder');
		}

		$searchtype = '';
		if( $request->request->get('qtype') != null && $request->request->get('qtype') != '' ) {
			$searchtype = $request->request->get('qtype');
		}

		$searchquery = '';
		if( $request->request->get('query') != null && $request->request->get('query') != '' ) {
			$searchquery = $request->request->get('query');
		}

		$rp = 20;
		if( $request->request->get('rp') != null && $request->request->get('rp') != '' ) {
			$rp = $request->request->get('rp');
		}

		$pageStart = ($page-1)*$rp;

		$repository = $this->getDoctrine()->getRepository('DellaertDCIMBundle:IncomingInvoice');
		$qb = $repository->createQueryBuilder('c');
		if( $searchquery != '' && $searchtype != '' ) {
			$qb->add('where',$qb->expr()->like('c.'.$searchtype, $qb->expr()->literal('%'.$searchquery.'%')));
		}
		$qb->orderBy('c.'.$sortname,$sortorder);
		$qb->setFirstResult($pageStart);
		$qb->setMaxResults($rp);
		$query = $qb->getQuery();
		$results = $query->getResult();

		$em = $this->getDoctrine()->getManager();
		$qstring = 'SELECT COUNT(c.id) FROM DellaertDCIMBundle:IncomingInvoice c';
		if( $searchquery != '' && $searchtype != '' ) {
			$qstring .= ' where '.$qb->expr()->like('c.'.$searchtype, $qb->expr()->literal('%'.$searchquery.'%'));
		}
		$query = $em->createQuery($qstring);
		$total = $query->getSingleScalarResult();

		$data['page'] = $page;
		$data['total'] = $total;
		$data['rows'] = array();
		foreach($results as $entity) {
			$data['rows'][] = array(
				'id' => $entity->getSlug(),
				'cell' => array($entity->getInvoiceNumber(),$entity->getTargetCompany()->getCompanyName(),$entity->getTitle(),$entity->getCategory()->getTitle(),$entity->getDate()->format('Y-m-d'))
			);
		}

		$response = new Response(json_encode($data));
		$response->headers->set('Content-Type', 'application/json');

		return $response;
	}

	public function viewAction($slug)
	{
		$repository = $this->getDoctrine()->getRepository('DellaertDCIMBundle:IncomingInvoice');
		$entity = $repository->findOneBySlug($slug);

		$this->get("white_october_breadcrumbs")
			->addItem("Home", $this->get("router")->generate("homepage"))
				->addItem("Companies", $this->get("router")->generate("CompanyList"));
		if( $entity ) {
			$this->get("white_october_breadcrumbs")
				->addItem($entity->getTargetCompany()->getCompanyName(), $this->get("router")->generate("CompanyViewSlug",array('slug'=>$entity->getTargetCompany()->getSlug())))
				->addItem($entity->getInvoiceNumber().' - '.$entity->getTitle(), $this->get("router")->generate("IncomingInvoiceViewSlug",array('slug'=>$slug)));
		} else {
			$this->get("white_october_breadcrumbs")->addItem("Unkown incoming invoice", '');
		}

		return $this->render('DellaertDCIMBundle:IncomingInvoice:view.html.twig',array('entity'=>$entity));
	}

	public function addAction()
	{
		$user = $this->get('security.context')->getToken()->getUser();
		$entity = new IncomingInvoice();
		$entity->setTargetCompany($user->getCompany());
		$today = new \DateTime();
		$entity->setDate($today);
		$due = new \DateTime();
		$due->add(new \DateInterval('P30D'));
		$entity->setDueDate($due);
		$request = $this->getRequest();
		$this->get("white_october_breadcrumbs")
		->addItem("Home", $this->get("router")->generate("homepage"))
			->addItem("Companies", $this->get("router")->generate("CompanyList"));

		if( $request->getMethod() != 'POST' ) {
			$this->get('session')->remove('return_url');
		}
		if( $this->get('session')->get('return_url') == null || $this->get('session')->get('return_url') == '' ) {
			$this->get('session')->set('return_url',$this->get('router')->generate('IncomingInvoiceList'));
		}

		$form = $this->createAddEditForm($entity);
		if( $request->getMethod() == 'POST' ) {
			$form->handleRequest($request);
			if( $form->isValid() ) {
				$entity->setCreatedBy($user);
				$entity->setEnabled(true);
				$entity->preInsert();

				$file = $entity->getFile();
				$fileDir = $entity->getFileDir();

				$em = $this->getDoctrine()->getManager();
				$em->persist($entity);
				$em->flush();

				if (null !== $file) {
					if( !is_dir($fileDir) ) {
						mkdir($fileDir);
					}
					$file->move($fileDir, $file->getClientOriginalName());
					unset($file);
				}

				$this->get("white_october_breadcrumbs")
					->addItem($entity->getInvoiceNumber().' - '.$entity->getTitle(), $this->get("router")->generate("IncomingInvoiceViewSlug",array('slug'=>$entity->getSlug())))
					->addItem("Save",'');
				return $this->render('DellaertDCIMBundle:IncomingInvoice:add.html.twig',array('entity'=>$entity));
			}
		}
		$this->get("white_october_breadcrumbs")
		->addItem("Incoming invoices", $this->get("router")->generate("IncomingInvoiceList"))
			->addItem("Add incoming invoice", '');
		return $this->render('DellaertDCIMBundle:IncomingInvoice:add.html.twig',array('form'=>$form->createView()));
	}

	public function editAction($id)
	{
		$entity = $this->getDoctrine()->getRepository('DellaertDCIMBundle:IncomingInvoice')->find($id);
		$user = $this->get('security.context')->getToken()->getUser();
		$this->get("white_october_breadcrumbs")
		->addItem("Home", $this->get("router")->generate("homepage"))
			->addItem("Companies", $this->get("router")->generate("CompanyList"));
		if( $entity ) {
			$this->get("white_october_breadcrumbs")
				->addItem($entity->getTargetCompany()->getCompanyName(), $this->get("router")->generate("CompanyViewSlug",array('slug'=>$entity->getTargetCompany()->getSlug())))
				->addItem($entity->getInvoiceNumber().' - '.$entity->getTitle(), $this->get("router")->generate("IncomingInvoiceViewSlug",array('slug'=>$entity->getSlug())));
			$form = $this->createAddEditForm($entity);
			$request = $this->getRequest();
			if( $request->getMethod() == 'POST' ) {
				$form->handleRequest($request);
				if( $form->isValid() ) {
					$bcentity = $entity;

					$em = $this->getDoctrine()->getManager();
					$entity->preUpdate();

					$file = $entity->getFile();
					$fileDir = $entity->getFileDir();

					$em->persist($entity);
					$em->flush();

					if (null !== $file) {
						if( !is_dir($fileDir) ) {
							mkdir($fileDir);
						}
						$file->move($fileDir, $file->getClientOriginalName());
						unset($file);
					}

					$this->get("white_october_breadcrumbs")->addItem("Save",'');
					return $this->render('DellaertDCIMBundle:IncomingInvoice:edit.html.twig',array('entity'=>$entity));
				}
			}
			$this->get("white_october_breadcrumbs")->addItem("Edit",'');
			return $this->render('DellaertDCIMBundle:IncomingInvoice:edit.html.twig',array('form'=>$form->createView(),'entity'=>$entity));
		}
		$this->get("white_october_breadcrumbs")
			->addItem("Incoming invoices", $this->get("router")->generate("IncomingInvoiceList"))
			->add("Unkown incoming invoice", '');
		return $this->render('DellaertDCIMBundle:IncomingInvoice:edit.html.twig');
	}

	public function deleteAction($id)
	{
		$entity = $this->getDoctrine()->getRepository('DellaertDCIMBundle:IncomingInvoice')->find($id);
		$this->get("white_october_breadcrumbs")
		->addItem("Home", $this->get("router")->generate("homepage"))
			->addItem("Companies", $this->get("router")->generate("CompanyList"));
		if( $entity ) {
			$this->get("white_october_breadcrumbs")
				->addItem($entity->getTargetCompany()->getCompanyName(), $this->get("router")->generate("CompanyViewSlug",array('slug'=>$entity->getTargetCompany()->getSlug())))
				->addItem($entity->getInvoiceNumber().' - '.$entity->getTitle(), $this->get("router")->generate("IncomingInvoiceViewSlug",array('slug'=>$entity->getSlug())))
				->addItem("Delete",'');
			$this->get('session')->set('return_url',$this->get('router')->generate('CompanyViewSlug', array('slug'=>$entity->getTargetCompany()->getSlug())));
			$em = $this->getDoctrine()->getManager();
			$em->remove($entity);
			$em->flush();
			$entity->postRemove();
			return $this->render('DellaertDCIMBundle:IncomingInvoice:delete.html.twig',array('entity'=>$entity));
		}
	$this->get("white_october_breadcrumbs")
		->addItem("Incoming invoices", $this->get("router")->generate("IncomingInvoiceList"))
			->addItem("Unkown incoming invoice", '');
		return $this->render('DellaertDCIMBundle:IncomingInvoice:delete.html.twig');
	}

	public function payedAction($id,$status) {
		$entity = $this->getDoctrine()->getRepository('DellaertDCIMBundle:IncomingInvoice')->find($id);
		$this->get("white_october_breadcrumbs")
		->addItem("Home", $this->get("router")->generate("homepage"))
			->addItem("Companies", $this->get("router")->generate("CompanyList"));
		if( $entity ) {
			$this->get("white_october_breadcrumbs")
				->addItem($entity->getTargetCompany()->getCompanyName(), $this->get("router")->generate("CompanyViewSlug",array('slug'=>$entity->getTargetCompany()->getSlug())))
				->addItem($entity->getInvoiceNumber().' - '.$entity->getTitle(), $this->get("router")->generate("IncomingInvoiceViewSlug",array('slug'=>$entity->getSlug())))
				->addItem("Set $status",'');
			if( $status == 'payed' ) {
				$entity->setPayed(true);
			} elseif( $status == 'unpayed' ) {
				$entity->setPayed(false);
			}
			$em = $this->getDoctrine()->getManager();
			$entity->preUpdate();
			$em->persist($entity);
			$em->flush();
			return $this->render('DellaertDCIMBundle:IncomingInvoice:payed.html.twig',array('entity'=>$entity));
		}
	$this->get("white_october_breadcrumbs")
		->addItem("Incoming invoices", $this->get("router")->generate("IncomingInvoiceList"))
			->addItem("Unkown incoming invoice", '');
		return $this->render('DellaertDCIMBundle:IncomingInvoice:payed.html.twig');
	}

	public function downloadAction($id) {
		$entity = $this->getDoctrine()->getRepository('DellaertDCIMBundle:IncomingInvoice')->find($id);
		$this->get("white_october_breadcrumbs")
		->addItem("Home", $this->get("router")->generate("homepage"))
			->addItem("Companies", $this->get("router")->generate("CompanyList"));
		if( $entity ) {
			$fileLocation= $entity->getAbsolutePath();
			$response = new Response(file_get_contents($fileLocation));
			$response->headers->set('Content-Type', 'application/pdf');
			$response->headers->set('Content-Disposition','attachement; filename="'.$entity->getFilePath().'"');
			return $response;
		}
	$this->get("white_october_breadcrumbs")
		->addItem("Projects", $this->get("router")->generate("ProjectList"))
		->addItem("Incoming invoices", $this->get("router")->generate("IncomingInvoiceList"))
			->addItem("Unkown incoming invoice", '');
		return $this->render('DellaertDCIMBundle:IncomingInvoice:download.html.twig');
	}

	public function createAddEditForm($entity)
	{
		$fb = $this->createFormBuilder($entity);
		$fb->add('title','text',array('max_length'=>255,'required'=>true,'label'=>'Title'));
		$fb->add('invoiceNumber','text',array('max_length'=>255,'required'=>true,'label'=>'Invoice Number'));
		$fb->add('targetCompany','entity',array(
			'class' => 'Dellaert\\DCIMBundle\\Entity\\Company',
			'query_builder' => function(EntityRepository $er) {
				return $er->createQueryBuilder('c')->orderBy('c.companyName','ASC');
			},
			'property' => 'companyName',
			'required' => true,
			'label' => 'Company'
		));
		$fb->add('category','entity',array(
			'class' => 'Dellaert\\DCIMBundle\\Entity\\Category',
			'query_builder' => function(EntityRepository $er) {
				return $er->createQueryBuilder('c')->orderBy('c.title','ASC');
			},
			'property' => 'title',
			'required' => true,
			'label' => 'Category'
		));
		$fb->add('date','date',array('required'=>true,'label'=>'Invoice date'));
		$fb->add('dueDate','date',array('required'=>true,'label'=>'Due Date'));
		$fb->add('amount','number',array('precision'=>2,'required'=>true,'label'=>'Amount'));
		$fb->add('vat','number',array('precision'=>2,'required'=>true,'label'=>'VAT'));
		$fb->add('file','file', array('required'=>false,'label'=>'Scan'));
		$fb->add('payed','checkbox', array('required'=>false,'label'=>'Payed'));
		return $fb->getForm();
	}
}


text:
"""Implementes Gfx.Driver using wxWidgets.
"""

import math
import wx
try:
    import Gfx
except ImportError:
    from . import Gfx

driverName = "wxGfx"

assert wx.VERSION[0] > 2 or (wx.VERSION[0]==2 and wx.VERSION[1]>=4), \
       "wxGfx.py requires wxPython Version 2.4 or higher!"

if wx.VERSION[0] == 2 and wx.VERSION[1] >= 6: _canRotateText = True
elif wx.Platform != "__WXGTK__": _canRotateText = True
else: _canRotateText = False

########################################################################
#
#   Compatibility with wxPython 2.5.1, which was not backward
#   compatible!
#
########################################################################

if wx.VERSION[0] == 2 and wx.VERSION[1] == 5 and wx.VERSION[2] <= 1:
    class DCCompatibilityWrapper(object):
        def __init__(self, dc):
            self.dc = dc
        def Clear(self):
            self.dc.Clear()
        def DrawLines(self, points):
            self.dc.DrawLines(points)
        def DrawPolygon(self, points):
            self.dc.DrawPolygon(points)
        def SetAxisOrientation(self, x, y):
            self.dc.SetAxisOrientation(x, y)
        def SetBackground(self, color):
            self.dc.SetBackground(color)
        def SetPen(self, pen):
            self.dc.SetPen(pen)
        def SetBrush(self, brush):
            self.dc.SetBrush(brush)
        def SetFont(self, font):
            self.dc.SetFont(font)
        def SetTextForeground(self, color):
            self.dc.SetTextForeground(color)
        def SetTextBackground(self, color):
            self.dc.SetTextBackground(color)
        def GetSizeTuple(self):
            return self.dc.GetSizeTuple()
        def Blit(self, dstX, dstY, w, h, srcDC, srcX, srcY):
            self.dc.BlitXY(dstX, dstY, w, h, srcDC, srcX, srcY)
        def DrawPoint(self, x, y):
            self.dc.DrawPointXY(x, y)
        def DrawLine(self, x1, y1, x2, y2):
            self.dc.DrawLineXY(x1, y1, x2, y2)
        def DrawText(self, str, x, y):
            self.dc.DrawTextXY(str, x, y)
        def DrawRotatedText(self, str, x, y, angle):
            self.dc.DrawRotatedTextXY(str, x, y, angle)
    def UnwrapDC(dc):
        return dc.dc
else:
    def DCCompatibilityWrapper(dc):
        return dc
    def UnwrapDC(dc):
        return dc

########################################################################
#
#   class Driver
#
########################################################################

class Driver(Gfx.Driver):
    """A graphics driver for  wxWidgets.
    For an explanation of the inherited methods see Gfx.py.
    """

    def __init__(self, dc):
        """Initialize canvas on the device context dc."""
        Gfx.Driver.__init__(self)
        self.font = wx.Font(12, wx.MODERN, wx.NORMAL, wx.NORMAL,
                           encoding=wx.FONTENCODING_ISO8859_1)
        self.pen = wx.Pen(wx.Colour(0, 0, 0), 1, wx.SOLID)
        self.pen.SetCap(wx.CAP_ROUND)
        self.brush = wx.Brush(wx.Colour(0, 0, 0), wx.SOLID)
        self.dc = None
        self.color = (0.0, 0.0, 0.0)
        self.changeDC(dc)
        if dc:
            self.reset()
            if not isinstance(dc, wx.PostScriptDC): self.clear()

    def changeDC(self, dc):
        """Use a new dc for the following drawing commands."""
        oldDC = self.getDC()
        self.dc = DCCompatibilityWrapper(dc)
        if dc:
            self.resizedGfx()
            dc.SetAxisOrientation(True, False)
            dc.SetBackground(wx.Brush(wx.Colour(255, 255, 255)))
            dc.SetPen(self.pen)
            dc.SetBrush(self.brush)
            dc.SetFont(self.font)
            dc.SetTextForeground(wx.Colour(int(round(self.color[0]*255)),
                                          int(round(self.color[1]*255)),
                                         int(round(self.color[2]*255))))
        return oldDC

    def getDC(self):
        """-> wx.DC of this graphics drivers object"""
        return UnwrapDC(self.dc)

    def resizedGfx(self):
        """Take notice if the underlying device has been resized."""
##        if isinstance(self.dc, wx.PostScriptDC):
##            self.dpi = self.dc.GetResolution()
##            self.w = self.dpi*6
##            self.h = self.dpi*6
##        else:
        try:
            self.w, self.h = self.dc.GetSizeTuple()
        except wx.PyAssertionError:
            self.w, self.h = 100, 100
        self.dpi = 100

    def getSize(self):
        return self.w, self.h

    def getResolution(self):
        return self.dpi

    def setColor(self, rgbTuple):
        self.color = rgbTuple
        wxCol = wx.Colour(int(round(rgbTuple[0]*255)),
                          int(round(rgbTuple[1]*255)),
                          int(round(rgbTuple[2]*255)))
        self.pen.SetColour(wxCol)
        self.brush.SetColour(wxCol)
        self.dc.SetTextForeground(wxCol)
        self.dc.SetPen(self.pen)
        self.dc.SetBrush(self.brush)

    def setLineWidth(self, width):
        self.lineWidth = width
        if width == Gfx.THIN: tn = 1
        elif width == Gfx.MEDIUM: tn = 2
        elif width == Gfx.THICK: tn = 3
        else: raise ValueError("'thickness' must be 'thin', 'medium' or thick' !")
        self.pen.SetWidth(tn)
        self.dc.SetPen(self.pen)

    def setLinePattern(self, pattern):
        self.linePattern = pattern
        if pattern == Gfx.CONTINUOUS: lp = wx.SOLID
        elif pattern == Gfx.DASHED: lp = wx.SHORT_DASH
        elif pattern == Gfx.DOTTED: lp = wx.DOT
        else: raise ValueError("'pattern' must be 'continuous','dashed' " + \
                    "or 'dotted'")
        self.pen.SetStyle(lp)
        self.dc.SetPen(self.pen)

    def setFillPattern(self, pattern):
        self.fillPattern = pattern
        if pattern == Gfx.SOLID: fp = wx.SOLID
        elif pattern == Gfx.PATTERN_A: fp = wx.BDIAGONAL_HATCH
        elif pattern == Gfx.PATTERN_B: fp = wx.FDIAGONAL_HATCH
        elif pattern == Gfx.PATTERN_C: fp = wx.CROSSDIAG_HATCH
        else: raise ValueError("'pattern' must be 'solid' or 'patternA', " + \
                    "'patternB', 'patternC' !")
        self.brush.SetStyle(fp)
        self.dc.SetBrush(self.brush)

    def setFont(self, ftype, size, weight):
        self.fontType = ftype
        self.fontSize = size
        self.fontWeight = weight
        if ftype == Gfx.SANS: ff = wx.SWISS
        elif ftype == Gfx.SERIF: ff = wx.ROMAN
        elif ftype == Gfx.FIXED: ff = wx.MODERN
        else: raise ValueError("'type' must be 'sans', 'serif' or 'fixed' !")
        if size == Gfx.SMALL: fs = 8
        elif size == Gfx.NORMAL: fs = 12
        elif size == Gfx.LARGE: fs = 16
        else: raise ValueError("'size' must be 'small', 'normal' or 'large' !")
        fst = wx.NORMAL
        fw = wx.NORMAL
        if "i" in weight: fst = wx.ITALIC
        elif "b" in weight: fw = wx.BOLD
        self.font = wx.Font(fs, ff, fst, fw,
                           encoding=wx.FONTENCODING_ISO8859_1)
        self.dc.SetFont(self.font)

    def getTextSize(self, text):
        try:
            return self.dc.GetTextExtent(text)
        except AttributeError:
            if self.fontSize == Gfx.SMALL: fs = 8
            elif self.fontSize == Gfx.NORMAL: fs = 12
            elif self.fontSize == Gfx.LARGE: fs = 16
            return (len(text) * fs * 2/3, fs)   # very inexact

    def clear(self, rgbTuple=(1.0, 1.0, 1.0)):
        if isinstance(self.dc, wx.PostScriptDC):
            oldColor = self.color
            oldFillPattern = self.fillPattern
            self.setColor(rgbTuple)
            self.setFillPattern(Gfx.SOLID)
            self.fillRect(0, 0, self.w, self.h)
            self.setColor(oldColor)
            self.setFillPattern(oldFillPattern)
        else:
            self.dc.SetBackground(wx.Brush(wx.Colour(
                                          int(round(rgbTuple[0]*255)),
                                          int(round(rgbTuple[1]*255)),
                                          int(round(rgbTuple[2]*255)))))
            self.dc.Clear()

    def drawPoint(self, x, y):
        if self.lineWidth == Gfx.THIN:
            self.dc.DrawPoint(x, self.h-y-1)
        else:
            self.dc.DrawLine(x, self.h-y-1, x, self.h-y-1)

    def drawLine(self, x1, y1, x2, y2):
        self.dc.DrawLine(x1, self.h-y1-1, x2, self.h-y2-1)

    def drawPoly(self, array):
        if len(array) > 1:
            points = [wx.Point(p[0],self.h-p[1]-1) for p in array]
            self.dc.DrawLines(points)
        elif array:
            point = array[0]
            self.drawPoint(point[0], point[1])

# somehow the following does not draw filled rectangles!?
##    def fillRect(self, x, y, w, h):
##        self.dc.SetPen(wx.TRANSPARENT_PEN)
##        self.dc.DrawRectangle(x, y, w, h)
##        self.dc.SetPen(self.pen)

    def fillRect(self, x, y, w, h):
        self.fillPoly([(x,y-1), (x+w,y-1), (x+w,y+h-1), (x, y+h-1)])
        # x+w,y+h are used instead of x+w-1, y+h-1, because
        # otherwise the rectangle misses one line / column!?

    def fillPoly(self, array):
        if len(array) > 2:
            self.dc.SetPen(wx.TRANSPARENT_PEN)
            points = [wx.Point(p[0],self.h-p[1]-1) for p in array]
            self.dc.DrawPolygon(points)
            self.dc.SetPen(self.pen)

    def writeStr(self, x, y, str, rotationAngle=0.0):
        w, h = self.getTextSize(str)
        if rotationAngle == 0.0:
            self.dc.DrawText(str, x, self.h-y-h)
        else:
            a = rotationAngle / 180.0 * math.pi
            da = math.atan2(h,0)-a
            dw = int(h*math.cos(da)+0.5)
            dh = int(h*math.sin(da)+0.5)-h
            if _canRotateText:
                # Unfortunately, DrawRotatedText does not work
                # under some configurations!
                self.dc.DrawRotatedText(str, x-dw, self.h-y-h-dh,rotationAngle)
                return
            _buffer = wx.EmptyBitmap(w, h)
            dc = DCCompatibilityWrapper(wx.BufferedDC(None, _buffer))
            dc.SetBackground(wx.BLACK_BRUSH)
            dc.Clear()
            dc.SetFont(self.font)
            dc.SetTextForeground((255,255,255))
            dc.SetTextBackground((0, 0, 0))
            dc.DrawText(str, 0, 0)
            if "ConvertToImage" in _buffer.__dict__:
                image = _buffer.ConvertToImage()
            else:
                image = wx.ImageFromBitmap(_buffer)
            data = image.GetData()
            for dy in range(h):
                for dx in range(w):
                    if ord(data[(dy*w + dx)*3]) > 128:
                        r = math.sqrt(dx**2+dy**2)
                        da = math.atan2(dy,dx) - a
                        xx = int(r * math.cos(da)+0.5)
                        yy = int(r * math.sin(da)+0.5)
                        self.dc.DrawPoint(x+xx-dw, self.h-y-h+yy-dh)

########################################################################
#
#   class Window
#
########################################################################

class Window(Driver, Gfx.Window):

    def __init__(self, size=(640, 480), title="wx.Graph", app=None):
        if app != None:
            self.app = app
        else:
            self.app = wx.PySimpleApp()

        self.win = wx.Frame(None, -1, title, style=
                            wx.DEFAULT_FRAME_STYLE)
        self.win.SetSize(size)
        self.win.Show(1)
        #self.app.SetTopWindow(self.win)
        #self.win.Refresh()

        size = self.win.GetClientSize()
        self.buffer = wx.EmptyBitmap(size.width, size.height)
        dc = wx.BufferedDC(None, self.buffer)
        self.app.SetTopWindow(self.win)
        wx.EVT_PAINT(self.win, self._OnPaint)
        Driver.__init__(self, dc)

    def _OnPaint(self, event):
        dc = DCCompatibilityWrapper(wx.PaintDC(self.win))
        dc.Blit(0, 0, self.w, self.h, self.getDC(), 0, 0)

    def refresh(self):
        self.win.Refresh()
        self.win.Update()

    def quit(self):
        self.win.Close()
        self.win.Destroy()

    def waitUntilClosed(self):
        self.app.MainLoop()

########################################################################
#
#   Test
#
########################################################################

if __name__ == "__main__":
    import systemTest
    systemTest.Test_wxGfx()


text:
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wikidot="http://www.wikidot.com/rss-namespace">

	<channel>
		<title>Comments for page "Smokestack"</title>
		<link>http://bvs.wikidot.com/forum/t-67620/smokestack</link>
		<description>Posts in the discussion thread "Smokestack"</description>
				<copyright></copyright>
		<lastBuildDate>Sun, 10 Jul 2022 03:51:49 +0000</lastBuildDate>

					<item>
				<guid>http://bvs.wikidot.com/forum/t-67620#post-369614</guid>
				<title>(no title)</title>
				<link>http://bvs.wikidot.com/forum/t-67620/smokestack#post-369614</link>
				<description></description>
				<pubDate>Thu, 29 Jan 2009 02:39:15 +0000</pubDate>
				<wikidot:authorName>bwayhawk2002</wikidot:authorName>				<wikidot:authorUserId>137405</wikidot:authorUserId>				<content:encoded>
					<![CDATA[

current data on smokestack is accurate. Data has been tested.

				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://bvs.wikidot.com/forum/t-67620#post-196821</guid>
				<title>This needs to be corrected on the main item page</title>
				<link>http://bvs.wikidot.com/forum/t-67620/smokestack#post-196821</link>
				<description></description>
				<pubDate>Mon, 16 Jun 2008 06:24:37 +0000</pubDate>
				<wikidot:authorName>PbookR</wikidot:authorName>				<wikidot:authorUserId>119536</wikidot:authorUserId>				<content:encoded>
					<![CDATA[

It says it uses 140% of appetite and provides 5 smokebombs there.

				 	]]>
				</content:encoded>							</item>
				</channel>
</rss>


text:
class RemoveOwnerFromChat < ActiveRecord::Migration
  def change
    remove_column :chats, :owner_type
    remove_column :chats, :owner_id
  end
end


text:
<?php

namespace FS\SolrBundle;

use FS\SolrBundle\DependencyInjection\Compiler\AddSolariumPluginsPass;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use FS\SolrBundle\DependencyInjection\Compiler\AddCreateDocumentCommandPass;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class FSSolrBundle extends Bundle
{
    public function build(ContainerBuilder $container)
    {
        parent::build($container);

        $container->addCompilerPass(new AddSolariumPluginsPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION);
    }
}


text:
package org.keycloak.protocol.oidc.utils;

import org.keycloak.common.util.StreamUtil;
import org.keycloak.connections.httpclient.HttpClientProvider;
import org.keycloak.jose.jwk.JSONWebKeySet;
import org.keycloak.jose.jwk.JWK;
import org.keycloak.jose.jwk.JWKParser;
import org.keycloak.models.KeycloakSession;
import org.keycloak.util.JsonSerialization;

import java.io.IOException;
import java.io.InputStream;
import java.security.PublicKey;

/**
 *
 * @author Marek Posolda
 */
public class JWKSHttpUtils {

    public static JSONWebKeySet sendJwksRequest(KeycloakSession session, String jwksURI) throws IOException {
        InputStream is = session.getProvider(HttpClientProvider.class).get(jwksURI);
        String keySetString = StreamUtil.readString(is);
        return JsonSerialization.readValue(keySetString, JSONWebKeySet.class);
    }
}


text:
main()
{
	printf("Number of Segments in Motion Buffer = %d\n",ParametricIndex);
	LastCoordSystem0=&ParametricCoeffs[0];  // reset to start at beginning
	ExecBuf();
}


text:
//===--- PMOMemoryUseCollector.cpp - Memory use analysis for PMO ----------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "definite-init"
#include "PMOMemoryUseCollector.h"
#include "swift/AST/Expr.h"
#include "swift/SIL/InstructionUtils.h"
#include "swift/SIL/SILArgument.h"
#include "swift/SIL/SILBuilder.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/SaveAndRestore.h"

using namespace swift;

//===----------------------------------------------------------------------===//
//                     PMOMemoryObjectInfo Implementation
//===----------------------------------------------------------------------===//

PMOMemoryObjectInfo::PMOMemoryObjectInfo(AllocationInst *allocation)
    : MemoryInst(allocation) {
  auto &module = MemoryInst->getModule();

  // Compute the type of the memory object.
  if (auto *abi = dyn_cast<AllocBoxInst>(MemoryInst)) {
    assert(abi->getBoxType()->getLayout()->getFields().size() == 1 &&
           "analyzing multi-field boxes not implemented");
    MemorySILType = abi->getBoxType()->getFieldType(module, 0);
  } else {
    MemorySILType = cast<AllocStackInst>(MemoryInst)->getElementType();
  }
}

SILInstruction *PMOMemoryObjectInfo::getFunctionEntryPoint() const {
  return &*getFunction().begin()->begin();
}

//===----------------------------------------------------------------------===//
//                          Scalarization Logic
//===----------------------------------------------------------------------===//

/// Given a pointer to a tuple type, compute the addresses of each element and
/// add them to the ElementAddrs vector.
static void
getScalarizedElementAddresses(SILValue Pointer, SILBuilder &B, SILLocation Loc,
                              SmallVectorImpl<SILValue> &ElementAddrs) {
  TupleType *TT = Pointer->getType().castTo<TupleType>();
  for (auto Index : indices(TT->getElements())) {
    ElementAddrs.push_back(B.createTupleElementAddr(Loc, Pointer, Index));
  }
}

/// Scalarize a load down to its subelements.  If NewLoads is specified, this
/// can return the newly generated sub-element loads.
static SILValue scalarizeLoad(LoadInst *LI,
                              SmallVectorImpl<SILValue> &ElementAddrs) {
  SILBuilderWithScope B(LI);
  SmallVector<SILValue, 4> ElementTmps;

  for (unsigned i = 0, e = ElementAddrs.size(); i != e; ++i) {
    auto *SubLI = B.createTrivialLoadOr(LI->getLoc(), ElementAddrs[i],
                                        LI->getOwnershipQualifier(),
                                        true /*supports unqualified*/);
    ElementTmps.push_back(SubLI);
  }

  if (LI->getType().is<TupleType>())
    return B.createTuple(LI->getLoc(), LI->getType(), ElementTmps);
  return B.createStruct(LI->getLoc(), LI->getType(), ElementTmps);
}

/// Scalarize a load_borrow down to its subelements. It will scalarize each of
/// the end_borrows of the load_borrow as well.
static void scalarizeLoadBorrow(LoadBorrowInst *lbi,
                                SmallVectorImpl<SILValue> &elementAddrs) {
  // First gather all of our end_borrows. We are going to scalarize them as
  // well.
  SmallVector<EndBorrowInst *, 8> endBorrows;
  for (auto *op : lbi->getUses()) {
    if (auto *ebi = dyn_cast<EndBorrowInst>(op->getUser())) {
      endBorrows.push_back(ebi);
    }
  }

  SILBuilderWithScope b(lbi);
  SmallVector<SILValue, 4> elementTmps;

  for (unsigned i : indices(elementAddrs)) {
    if (elementAddrs[i]->getType().isTrivial(*lbi->getFunction())) {
      elementTmps.push_back(b.createLoad(lbi->getLoc(), elementAddrs[i],
                                         LoadOwnershipQualifier::Trivial));
      continue;
    }

    SILValue v = b.createLoadBorrow(lbi->getLoc(), elementAddrs[i]);
    for (auto *ebi : endBorrows) {
      SILBuilderWithScope(ebi).createEndBorrow(lbi->getLoc(), v);
    }
    elementTmps.push_back(v);
  }

  // Inline constructor.
  auto result = ([&]() -> SILValue {
    if (lbi->getType().is<TupleType>())
      return b.createTuple(lbi->getLoc(), lbi->getType(), elementTmps);
    return b.createStruct(lbi->getLoc(), lbi->getType(), elementTmps);
  })();

  // Delete all of the end borrows, rauw, and we are done!
  for (auto *ebi : endBorrows) {
    ebi->eraseFromParent();
  }
  lbi->replaceAllUsesWith(result);
  lbi->eraseFromParent();
}

//===----------------------------------------------------------------------===//
//                     ElementUseCollector Implementation
//===----------------------------------------------------------------------===//

namespace {

class ElementUseCollector {
  SILModule &Module;
  const PMOMemoryObjectInfo &TheMemory;
  SmallVectorImpl<PMOMemoryUse> &Uses;
  SmallVectorImpl<SILInstruction *> &Releases;

  /// When walking the use list, if we index into a struct element, keep track
  /// of this, so that any indexes into tuple subelements don't affect the
  /// element we attribute an access to.
  bool InStructSubElement = false;

public:
  ElementUseCollector(const PMOMemoryObjectInfo &TheMemory,
                      SmallVectorImpl<PMOMemoryUse> &Uses,
                      SmallVectorImpl<SILInstruction *> &Releases)
      : Module(TheMemory.MemoryInst->getModule()), TheMemory(TheMemory),
        Uses(Uses), Releases(Releases) {}

  /// This is the main entry point for the use walker.  It collects uses from
  /// the address and the refcount result of the allocation.
  LLVM_NODISCARD bool collectFrom();

private:
  LLVM_NODISCARD bool collectUses(SILValue Pointer);
  LLVM_NODISCARD bool collectContainerUses(SILValue boxValue);
};
} // end anonymous namespace

bool ElementUseCollector::collectFrom() {
  if (auto *abi = TheMemory.getContainer()) {
    return collectContainerUses(abi);
  }

  return collectUses(TheMemory.getAddress());
}

bool ElementUseCollector::collectContainerUses(SILValue boxValue) {
  assert(isa<AllocBoxInst>(boxValue) || isa<CopyValueInst>(boxValue));

  for (auto *ui : boxValue->getUses()) {
    auto *user = ui->getUser();

    // dealloc_box deallocated a box containing uninitialized memory. This can
    // not effect any value stored into the box.
    if (isa<DeallocBoxInst>(user))
      continue;

    // Retaining the box doesn't effect the value inside the box.
    if (isa<StrongRetainInst>(user) || isa<RetainValueInst>(user))
      continue;

    // Like retaining, copies do not effect the underlying value. We do need to
    // recursively visit the copies users though.
    if (auto *cvi = dyn_cast<CopyValueInst>(user)) {
      if (!collectContainerUses(cvi))
        return false;
      continue;
    }

    // Since we are trying to promote loads/stores, any releases of the box are
    // not considered uses of the underlying value due to:
    //
    // 1. If this is not the last release of the box, then the underlying value
    // is not effected implying we do not add this value.
    //
    // 2. If this is the last release of the box, then the box's destruction
    // will result in a release of the underlying value. If there are any
    // loads/stores after this point, the behavior would be undefined so we can
    // ignore this possibility.
    //
    // That being said, if we want to eliminate the box completely we need to
    // know where the releases are so that we can release the value that would
    // have been at +1 in the box at that time. So we add these to the Releases
    // array.
    //
    // FIXME: Since we do not support promoting strong_release or release_value
    // today this will cause the underlying allocation to never be
    // eliminated. That should be implemented and fixed.
    if (isa<StrongReleaseInst>(user) || isa<ReleaseValueInst>(user) ||
        isa<DestroyValueInst>(user)) {
      Releases.push_back(user);
      continue;
    }

    if (auto *p = dyn_cast<ProjectBoxInst>(user)) {
      if (!collectUses(p))
        return false;
      continue;
    }

    // Other uses of the container are considered escapes of the underlying
    // value.
    //
    // This will cause the dataflow to stop propagating any information at the
    // use block.
    Uses.emplace_back(user, PMOUseKind::Escape);
  }

  return true;
}

bool ElementUseCollector::collectUses(SILValue Pointer) {
  assert(Pointer->getType().isAddress() &&
         "Walked through the pointer to the value?");
  SILType PointeeType = Pointer->getType().getObjectType();

  /// This keeps track of instructions in the use list that touch multiple tuple
  /// elements and should be scalarized.  This is done as a second phase to
  /// avoid invalidating the use iterator.
  ///
  SmallVector<SILInstruction *, 4> UsesToScalarize;

  for (auto *UI : Pointer->getUses()) {
    auto *User = UI->getUser();

    // struct_element_addr P, #field indexes into the current element.
    if (auto *seai = dyn_cast<StructElementAddrInst>(User)) {
      // Generally, we set the "InStructSubElement" flag and recursively process
      // the uses so that we know that we're looking at something within the
      // current element.
      llvm::SaveAndRestore<bool> X(InStructSubElement, true);
      if (!collectUses(seai))
        return false;
      continue;
    }

    // Instructions that compute a subelement are handled by a helper.
    if (auto *teai = dyn_cast<TupleElementAddrInst>(User)) {
      if (!collectUses(teai))
        return false;
      continue;
    }

    // Look through begin_access.
    if (auto *bai = dyn_cast<BeginAccessInst>(User)) {
      if (!collectUses(bai))
        return false;
      continue;
    }

    // Ignore end_access.
    if (isa<EndAccessInst>(User)) {
      continue;
    }

    // Loads are a use of the value.
    if (isa<LoadInst>(User) || isa<LoadBorrowInst>(User)) {
      if (PointeeType.is<TupleType>())
        UsesToScalarize.push_back(User);
      else
        Uses.emplace_back(User, PMOUseKind::Load);
      continue;
    }

    // Stores *to* the allocation are writes.
    if (auto *si = dyn_cast<StoreInst>(User)) {
      if (UI->getOperandNumber() == StoreInst::Dest) {
        if (PointeeType.is<TupleType>()) {
          UsesToScalarize.push_back(User);
          continue;
        }

        auto kind = ([&]() -> PMOUseKind {
          switch (si->getOwnershipQualifier()) {
          // Coming out of SILGen, we assume that raw stores are
          // initializations, unless they have trivial type (which we classify
          // as InitOrAssign).
          case StoreOwnershipQualifier::Unqualified:
            if (PointeeType.isTrivial(*User->getFunction()))
              return PMOUseKind::InitOrAssign;
            return PMOUseKind::Initialization;

          case StoreOwnershipQualifier::Init:
            return PMOUseKind::Initialization;

          case StoreOwnershipQualifier::Assign:
            return PMOUseKind::Assign;

          case StoreOwnershipQualifier::Trivial:
            return PMOUseKind::InitOrAssign;
          }
        })();
        Uses.emplace_back(si, kind);
        continue;
      }
    }

    if (auto *CAI = dyn_cast<CopyAddrInst>(User)) {
      // If this is a copy of a tuple, we should scalarize it so that we don't
      // have an access that crosses elements.
      if (PointeeType.is<TupleType>()) {
        UsesToScalarize.push_back(CAI);
        continue;
      }

      // If this is the source of the copy_addr, then this is a load.  If it is
      // the destination, then this is an unknown assignment.  Note that we'll
      // revisit this instruction and add it to Uses twice if it is both a load
      // and store to the same aggregate.
      //
      // Inline constructor.
      auto Kind = ([&]() -> PMOUseKind {
        if (UI->getOperandNumber() == CopyAddrInst::Src)
          return PMOUseKind::Load;
        if (PointeeType.isTrivial(*CAI->getFunction()))
          return PMOUseKind::InitOrAssign;
        if (CAI->isInitializationOfDest())
          return PMOUseKind::Initialization;
        return PMOUseKind::Assign;
      })();
      Uses.emplace_back(User, Kind);
      continue;
    }

    // The apply instruction does not capture the pointer when it is passed
    // through 'inout' arguments or for indirect returns.  InOut arguments are
    // treated as uses and may-store's, but an indirect return is treated as a
    // full store.
    //
    // Note that partial_apply instructions always close over their argument.
    //
    if (auto *Apply = dyn_cast<ApplyInst>(User)) {
      auto substConv = Apply->getSubstCalleeConv();
      unsigned ArgumentNumber = UI->getOperandNumber() - 1;

      // If this is an out-parameter, it is like a store.
      unsigned NumIndirectResults = substConv.getNumIndirectSILResults();
      if (ArgumentNumber < NumIndirectResults) {
        // We do not support initializing sub members. This is an old
        // restriction from when this code was used by Definite
        // Initialization. With proper code review, we can remove this, but for
        // now, lets be conservative.
        if (InStructSubElement) {
          return false;
        }
        Uses.emplace_back(User, PMOUseKind::Initialization);
        continue;

        // Otherwise, adjust the argument index.
      } else {
        ArgumentNumber -= NumIndirectResults;
      }

      auto ParamConvention =
          substConv.getParameters()[ArgumentNumber].getConvention();

      switch (ParamConvention) {
      case ParameterConvention::Direct_Owned:
      case ParameterConvention::Direct_Unowned:
      case ParameterConvention::Direct_Guaranteed:
        llvm_unreachable("address value passed to indirect parameter");

      // If this is an in-parameter, it is like a load.
      case ParameterConvention::Indirect_In:
      case ParameterConvention::Indirect_In_Constant:
      case ParameterConvention::Indirect_In_Guaranteed:
        Uses.emplace_back(User, PMOUseKind::IndirectIn);
        continue;

      // If this is an @inout parameter, it is like both a load and store.
      case ParameterConvention::Indirect_Inout:
      case ParameterConvention::Indirect_InoutAliasable: {
        // If we're in the initializer for a struct, and this is a call to a
        // mutating method, we model that as an escape of self.  If an
        // individual sub-member is passed as inout, then we model that as an
        // inout use.
        Uses.emplace_back(User, PMOUseKind::InOutUse);
        continue;
      }
      }
      llvm_unreachable("bad parameter convention");
    }

    // init_existential_addr is modeled as an initialization store.
    if (isa<InitExistentialAddrInst>(User)) {
      // init_existential_addr should not apply to struct subelements.
      if (InStructSubElement) {
        return false;
      }
      Uses.emplace_back(User, PMOUseKind::Initialization);
      continue;
    }

    // open_existential_addr is a use of the protocol value,
    // so it is modeled as a load.
    if (isa<OpenExistentialAddrInst>(User)) {
      Uses.emplace_back(User, PMOUseKind::Load);
      // TODO: Is it safe to ignore all uses of the open_existential_addr?
      continue;
    }

    // We model destroy_addr as a release of the entire value.
    if (isa<DestroyAddrInst>(User)) {
      Releases.push_back(User);
      continue;
    }

    if (isa<DeallocStackInst>(User)) {
      continue;
    }

    // Sanitizer instrumentation is not user visible, so it should not
    // count as a use and must not affect compile-time diagnostics.
    if (isSanitizerInstrumentation(User))
      continue;

    // Otherwise, the use is something complicated, it escapes.
    Uses.emplace_back(User, PMOUseKind::Escape);
  }

  // Now that we've walked all of the immediate uses, scalarize any operations
  // working on tuples if we need to for canonicalization or analysis reasons.
  if (!UsesToScalarize.empty()) {
    SILInstruction *PointerInst = Pointer->getDefiningInstruction();
    SmallVector<SILValue, 4> ElementAddrs;
    SILBuilderWithScope AddrBuilder(++SILBasicBlock::iterator(PointerInst),
                                    PointerInst);
    getScalarizedElementAddresses(Pointer, AddrBuilder, PointerInst->getLoc(),
                                  ElementAddrs);

    SmallVector<SILValue, 4> ElementTmps;
    for (auto *User : UsesToScalarize) {
      ElementTmps.clear();

      LLVM_DEBUG(llvm::errs() << "  *** Scalarizing: " << *User << "\n");

      // Scalarize LoadInst
      if (auto *LI = dyn_cast<LoadInst>(User)) {
        SILValue Result = scalarizeLoad(LI, ElementAddrs);
        LI->replaceAllUsesWith(Result);
        LI->eraseFromParent();
        continue;
      }

      // Scalarize LoadBorrowInst
      if (auto *LBI = dyn_cast<LoadBorrowInst>(User)) {
        scalarizeLoadBorrow(LBI, ElementAddrs);
        continue;
      }

      // Scalarize StoreInst
      if (auto *SI = dyn_cast<StoreInst>(User)) {
        SILBuilderWithScope B(User, SI);
        B.emitDestructureValueOperation(
            SI->getLoc(), SI->getSrc(),
            [&](unsigned index, SILValue v) { ElementTmps.push_back(v); });
        for (unsigned i = 0, e = ElementAddrs.size(); i != e; ++i)
          B.createTrivialStoreOr(SI->getLoc(), ElementTmps[i], ElementAddrs[i],
                                 SI->getOwnershipQualifier(),
                                 true /*supports unqualified*/);
        SI->eraseFromParent();
        continue;
      }

      // Scalarize CopyAddrInst.
      auto *CAI = cast<CopyAddrInst>(User);
      SILBuilderWithScope B(User, CAI);

      // Determine if this is a copy *from* or *to* "Pointer".
      if (CAI->getSrc() == Pointer) {
        // Copy from pointer.
        getScalarizedElementAddresses(CAI->getDest(), B, CAI->getLoc(),
                                      ElementTmps);
        for (unsigned i = 0, e = ElementAddrs.size(); i != e; ++i)
          B.createCopyAddr(CAI->getLoc(), ElementAddrs[i], ElementTmps[i],
                           CAI->isTakeOfSrc(), CAI->isInitializationOfDest());

      } else {
        getScalarizedElementAddresses(CAI->getSrc(), B, CAI->getLoc(),
                                      ElementTmps);
        for (unsigned i = 0, e = ElementAddrs.size(); i != e; ++i)
          B.createCopyAddr(CAI->getLoc(), ElementTmps[i], ElementAddrs[i],
                           CAI->isTakeOfSrc(), CAI->isInitializationOfDest());
      }
      CAI->eraseFromParent();
    }

    // Now that we've scalarized some stuff, recurse down into the newly created
    // element address computations to recursively process it.  This can cause
    // further scalarization.
    if (llvm::any_of(ElementAddrs, [&](SILValue v) {
          return !collectUses(cast<TupleElementAddrInst>(v));
        })) {
      return false;
    }
  }

  return true;
}

/// collectPMOElementUsesFrom - Analyze all uses of the specified allocation
/// instruction (alloc_box, alloc_stack or mark_uninitialized), classifying them
/// and storing the information found into the Uses and Releases lists.
bool swift::collectPMOElementUsesFrom(
    const PMOMemoryObjectInfo &MemoryInfo, SmallVectorImpl<PMOMemoryUse> &Uses,
    SmallVectorImpl<SILInstruction *> &Releases) {
  return ElementUseCollector(MemoryInfo, Uses, Releases).collectFrom();
}