<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[/dev/zero]]></title>
  <link href="http://www.devzero.it/atom.xml" rel="self"/>
  <link href="http://www.devzero.it/"/>
  <updated>2016-10-28T13:57:28+02:00</updated>
  <id>http://www.devzero.it/</id>
  <author>
    <name><![CDATA[unixo]]></name>
    <email><![CDATA[unixo@devzero.it]]></email>
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Changing location with Alfred]]></title>
    <link href="http://www.devzero.it/blog/2015/06/02/Change-location-with-Alfred/"/>
    <updated>2015-06-02T11:16:00+02:00</updated>
    <id>http://www.devzero.it/blog/2015/06/02/Change-location-with-Alfred</id>
    <content type="html"><![CDATA[<p>As developer, I&rsquo;ve always been a fan of keyboard; as many other coders I learned as much key combinations as possible instead of using a mouse: and here comes <a href="http://www.alfredapp.com">Alfred</a> and its workflows.
Alfred is a powerful conterpart to Apple Spotlight as it saves your time when you search for files online or on your Mac, it helps you to more productive with hotkeys, keywords and file actions at your fingertips.
With Alfred you can also create immensely powerful workflows by connecting keywords, hotkeys and actions together to extend Alfred to do amazing things without writing a single line of code!</p>

<p>That&rsquo;s the scenario for my first workflow!</p>

<!-- more -->


<h1>Changing location</h1>

<p>I configured three <a href="https://support.apple.com/en-us/HT202480">network locations</a> on my laptop, two for home and the last one for office setup; I can switch between locations using the network pane in System Preferences or via the Apple logo in the menu bar&hellip; but why don&rsquo;t reach these settings via keyboard?</p>

<p>Since 2003, Macos comes with an handy command line utility called <strong>scselect</strong>: scselect provides access to the system configuration sets, commonly referred to as &ldquo;locations&rdquo;.  When invoked with no arguments, scselect displays the names and associated identifiers for each defined &ldquo;location&rdquo; and indicates which is currently active. scselect also allows the user to select or change the active &ldquo;location&rdquo; by specifying its name or identifier.</p>

<p>Let&rsquo;s see how it works.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>unixo:~ unixo$ scselect
</span><span class='line'>Defined sets include: (* == current set)
</span><span class='line'>   697A0192-1617-4BBF-A9FB-96E724876608   (Automatic)
</span><span class='line'>   BFA8697D-49B0-457C-8080-CD9E18337E3E   (Home (Wi-Fi))
</span><span class='line'>   FCFEA5B9-DE9F-41FA-92BB-EEA054A00846   (Home (Thunderbolt))
</span><span class='line'> * 0F946EF4-B73C-4AE5-8883-8A765DB82D2F   (Office)</span></code></pre></td></tr></table></div></figure>


<p>As we expects, without any paramters, scselect returned all the configured locations: each of them is represented by the tuple &lt;ID, name>; the line marked with the star represents the currently active network location, &ldquo;Office&rdquo; in this case.</p>

<p>If you want to switch to a specific location, simply specify its ID as parameter and let scselect do the rest.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>unixo:~ unixo$ scselect BFA8697D-49B0-457C-8080-CD9E18337E3E
</span><span class='line'>CurrentSet updated to BFA8697D-49B0-457C-8080-CD9E18337E3E (Home (Wi-Fi))</span></code></pre></td></tr></table></div></figure>


<h1>The workflow</h1>

<p>My workflow will be made up of three objects:</p>

<ul>
<li><em>scselect</em>, without any arguments, will be used in the first block to get the list of all network location (or part of it)</li>
<li>the second block would be executed by Alfred only if the user select the an entry from the result list</li>
<li>the third and last one will notify the user if everything went fine.</li>
</ul>


<p><img class="center" src="http://www.devzero.it/assets/images/posts/alfred-workflow.png"></p>

<h2>The script filter</h2>

<p>For a script filter (the first block in the above picture) to display an output in result list, Alfred expects at least a XML like this:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;items&gt;</span>
</span><span class='line'>  <span class="nt">&lt;item</span> <span class="na">uid=</span><span class="s">&quot;...&quot;</span> <span class="na">arg=</span><span class="s">&quot;...&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>      <span class="nt">&lt;title&gt;</span>here goes the title of the item<span class="nt">&lt;/title&gt;</span>
</span><span class='line'>      <span class="nt">&lt;subtitle&gt;</span>and here the subtitle for a small description<span class="nt">&lt;/subtitle&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/item&gt;</span>
</span><span class='line'>  <span class="nt">&lt;item&gt;</span>
</span><span class='line'>      ...
</span><span class='line'>  <span class="nt">&lt;/item&gt;</span>
</span><span class='line'><span class="nt">&lt;/items&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>The first block, the script filter, will use scselect to display all configured locations, formatted in XML.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nb">shopt</span> -s nocasematch;
</span><span class='line'><span class="nb">echo</span> <span class="s2">&quot;&lt;items&gt;&quot;</span>;
</span><span class='line'>
</span><span class='line'><span class="o">[</span> -z <span class="s2">&quot;{query}&quot;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="nv">line</span><span class="o">=</span>1 <span class="o">||</span> <span class="nv">line</span><span class="o">=</span>0
</span><span class='line'>
</span><span class='line'>scselect | grep -i <span class="s2">&quot;{query}&quot;</span> | <span class="se">\</span>
</span><span class='line'>  sed -Ee <span class="k">${</span><span class="nv">line</span><span class="k">}</span>d -e <span class="s1">&#39;s/  \(/ /g&#39;</span> -e <span class="s1">&#39;s/)$//g&#39;</span> -e <span class="s1">&#39;s/^[ \*]+//g&#39;</span> | <span class="se">\</span>
</span><span class='line'>  sed -E <span class="s1">&#39;s/^([^ ]+) (.*)$/&lt;item uid=&quot;\1&quot; arg=&quot;\1&quot;&gt;&lt;title&gt;\2&lt;\/title&gt;&lt;subtitle&gt;Set &quot;\2&quot; as current location&lt;\/subtitle&gt;&lt;\/item&gt;/g&#39;</span>;
</span><span class='line'>
</span><span class='line'><span class="nb">echo</span> <span class="s2">&quot;&lt;/items&gt;&quot;</span>;
</span></code></pre></td></tr></table></div></figure>


<p>This would generate the folloing result:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;items&gt;</span>
</span><span class='line'>  <span class="nt">&lt;item</span> <span class="na">uid=</span><span class="s">&quot;697A0192-1617-4BBF-A9FB-96E724876608&quot;</span> <span class="na">arg=</span><span class="s">&quot;697A0192-1617-4BBF-A9FB-96E724876608&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>      <span class="nt">&lt;title&gt;</span>Automatic<span class="nt">&lt;/title&gt;</span>
</span><span class='line'>      <span class="nt">&lt;subtitle&gt;</span>Set &quot;Automatic&quot; as current location<span class="nt">&lt;/subtitle&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/item&gt;</span>
</span><span class='line'>  <span class="nt">&lt;item</span> <span class="na">uid=</span><span class="s">&quot;BFA8697D-49B0-457C-8080-CD9E18337E3E&quot;</span> <span class="na">arg=</span><span class="s">&quot;BFA8697D-49B0-457C-8080-CD9E18337E3E&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>      <span class="nt">&lt;title&gt;</span>Home (Wi-Fi)<span class="nt">&lt;/title&gt;</span>
</span><span class='line'>      <span class="nt">&lt;subtitle&gt;</span>Set &quot;Home (Wi-Fi)&quot; as current location<span class="nt">&lt;/subtitle&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/item&gt;</span>
</span><span class='line'>  <span class="nt">&lt;item</span> <span class="na">uid=</span><span class="s">&quot;FCFEA5B9-DE9F-41FA-92BB-EEA054A00846&quot;</span> <span class="na">arg=</span><span class="s">&quot;FCFEA5B9-DE9F-41FA-92BB-EEA054A00846&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>      <span class="nt">&lt;title&gt;</span>Home (Thunderbolt)<span class="nt">&lt;/title&gt;</span>
</span><span class='line'>      <span class="nt">&lt;subtitle&gt;</span>Set &quot;Home (Thunderbolt)&quot; as current location<span class="nt">&lt;/subtitle&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/item&gt;</span>
</span><span class='line'>  <span class="nt">&lt;item</span> <span class="na">uid=</span><span class="s">&quot;0F946EF4-B73C-4AE5-8883-8A765DB82D2F&quot;</span> <span class="na">arg=</span><span class="s">&quot;0F946EF4-B73C-4AE5-8883-8A765DB82D2F&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>      <span class="nt">&lt;title&gt;</span>Office<span class="nt">&lt;/title&gt;</span>
</span><span class='line'>      <span class="nt">&lt;subtitle&gt;</span>Set &quot;Office&quot; as current location<span class="nt">&lt;/subtitle&gt;</span>
</span><span class='line'>  <span class="nt">&lt;/item&gt;</span>
</span><span class='line'><span class="nt">&lt;/items&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Each location is represented by an <code>&lt;item&gt;</code> entry: if the user selects a specific location, its <em>ID</em> will be extracted from the property <em>UID</em> of the item: this will be the input for the second block.</p>

<h2>Run script</h2>

<p>The second script is invoked only if user didn&rsquo;t abort the operation and selected something.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>scselect <span class="s2">&quot;{query}&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>The <code>query</code> variable will be filled by Alfred with the <code>UID</code> of the selected item.</p>

<h2>Post notification</h2>

<p>Yay, you changed the location, let Alfred notify the user.</p>

<p>You can download the workflow <a href="http://www.devzero.it/attachments/Switch%20location.alfredworkflow">here</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Symfony entities and traits]]></title>
    <link href="http://www.devzero.it/blog/2015/05/08/symfony-and-traits/"/>
    <updated>2015-05-08T10:55:00+02:00</updated>
    <id>http://www.devzero.it/blog/2015/05/08/symfony-and-traits</id>
    <content type="html"><![CDATA[<p>I&rsquo;m currently working on a <a href="http://symfony.com/">Symfony</a>-based project whose data model is far from being stable and all its properties known;
for this reason, three <a href="http://www.doctrine-project.org">Doctrine</a> entities have a common private property called &ldquo;attributes&rdquo;,
declared as <a href="http://doctrine-dbal.readthedocs.org/en/latest/reference/types.html#json-array">json_array</a>: by mapping and converting
array data based on PHP’s JSON encoding functions, I&rsquo;m sure that any other additional entity properties can be added to the array,
without altering database structure or application logic.</p>

<!-- more -->


<p>The following piece of code shows one of the entity.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="k">namespace</span> <span class="nx">AppBundle\Entity</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">use</span> <span class="nx">Doctrine\ORM\Mapping</span> <span class="k">AS</span> <span class="nx">ORM</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="sd">/**</span>
</span><span class='line'><span class="sd"> * @ORM\Entity</span>
</span><span class='line'><span class="sd"> * @ORM\Table()</span>
</span><span class='line'><span class="sd"> */</span>
</span><span class='line'><span class="k">class</span> <span class="nc">Archetype</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>  <span class="o">...</span>
</span><span class='line'>      
</span><span class='line'>    <span class="sd">/**</span>
</span><span class='line'><span class="sd">     * @var array</span>
</span><span class='line'><span class="sd">     * @ORM\Column(type=&quot;json_array&quot;, nullable=true)</span>
</span><span class='line'><span class="sd">     */</span>
</span><span class='line'>    <span class="k">private</span> <span class="nv">$attributes</span><span class="p">;</span>
</span><span class='line'>  
</span><span class='line'>  <span class="o">...</span>
</span><span class='line'><span class="p">}</span>  
</span></code></pre></td></tr></table></div></figure>


<p>Of course this feature comes with a little of logic to be implemented, so that controllers and repositories can use them:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="k">public</span> <span class="k">function</span> <span class="nf">setAttribute</span><span class="p">(</span><span class="nv">$name</span><span class="p">,</span> <span class="nv">$value</span><span class="p">,</span> <span class="nv">$exposed</span> <span class="o">=</span> <span class="k">true</span><span class="p">)</span> <span class="p">{</span> <span class="o">...</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">public</span> <span class="k">function</span> <span class="nf">setAttributes</span><span class="p">(</span><span class="nv">$attributes</span><span class="p">)</span> <span class="p">{</span> <span class="o">...</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">public</span> <span class="k">function</span> <span class="nf">getAttributes</span><span class="p">()</span> <span class="p">{</span> <span class="o">...</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">public</span> <span class="k">function</span> <span class="nf">getAttribute</span><span class="p">(</span><span class="nv">$key</span><span class="p">)</span> <span class="p">{</span> <span class="o">...</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">public</span> <span class="k">function</span> <span class="nf">hasAttribute</span><span class="p">(</span><span class="nv">$key</span><span class="p">)</span> <span class="p">{</span> <span class="o">...</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Instead of duplicating all these methods in each entity class, I found that PHP&rsquo;s <em>traits</em> offers a good and nice tradeoff.</p>

<h2>Traits</h2>

<p>As of PHP 5.4.0, PHP implements a method of code reuse called Traits.
Traits are a mechanism for code reuse in single inheritance languages such as PHP. A Trait is intended to reduce some limitations of single inheritance by enabling a developer to reuse sets of methods freely in several independent classes living in different class hierarchies. The semantics of the combination of Traits and classes is defined in a way which reduces complexity, and avoids the typical problems associated with multiple inheritance and Mixins.</p>

<p>I created a trait called &ldquo;AttributeTrait&rdquo; in the same namespace of my entities and implemented in it the methods listed before.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="k">namespace</span> <span class="nx">AppBundle\Entity</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">trait</span> <span class="nx">AttributeTrait</span> <span class="p">{</span>
</span><span class='line'>  
</span><span class='line'>    <span class="sd">/**</span>
</span><span class='line'><span class="sd">     * @var array</span>
</span><span class='line'><span class="sd">     * @ORM\Column(type=&quot;json_array&quot;, nullable=true)</span>
</span><span class='line'><span class="sd">     */</span>
</span><span class='line'>    <span class="k">private</span> <span class="nv">$attributes</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="k">function</span> <span class="nf">setAttribute</span><span class="p">(</span><span class="nv">$name</span><span class="p">,</span> <span class="nv">$value</span><span class="p">,</span> <span class="nv">$exposed</span> <span class="o">=</span> <span class="k">true</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="nv">$attribute</span> <span class="o">=</span> <span class="nb">compact</span><span class="p">(</span><span class="s1">&#39;value&#39;</span><span class="p">,</span> <span class="s1">&#39;exposed&#39;</span><span class="p">);</span>
</span><span class='line'>        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">attributes</span><span class="p">[</span><span class="nv">$name</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$attribute</span><span class="p">;</span>
</span><span class='line'>        <span class="k">return</span> <span class="nv">$this</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>  
</span><span class='line'>  <span class="o">...</span>
</span></code></pre></td></tr></table></div></figure>


<p>The nice aspect is that, the <em>traits</em> and the class that uses it, are <em>merged</em> togheter, as they were a whole class: this means that Doctrine will
create a table with all the properties declared in the entity class and those belonging to the traits.
The <code>$this</code> reference points to the container class, the entity instance in this case, so no changes to the code should be made.</p>

<h2>Accessing the property from Twig</h2>

<p>To complete the picture and make it more flexible even inside a Twig templates, I also implemented the special method <code>__call</code>,
to make the code more readable.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="o">&lt;?</span><span class="nx">php</span>
</span><span class='line'>
</span><span class='line'><span class="k">namespace</span> <span class="nx">AppBundle\Entity</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">trait</span> <span class="nx">AttributeTrait</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>    <span class="sd">/**</span>
</span><span class='line'><span class="sd">     * @var array</span>
</span><span class='line'><span class="sd">     * @ORM\Column(type=&quot;json_array&quot;, nullable=true)</span>
</span><span class='line'><span class="sd">     */</span>
</span><span class='line'>    <span class="k">private</span> <span class="nv">$attributes</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="k">function</span> <span class="nf">__call</span><span class="p">(</span><span class="nv">$name</span><span class="p">,</span> <span class="nv">$arguments</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="nv">$attributeName</span> <span class="o">=</span>  <span class="nb">lcfirst</span><span class="p">(</span><span class="nb">str_replace</span><span class="p">(</span><span class="s1">&#39;get&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="nx">trim</span><span class="p">(</span><span class="nv">$name</span><span class="p">)));</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="nb">array_key_exists</span><span class="p">(</span><span class="nv">$attributeName</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">attributes</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">attributes</span><span class="p">[</span><span class="nv">$attributeName</span><span class="p">][</span><span class="s1">&#39;value&#39;</span><span class="p">];</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="k">throw</span> <span class="k">new</span> <span class="nx">\BadMethodCallException</span><span class="p">(</span><span class="nb">sprintf</span><span class="p">(</span><span class="s1">&#39;Product has no &quot;%s&quot; attribute.&#39;</span><span class="p">,</span> <span class="nv">$attributeName</span><span class="p">));</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="sd">/**</span>
</span><span class='line'><span class="sd">     * Add a new attribute</span>
</span><span class='line'><span class="sd">     * </span>
</span><span class='line'><span class="sd">     * @param string $name</span>
</span><span class='line'><span class="sd">     * @param mixed $value</span>
</span><span class='line'><span class="sd">     * @param bool $exposed</span>
</span><span class='line'><span class="sd">     * @return container class</span>
</span><span class='line'><span class="sd">     */</span>
</span><span class='line'>    <span class="k">public</span> <span class="k">function</span> <span class="nf">setAttribute</span><span class="p">(</span><span class="nv">$name</span><span class="p">,</span> <span class="nv">$value</span><span class="p">,</span> <span class="nv">$exposed</span> <span class="o">=</span> <span class="k">true</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="nv">$attribute</span> <span class="o">=</span> <span class="nb">compact</span><span class="p">(</span><span class="s1">&#39;value&#39;</span><span class="p">,</span> <span class="s1">&#39;exposed&#39;</span><span class="p">);</span>
</span><span class='line'>        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">attributes</span><span class="p">[</span><span class="nv">$name</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$attribute</span><span class="p">;</span>
</span><span class='line'>        <span class="k">return</span> <span class="nv">$this</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="sd">/**</span>
</span><span class='line'><span class="sd">     * Add a set of attributes</span>
</span><span class='line'><span class="sd">     * </span>
</span><span class='line'><span class="sd">     * @param array $attributes</span>
</span><span class='line'><span class="sd">     * @return container class</span>
</span><span class='line'><span class="sd">     */</span>
</span><span class='line'>    <span class="k">public</span> <span class="k">function</span> <span class="nf">setAttributes</span><span class="p">(</span><span class="nv">$attributes</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">attributes</span> <span class="o">=</span> <span class="nv">$attributes</span><span class="p">;</span>
</span><span class='line'>        <span class="k">return</span> <span class="nv">$this</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="sd">/**</span>
</span><span class='line'><span class="sd">     * Get all the attributes</span>
</span><span class='line'><span class="sd">     * </span>
</span><span class='line'><span class="sd">     * @return array|null</span>
</span><span class='line'><span class="sd">     */</span>
</span><span class='line'>    <span class="k">public</span> <span class="k">function</span> <span class="nf">getAttributes</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">attributes</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="sd">/**</span>
</span><span class='line'><span class="sd">     * Get a single attribute corresponding to the given key</span>
</span><span class='line'><span class="sd">     * </span>
</span><span class='line'><span class="sd">     * @see __call</span>
</span><span class='line'><span class="sd">     * @param string $key</span>
</span><span class='line'><span class="sd">     * @return mixed</span>
</span><span class='line'><span class="sd">     */</span>
</span><span class='line'>    <span class="k">public</span> <span class="k">function</span> <span class="nf">getAttribute</span><span class="p">(</span><span class="nv">$key</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">attributes</span><span class="p">[</span><span class="nv">$key</span><span class="p">][</span><span class="s1">&#39;value&#39;</span><span class="p">];</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="sd">/**</span>
</span><span class='line'><span class="sd">     * Returns true if instance has the given attribute set</span>
</span><span class='line'><span class="sd">     * </span>
</span><span class='line'><span class="sd">     * @param string $key</span>
</span><span class='line'><span class="sd">     * @return boolean</span>
</span><span class='line'><span class="sd">     */</span>
</span><span class='line'>    <span class="k">public</span> <span class="k">function</span> <span class="nf">hasAttribute</span><span class="p">(</span><span class="nv">$key</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="nb">array_key_exists</span><span class="p">(</span><span class="nv">$key</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">attributes</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>From within a <a href="http://twig.sensiolabs.org">Twig</a> template, I could use the typical syntax <code>instance.property</code>.</p>

<p>For example:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="o">&lt;?</span><span class="nx">php</span>
</span><span class='line'>
</span><span class='line'><span class="nv">$archetype</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Archetype</span><span class="p">();</span>
</span><span class='line'><span class="nv">$archetype</span><span class="o">-&gt;</span><span class="na">setAttribute</span><span class="p">(</span><span class="s1">&#39;width&#39;</span><span class="p">,</span> <span class="mf">25.4</span><span class="p">);</span>
</span><span class='line'><span class="k">echo</span> <span class="nv">$archetype</span><span class="o">-&gt;</span><span class="na">getWidth</span><span class="p">();</span> <span class="c1">// this will invoke __call</span>
</span></code></pre></td></tr></table></div></figure>


<p>From within a Twig template:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;p&gt;</span>Width: {{ archetype.width }}<span class="nt">&lt;/p&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>The <code>width</code> property doesn&rsquo;t exist in class <code>Archetype</code>, but was added as dynamic property with trait support; Twig will call the
corresponding method <code>getWidth</code> which is intercepted from special method <code>__call</code> and converted in an attribute access.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Guzzle and the empty cookie]]></title>
    <link href="http://www.devzero.it/blog/2014/02/05/guzzle-and-the-empty-cookie/"/>
    <updated>2014-02-05T10:55:00+01:00</updated>
    <id>http://www.devzero.it/blog/2014/02/05/guzzle-and-the-empty-cookie</id>
    <content type="html"><![CDATA[<p>Recently I had to write an HTTP client to fetch some data from a remote website and parse it.</p>

<p>I ain&rsquo;t a perl-fan, for this kind of problem I prefer PHP as development tool, so I was looking for
some rock-solid PHP-framework that was:</p>

<ul>
<li>object-oriented developed</li>
<li>able to manage an authentication (basic, digest, &hellip;)</li>
<li>capable to issue any HTTP method (GET, POST, DELETE, &hellip;)</li>
<li>(possibly) managed by composer</li>
</ul>


<!-- more -->


<p>Googling around I found <a href="http://docs.guzzlephp.org/en/latest/">Guzzle</a>, which meets all my requirements, makes
use of Symfony&rsquo;s event dispatcher (which I used in the past) and it&rsquo;s also used by other well-known realities
such as Drupal and <a href="https://github.com/fabpot/goutte">Goutte</a>.</p>

<p>Guzzle is ready-to-use, easy to setup and integrate with your project; by the way I spent half an afternoon
analyzing the following scenario.</p>

<p><img class="center" src="http://www.devzero.it/assets/images/posts/guzzle.png" /></p>

<p>In its first response, the server sets the cookie <strong>FOO</strong> and, after the client successfully authenticates (basic
authentication), the server clears the cookie <strong>FOO</strong> (assigning an empty value), along with creating a new one
(<em>BAR</em>). From this moment, all requests sent by the client must not include the cookie <code>FOO</code>, but only <code>BAR</code>.</p>

<p>The problem is that the empty cookie <code>FOO</code> contained in the second server response is correctly discarded by
Guzzle as it&rsquo;s considered <em>invalid</em>, but Guzzle doesn&rsquo;t check if there is already a cookie with the same name in
the cookie jar.</p>

<p>Introducing the patch.</p>

<p><img class="center" src="http://www.devzero.it/assets/images/posts/guzzle_patch.png" /></p>

<p>You can find the source <a href="https://github.com/unixo/guzzle/commit/f9a2553d8ed0526b56d170a4f5f8434c4daa829e">here</a>,
the <a href="https://github.com/unixo/guzzle/commit/805b34a872cc768260cf3acacd9f22a024000871">unit test</a> and the
merged <a href="https://github.com/guzzle/guzzle/pull/546">pull request</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Clearing Symfony cache]]></title>
    <link href="http://www.devzero.it/blog/2013/08/18/clearing-symfony-cache/"/>
    <updated>2013-08-18T13:29:00+02:00</updated>
    <id>http://www.devzero.it/blog/2013/08/18/clearing-symfony-cache</id>
    <content type="html"><![CDATA[<p>I&rsquo;m currently working on a Symfony2-based project which makes also use of the great
<a href="http://jmsyst.com/bundles/JMSSecurityExtraBundle">JMSSecurityExtraBundle</a> by Johannes Schmitt,
in order to address method security authorization.</p>

<p>Everything work fine, but deploying in production, I ran into this problem:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="o">%</span> <span class="n">app</span><span class="o">/</span><span class="n">console</span> <span class="nl">cache:</span><span class="n">clear</span> <span class="o">--</span><span class="n">env</span><span class="o">=</span><span class="n">prod</span>
</span><span class='line'><span class="n">Clearing</span> <span class="n">the</span> <span class="n">cache</span> <span class="k">for</span> <span class="n">the</span> <span class="n">prod</span> <span class="n">environment</span> <span class="n">with</span> <span class="n">debug</span> <span class="n">false</span>
</span><span class='line'><span class="n">PHP</span> <span class="n">Fatal</span> <span class="nl">error:</span>  <span class="n">Cannot</span> <span class="n">redeclare</span> <span class="n">class</span> <span class="n">EnhancedProxy_</span><span class="p">....</span> <span class="n">on</span> <span class="n">line</span> <span class="mi">64</span>
</span></code></pre></td></tr></table></div></figure>




<!-- more -->


<p>I spent a lot of time digging Google, the problem seems very hard to solve at its origin, but I
found this simple workaround: without any further arguments, the <code>cache:clear</code> command also tries
to warm-up the cache and it seems that causes the problem.</p>

<p>By splitting the two operations, everything worked (at least for me!).</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="o">%</span> <span class="n">app</span><span class="o">/</span><span class="n">console</span> <span class="nl">cache:</span><span class="n">clear</span> <span class="o">--</span><span class="n">env</span><span class="o">=</span><span class="n">prod</span> <span class="o">--</span><span class="n">no</span><span class="o">-</span><span class="n">warmup</span>
</span><span class='line'><span class="n">Clearing</span> <span class="n">the</span> <span class="n">cache</span> <span class="k">for</span> <span class="n">the</span> <span class="n">prod</span> <span class="n">environment</span> <span class="n">with</span> <span class="n">debug</span> <span class="n">false</span>
</span><span class='line'><span class="o">%</span> <span class="n">app</span><span class="o">/</span><span class="n">console</span> <span class="nl">cache:</span><span class="n">warmup</span> <span class="o">--</span><span class="n">env</span><span class="o">=</span><span class="n">prod</span>
</span><span class='line'><span class="n">Warming</span> <span class="n">up</span> <span class="n">the</span> <span class="n">cache</span> <span class="k">for</span> <span class="n">the</span> <span class="n">prod</span> <span class="n">environment</span> <span class="n">with</span> <span class="n">debug</span> <span class="n">false</span>
</span></code></pre></td></tr></table></div></figure>


<p>Hope this saves someone some time.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Importing data in background with CoreData]]></title>
    <link href="http://www.devzero.it/blog/2013/07/21/importing-data-in-background-with-coredata/"/>
    <updated>2013-07-21T11:17:00+02:00</updated>
    <id>http://www.devzero.it/blog/2013/07/21/importing-data-in-background-with-coredata</id>
    <content type="html"><![CDATA[<p>It&rsquo;s very common for an application to import and export data to other programs, granting
intercommunicability and flexibility. This kind of operation should be executed in background, so
that your application UI remains reactive. Under Cocoa and, specifically, with CoreData there are
a lot of available options to implement background operations, as much as a lot of literature and
best practices about it.</p>

<!-- more -->


<p>Here the pattern I chose for my application and the reasons why.</p>

<h1>Problem description</h1>

<p>First of all, my application runs under MacOS, it&rsquo;s backed by CoreData and based on <code>NSPersistentDocument</code>, so my
considerations and needs are strictly related to this context: <em>the same problem would be addressed in a
different way if it was under IOS or requirements were different</em>.</p>

<p>In a subview of my application, user can drop one or more files into a drop view, for example dragging them from Finder;
these files could be of different kind (images, documents, &hellip;) but must be all handled in the same way and, possibly,
without any interaction with the user.
The drop view, the receiver of dropping operation, will ask the import manager to handle these files, returning immediately
and maintaining the UI responsive; the import manager should also be able to import files concurrently, abort one or more
operations if user asked so.</p>

<p><img class="center" src="http://www.devzero.it/assets/images/import_flowchart.png"></p>

<h1>The &ldquo;Import Manager&rdquo;</h1>

<p>As different file types must be handled, there will be an importer for each of them and another one class to
manage them all. The import manager creates an operation queue in which will enqueue the import operations:
it will wait for the drop view to ask to import new resources and create as many operations as requested.</p>

<p>The method <code>importItems:intoDocument</code> of the importer manager is called by the drop view: it requires an
array of items to import and the current document which will be the owner of newly created resources.
Note that <code>items</code> is an array of <code>DZImportItem</code>, a wrapper class that represent a single file to import.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">@implementation</span> <span class="nc">DZImporterManager</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="nf">importItems:</span><span class="p">(</span><span class="n">NSArray</span> <span class="o">*</span><span class="p">)</span><span class="nv">items</span> <span class="nf">intoDocument:</span><span class="p">(</span><span class="n">NSPersistentDocument</span> <span class="o">*</span><span class="p">)</span><span class="nv">aDocument</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">dispatch_queue_t</span> <span class="n">queue</span> <span class="o">=</span> <span class="n">dispatch_get_global_queue</span><span class="p">(</span><span class="n">DISPATCH_QUEUE_PRIORITY_BACKGROUND</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">dispatch_async</span><span class="p">(</span><span class="n">queue</span><span class="p">,</span> <span class="o">^</span><span class="p">{</span>
</span><span class='line'>        <span class="p">[</span><span class="n">items</span> <span class="nl">enumerateObjectsWithOptions:</span><span class="n">NSEnumerationConcurrent</span>
</span><span class='line'>                                <span class="nl">usingBlock:</span><span class="o">^</span><span class="p">(</span><span class="n">DZImportItem</span> <span class="o">*</span><span class="n">item</span><span class="p">,</span> <span class="n">NSUInteger</span> <span class="n">idx</span><span class="p">,</span> <span class="kt">BOOL</span> <span class="o">*</span><span class="n">stop</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                       <span class="c1">// Search for a class handler for current file</span>
</span><span class='line'>                       <span class="n">DZImportOperation</span> <span class="o">*</span><span class="n">operation</span> <span class="o">=</span> <span class="nb">nil</span><span class="p">;</span>
</span><span class='line'>                       <span class="k">for</span> <span class="p">(</span><span class="n">Class</span> <span class="n">handlerClass</span> <span class="k">in</span> <span class="n">_importers</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                           <span class="k">if</span> <span class="p">([</span><span class="n">handlerClass</span> <span class="nl">canOpenURL:</span><span class="n">item</span><span class="p">.</span><span class="n">url</span><span class="p">])</span> <span class="p">{</span>
</span><span class='line'>                               <span class="n">operation</span> <span class="o">=</span> <span class="p">[[</span><span class="n">handlerClass</span> <span class="n">new</span><span class="p">]</span> <span class="nl">initWithItem:</span><span class="n">item</span>
</span><span class='line'>                                                                    <span class="nl">context:</span><span class="n">aDocument</span><span class="p">.</span><span class="n">managedObjectContext</span><span class="p">];</span>
</span><span class='line'>                               <span class="k">break</span><span class="p">;</span>
</span><span class='line'>                           <span class="p">}</span>
</span><span class='line'>                       <span class="p">}</span>
</span><span class='line'>                       <span class="c1">// If an handler was found, enqueue the import operation</span>
</span><span class='line'>                       <span class="k">if</span> <span class="p">(</span><span class="n">operation</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                           <span class="p">[</span><span class="n">_queue</span> <span class="nl">addOperation:</span><span class="n">operation</span><span class="p">];</span>
</span><span class='line'>                       <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>                           <span class="n">DDLogError</span><span class="p">(</span><span class="s">@&quot;No registered handler for %@&quot;</span><span class="p">,</span> <span class="n">item</span><span class="p">.</span><span class="n">url</span><span class="p">);</span>
</span><span class='line'>                           <span class="p">[</span><span class="n">item</span> <span class="nl">setStatus:</span><span class="n">DZStatusAborted</span>
</span><span class='line'>                               <span class="nl">withMessage:</span><span class="n">Localize</span><span class="p">(</span><span class="s">@&quot;No registered handler for this file type&quot;</span><span class="p">)];</span>
</span><span class='line'>                       <span class="p">}</span>
</span><span class='line'>                   <span class="p">}];</span>
</span><span class='line'>    <span class="p">});</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Using <code>dispatch_async</code> of GCD we ensure that this operation will be executed in background and not in
the same queue of UI, without blocking it.</p>

<p>Each data importer is a subclass of <code>NSOperation</code>, its <code>main</code> method will do the job.
The following example is responsible to import image files.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">@implementation</span> <span class="nc">DZImageImportOperation</span>
</span><span class='line'>
</span><span class='line'><span class="k">+</span> <span class="p">(</span><span class="kt">BOOL</span><span class="p">)</span><span class="nf">canOpenURL:</span><span class="p">(</span><span class="n">NSURL</span> <span class="o">*</span><span class="p">)</span><span class="nv">anUrl</span><span class="p">;</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">BOOL</span> <span class="n">retValue</span> <span class="o">=</span> <span class="n">NO</span><span class="p">;</span>
</span><span class='line'>    <span class="n">NSString</span> <span class="o">*</span><span class="n">uti</span><span class="p">;</span>
</span><span class='line'>    <span class="n">NSError</span> <span class="o">*</span><span class="n">error</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">if</span> <span class="p">([</span><span class="n">anUrl</span> <span class="nl">getResourceValue:</span><span class="o">&amp;</span><span class="n">uti</span> <span class="nl">forKey:</span><span class="n">NSURLTypeIdentifierKey</span> <span class="nl">error:</span><span class="o">&amp;</span><span class="n">error</span><span class="p">])</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">retValue</span> <span class="o">=</span> <span class="n">UTTypeConformsTo</span><span class="p">((</span><span class="n">__bridge</span> <span class="n">CFStringRef</span><span class="p">)(</span><span class="n">uti</span><span class="p">),</span> <span class="p">(</span><span class="n">__bridge</span> <span class="n">CFStringRef</span><span class="p">)</span> <span class="s">@&quot;public.image&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">return</span> <span class="n">retValue</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="o">-</span> <span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nl">initWithItem:</span><span class="p">(</span><span class="n">DZImportItem</span> <span class="o">*</span><span class="p">)</span><span class="n">item</span> <span class="nl">context:</span><span class="p">(</span><span class="n">NSManagedObjectContext</span> <span class="o">*</span><span class="p">)</span><span class="n">moc</span><span class="p">;</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">((</span><span class="n">self</span> <span class="o">=</span> <span class="p">[</span><span class="n">super</span> <span class="n">init</span><span class="p">]))</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">_importItem</span> <span class="o">=</span> <span class="n">item</span><span class="p">;</span>
</span><span class='line'>        <span class="n">_context</span> <span class="o">=</span> <span class="p">[</span><span class="n">moc</span> <span class="n">createPrivateSubcontext</span><span class="p">];</span> <span class="cm">/* we&#39;ll see later this method */</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">return</span> <span class="n">self</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="n">main</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">context</span> <span class="nl">performBlockAndWait:</span><span class="o">^</span><span class="p">{</span>
</span><span class='line'>        <span class="err">@</span><span class="n">autoreleasepool</span> <span class="p">{</span>
</span><span class='line'>            <span class="c1">// Create new managed objects in self.context </span>
</span><span class='line'>          <span class="c1">// (an instance of NSManagedObjectContext)</span>
</span><span class='line'>          
</span><span class='line'>            <span class="p">[</span><span class="n">self</span> <span class="n">saveContext</span><span class="p">];</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}];</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">@end</span>
</span></code></pre></td></tr></table></div></figure>


<p>The method <code>canOpenURL</code> checks if the given file conforms to UTI <em>public.image</em>, which identifies an image file,
while its <code>main</code> performs the job of opening the file and creating a corresponding managed object in the context.
The last operation is saving the context: we&rsquo;ll see deeper this part.</p>

<h1>Managed Object Contexts</h1>

<p>The pattern I chose is nested managed object contexts: in this scenario, you create new contexts which are children
of the document&rsquo;s one; at this point all the managed objects created in child context are propagated to the parent
whenever a save occurs.</p>

<p>Let&rsquo;s see the required steps to use them.</p>

<p>As you already saw, the importer makes use of <code>-[NSManagedObjectContext performBlockAndWait]</code>, which implies that
the managed object context has an associated queue. By default, an application based on <code>NSPersistentDocument</code>
creates a managed object context initialized with <code>NSConfinementConcurrencyType</code>, which specifies that the context
will use the thread confinement pattern: trying to use <code>perfomBlock</code> with this concurrency type would rise an
exception.
We have to override this default initialization by rewriting <code>-[NSPersistentDocument setManagedObjectContext:]</code>.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">setManagedObjectContext:</span><span class="p">(</span><span class="n">NSManagedObjectContext</span> <span class="o">*</span><span class="p">)</span><span class="nv">managedObjectContext</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="n">managedObjectContext</span><span class="p">.</span><span class="n">concurrencyType</span> <span class="o">!=</span> <span class="n">NSMainQueueConcurrencyType</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">NSManagedObjectContext</span> <span class="o">*</span><span class="n">context</span> <span class="o">=</span> <span class="p">[[</span><span class="n">NSManagedObjectContext</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithConcurrencyType:</span><span class="n">NSMainQueueConcurrencyType</span><span class="p">];</span>
</span><span class='line'>        <span class="n">context</span><span class="p">.</span><span class="n">persistentStoreCoordinator</span> <span class="o">=</span> <span class="n">managedObjectContext</span><span class="p">.</span><span class="n">persistentStoreCoordinator</span><span class="p">;</span>
</span><span class='line'>        <span class="p">[</span><span class="n">super</span> <span class="nl">setManagedObjectContext:</span><span class="n">context</span><span class="p">];</span>
</span><span class='line'>    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>        <span class="p">[</span><span class="n">super</span> <span class="nl">setManagedObjectContext:</span><span class="n">managedObjectContext</span><span class="p">];</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>In this way we create a managed object context with concurrency type <code>NSMainQueueConcurrencyType</code>, which allows us to
create subcontexts.
The inizialization of each single <code>NSOperation</code> subclass creates a new subcontext which is set up as child of document
main context: a category of <code>NSManagedObjectContext</code> makes available this method and init the context with <code>NSPrivateQueueConcurrencyType</code> so that it will be associated with a private dispatch queue and won&rsquo;t block the main
context.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">NSManagedObjectContext</span><span class="o">*</span><span class="p">)</span><span class="nf">createPrivateSubcontext</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">NSManagedObjectContext</span><span class="o">*</span> <span class="n">context</span> <span class="o">=</span> <span class="p">[[</span><span class="n">NSManagedObjectContext</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithConcurrencyType:</span><span class="n">NSPrivateQueueConcurrencyType</span><span class="p">];</span>
</span><span class='line'>    <span class="n">context</span><span class="p">.</span><span class="n">parentContext</span> <span class="o">=</span> <span class="n">self</span><span class="p">;</span>
</span><span class='line'>    <span class="n">context</span><span class="p">.</span><span class="n">undoManager</span> <span class="o">=</span> <span class="nb">nil</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">return</span> <span class="n">context</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<blockquote><p><strong>Note</strong>: in my case the import operation doesn&rsquo;t ever read of any other existing objects of the parent context, i.e.
doesn&rsquo;t issue a fetch request: this kind of operation would block the parent context even if the request was issued by
the child.</p></blockquote>

<h1>Considerations</h1>

<p>From the performance point of view, it seems this isn&rsquo;t the best approach as nested contexts waste a lot of time in
reciprocal synchronization and do a lot of disk access; read this excellent article by <a href="http://floriankugler.com/blog/2013/4/29/concurrent-core-data-stack-performance-shootout">Florian Kugler</a> about this argument.</p>

<p>According to his measurement, the best solution is create another context which shares the same persistent store; by
the way, under MacOS, it&rsquo;s not unusual for an application to create a new document and working on it without having
saved to disk, i.e. without a persistent store.
In this scenario, I had a lot of problem and got very often this exception: &ldquo;<em>Object&rsquo;s persistent store is not reachable from this NSManagedObjectContext&rsquo;s coordinator</em>&rdquo;.</p>

<p>With nested context there is also no need to watch for context save notification and call <code>mergeChangesFromContextDidSaveNotification</code>.</p>

<h2>Useful resources and links</h2>

<ul>
<li><a href="http://developer.apple.com/library/ios/#releasenotes/DataManagement/RN-CoreData/index.html">Apple&rsquo;s doc</a>: concurrency Support;</li>
<li><a href="http://www.objc.io/issue-2/common-background-practices.html">objc.io</a>: Great article about best practises;</li>
<li><a href="https://github.com/magicalpanda/magicalrecord">Magical Records</a>: Fantastic CoreData helper.</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[NSViewController (bad) initialization]]></title>
    <link href="http://www.devzero.it/blog/2013/07/12/nsviewcontroller-initialization/"/>
    <updated>2013-07-12T21:27:00+02:00</updated>
    <id>http://www.devzero.it/blog/2013/07/12/nsviewcontroller-initialization</id>
    <content type="html"><![CDATA[<p>Since 2008 NSViewController are considered an incomplete implementation, most of all if compared to
its counterpart NSWindowController (for example NSViewController doesn&rsquo;t ensure that its view is
added into the responder chain).</p>

<p>Some days ago, I encountered another issue about view controllers which completely drove me crazy; in
my application I&rsquo;ve a left sidebar and a right subview based on selection of the first one: each time
the user makes a selection, a new subview is loaded by an equivalent NSViewController and presented to
the user.</p>

<!-- more -->


<p>As well as with NSWindowController I put some basic initialization in <code>awakeFromNib</code> method of NSViewController,
to be sure that NIB was loaded and all IBOutlet connected. In particular, in a subview, I had something like this:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="nf">awakeFromNib</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="cm">/* NSArrayController sort descriptor setup */</span>
</span><span class='line'>  <span class="p">[</span><span class="n">self</span> <span class="n">reloadItems</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="nf">reloadItems</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">dispatch_queue_t</span> <span class="n">queue</span> <span class="o">=</span> <span class="n">dispatch_get_global_queue</span><span class="p">(</span><span class="n">DISPATCH_QUEUE_PRIORITY_LOW</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
</span><span class='line'>    <span class="n">dispatch_queue_t</span> <span class="n">main</span> <span class="o">=</span> <span class="n">dispatch_get_main_queue</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">dispatch_async</span><span class="p">(</span><span class="n">queue</span><span class="p">,</span> <span class="o">^</span><span class="p">{</span>
</span><span class='line'>        <span class="p">[</span><span class="n">_arrayController</span> <span class="nl">fetchWithRequest:</span><span class="nb">nil</span> <span class="nl">merge:</span><span class="n">NO</span> <span class="nl">error:</span><span class="nb">nil</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">dispatch_async</span><span class="p">(</span><span class="n">main</span><span class="p">,</span> <span class="o">^</span><span class="p">{</span>
</span><span class='line'>            <span class="p">[</span><span class="n">_tableview</span> <span class="n">reloadData</span><span class="p">];</span>
</span><span class='line'>        <span class="p">});</span>
</span><span class='line'>    <span class="p">});</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Occasionally I noticed that <code>reloadItems</code> was called twice (or more), even much time later after initialization.
After a boring debug session, I realized that in that subview I also had a view-based NSTableview and the view
controller was its datasource and delegate.</p>

<p>That&rsquo;s means that there also is a method like this:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">NSTableRowView</span> <span class="o">*</span><span class="p">)</span><span class="nf">tableView:</span><span class="p">(</span><span class="n">NSTableView</span> <span class="o">*</span><span class="p">)</span><span class="nv">tableView</span> <span class="nf">rowViewForRow:</span><span class="p">(</span><span class="n">NSInteger</span><span class="p">)</span><span class="nv">row</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="kt">id</span> <span class="n">result</span> <span class="o">=</span> <span class="nb">nil</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="n">tableView</span> <span class="o">==</span> <span class="n">_tableview</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">result</span> <span class="o">=</span> <span class="p">[[</span><span class="n">DZMyRowView</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithFrame:</span><span class="n">NSMakeRect</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">100</span><span class="p">)];</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">return</span> <span class="n">result</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Each time this table needs a new row, ask its delegate for an instance of NSTableRowView and <strong>this</strong> causes
<code>awakeFromNib</code> to be called again!!</p>

<p>For (at least) this reason, it&rsquo;s always better initialize NSViewController overriding <code>loadView</code> method or
by updating your <code>awakeFromNib</code> like this:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="nf">awakeFromNib</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">static</span> <span class="kt">BOOL</span> <span class="n">alreadyInit</span> <span class="o">=</span> <span class="n">NO</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">alreadyInit</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="cm">/* NSArrayController sort descriptor setup */</span>
</span><span class='line'>      <span class="p">[</span><span class="n">self</span> <span class="n">reloadItems</span><span class="p">];</span>
</span><span class='line'>      
</span><span class='line'>      <span class="n">alreadyInit</span> <span class="o">=</span> <span class="n">YES</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Your Mac Keeps A Log Of All Your Downloads]]></title>
    <link href="http://www.devzero.it/blog/2013/01/24/Macos-download-history/"/>
    <updated>2013-01-24T00:00:00+01:00</updated>
    <id>http://www.devzero.it/blog/2013/01/24/Macos-download-history</id>
    <content type="html"><![CDATA[<p>Some days ago, I read an interesting post of <a href="http://goo.gl/2BYwT">Michael McConnell</a> about a MacOS
&ldquo;feature&rdquo; that keeps track of all files you downloaded, no matter which programs you used. By the way it&rsquo;s
not such a brand new, as <a href="http://osxdaily.com/2012/07/12/list-download-history-mac-os-x/">OSXDaily</a>
already talked about it one year ago.</p>

<!-- more -->


<h3>Introducing Download History</h3>

<p>Whenever you don&rsquo;t want to mess with Terminal, command lines and sqlite, you can use this simple utility,
called Download History. This tool just opens your quarantine log and shows its content in a more readable
format, powered with search and a command to delete the content.</p>

<p><img src="http://www.devzero.it/assets/images/posts/download-history.png" /></p>

<p>For each table item, the detail box shows:</p>

<ul>
<li>the internal ID that uniquely identifies the resource</li>
<li>the date/time you downloaded the file</li>
<li>the title of the page you visited</li>
<li>the URL of the downloaded file</li>
<li>the original URL you came from</li>
<li>the sender&rsquo;s name and email address (whenever you received an attachment with Mail.app)</li>
</ul>


<p>You can download the program <a href="http://www.devzero.it/attachments/Download%20History.zip">here</a> (built for
Mountain Lion) and browse its sources on <a href="https://github.com/unixo/Download-History">Github</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[PHPExcel and Symfony2]]></title>
    <link href="http://www.devzero.it/blog/2012/12/23/PHPExcel_and_Symfony2/"/>
    <updated>2012-12-23T00:00:00+01:00</updated>
    <id>http://www.devzero.it/blog/2012/12/23/PHPExcel_and_Symfony2</id>
    <content type="html"><![CDATA[<p>Recently, for a website I developed using <a href="www.symfony.com">Symfony 2</a>, I
needed to export some data in Microsoft Excel format. As you may expect, there is already
a great bundle to integrate PHPExcel into your Symfony-based project, the
<a href="https://github.com/liuggio/ExcelBundle">ExcelBundle</a> by liuggio.</p>

<!-- more -->


<p>As stated in bundle documentation, if you are using a HTTPS connection, you have to set
these two headers in your response for compatibility with IE&lt;9:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="nv">$response</span><span class="o">-&gt;</span><span class="na">headers</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span><span class="s1">&#39;Pragma&#39;</span><span class="p">,</span> <span class="s1">&#39;public&#39;</span><span class="p">);</span>
</span><span class='line'><span class="nv">$response</span><span class="o">-&gt;</span><span class="na">headers</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span><span class="s1">&#39;Cache-Control&#39;</span><span class="p">,</span> <span class="s1">&#39;maxage=1&#39;</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>By the way, as I had to generate a lot of reports and, instead of adding these two more lines,
I decided to write a response listener: let&rsquo;s describe these two simple steps.</p>

<p>First of all create a new file named MSExcelListener.php and store under the Listener folder of
your bundle. Here the content of the file.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="o">&lt;?</span><span class="nx">php</span>
</span><span class='line'><span class="k">namespace</span> <span class="nx">replace</span><span class="o">-</span><span class="k">this</span><span class="o">-</span><span class="nx">line</span><span class="o">-</span><span class="nx">with</span><span class="o">-</span><span class="nx">your</span><span class="o">-</span><span class="k">namespace</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">use</span> <span class="nx">Symfony\Component\HttpKernel\HttpKernelInterface</span><span class="p">,</span>
</span><span class='line'>    <span class="nx">Symfony\Component\HttpKernel\Event\FilterResponseEvent</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">MSExcelListener</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>
</span><span class='line'>    <span class="sd">/**</span>
</span><span class='line'><span class="sd">     * Adds the headers to the response once it&#39;s created</span>
</span><span class='line'><span class="sd">     */</span>
</span><span class='line'>    <span class="k">public</span> <span class="k">function</span> <span class="nf">onKernelResponse</span><span class="p">(</span><span class="nx">FilterResponseEvent</span> <span class="nv">$event</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="c1">// Only master requests are handled</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="nx">HttpKernelInterface</span><span class="o">::</span><span class="na">MASTER_REQUEST</span> <span class="o">!==</span> <span class="nv">$event</span><span class="o">-&gt;</span><span class="na">getRequestType</span><span class="p">())</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">return</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// Check if response is serving an &quot;vnd.ms-excel&quot; file</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="nb">preg_match</span><span class="p">(</span><span class="s1">&#39;/vnd.ms-excel/&#39;</span><span class="p">,</span> <span class="nv">$event</span><span class="o">-&gt;</span><span class="na">getResponse</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">headers</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s1">&#39;Content-Type&#39;</span><span class="p">)))</span> <span class="p">{</span>
</span><span class='line'>            <span class="sd">/** </span>
</span><span class='line'><span class="sd">             * If you are using a https connection, you have to set those two </span>
</span><span class='line'><span class="sd">             * headers for compatibility with IE &lt;9</span>
</span><span class='line'><span class="sd">             */</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="k">empty</span><span class="p">(</span><span class="nv">$_SERVER</span><span class="p">[</span><span class="s1">&#39;HTTPS&#39;</span><span class="p">])</span> <span class="o">&amp;&amp;</span> <span class="nv">$_SERVER</span><span class="p">[</span><span class="s1">&#39;HTTPS&#39;</span><span class="p">]</span> <span class="o">!==</span> <span class="s1">&#39;off&#39;</span> <span class="o">||</span> <span class="nv">$_SERVER</span><span class="p">[</span><span class="s1">&#39;SERVER_PORT&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="mi">443</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                <span class="nv">$response</span> <span class="o">=</span> <span class="nv">$event</span><span class="o">-&gt;</span><span class="na">getResponse</span><span class="p">();</span>
</span><span class='line'>                <span class="nv">$response</span><span class="o">-&gt;</span><span class="na">headers</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span><span class="s1">&#39;Pragma&#39;</span><span class="p">,</span> <span class="s1">&#39;public&#39;</span><span class="p">);</span>
</span><span class='line'>                <span class="nv">$response</span><span class="o">-&gt;</span><span class="na">headers</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span><span class="s1">&#39;Cache-Control&#39;</span><span class="p">,</span> <span class="s1">&#39;maxage=1&#39;</span><span class="p">);</span>
</span><span class='line'>                <span class="nv">$event</span><span class="o">-&gt;</span><span class="na">setResponse</span><span class="p">(</span><span class="nv">$response</span><span class="p">);</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="cp">?&gt;</span><span class="x"></span>
</span></code></pre></td></tr></table></div></figure>


<p>Next step is registering the listener, so that Symfony kernel calls it before the response is
sent to the client: simply add these lines to your configuration (just like you register a new
service):</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;service</span> <span class="na">id=</span><span class="s">&quot;listener_msexcel_tweak&quot;</span> <span class="na">class=</span><span class="s">&quot;&lt;YourBundleName&gt;\Listener\MSExcelListener&quot;</span> <span class="na">public=</span><span class="s">&quot;true&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>  <span class="nt">&lt;tag</span> <span class="na">name=</span><span class="s">&quot;kernel.event_listener&quot;</span> <span class="na">event=</span><span class="s">&quot;kernel.response&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'><span class="nt">&lt;/service&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>If the response content-type is a <em>vnd.ms-excel</em> file and the site is running over HTTP,
the two headers are automatically added.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[ASExplorer]]></title>
    <link href="http://www.devzero.it/blog/2012/09/12/asexplorer/"/>
    <updated>2012-09-12T00:00:00+02:00</updated>
    <id>http://www.devzero.it/blog/2012/09/12/asexplorer</id>
    <content type="html"><![CDATA[<p>ASExplorer is a tool useful to browse resources exposed by an application server, such as Weblogic or JBoss; especially useful if you&rsquo;re enforcing security.</p>

<p>Main features:</p>

<ul>
<li>built-in support for Weblogic and JBoss&lt;</li>
<li>JNDI resources browsing</li>
<li>automatic discovering of SQL datasource</li>
<li>automatic loading of external libraries (JARs) to interact with AS</li>
<li>interaction with SQL datasources</li>
<li>easy to extend</li>
</ul>


<!-- more -->


<h2>Installation</h2>

<p>To use ASExplorer you&rsquo;ll need:</p>

<ul>
<li>a JAVA compiler (javac)</li>
<li>a Java based make tool (ant)</li>
<li>specific application server libraries</li>
</ul>


<p>First of all, download the package and build it:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ cd &lt;path-to-asexplorer>
</span><span class='line'>$ ant
</span><span class='line'>$ cd dist
</span><span class='line'>$ mkdir -p lib/ext</span></code></pre></td></tr></table></div></figure>


<p>Copy all <em>JAR</em> files you need to connect to in this folder (lib/ext); in my testing environment, I use the following files:</p>

<ul>
<li>concurrent.jar</li>
<li>cryptojFIPS.jar</li>
<li>jboss-client.jar</li>
<li>jboss-common-core.jar</li>
<li>jboss-integration.jar</li>
<li>jboss-jmx.jar</li>
<li>jboss-logging-log4j.jar</li>
<li>jboss-logging-spi.jar</li>
<li>jboss-remoting.jar</li>
<li>jboss-security-spi.jar</li>
<li>jboss-serialization.jar</li>
<li>jbossall-client.jar</li>
<li>jbosscx-client.jar</li>
<li>jbosssx-client.jar</li>
<li>jnp-client.jar</li>
<li>ojdbc14.jar</li>
<li>webserviceclient+ssl.jar</li>
<li>webserviceclient.jar</li>
<li>wlcipher.jar</li>
<li>wlfullclient.jar</li>
<li>wls-api.jar</li>
<li>wlthint3client.jar</li>
</ul>


<h2>Examples</h2>

<h3>Enumerate all JNDI resources exposed by application server</h3>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ java -jar ASExplorer.jar --server localhost:1099 --type jboss --command browse
</span><span class='line'> |
</span><span class='line'> +- UserTransactionSessionFactory
</span><span class='line'> +- UUIDKeyGeneratorFactory
</span><span class='line'> +- MySqlDS
</span><span class='line'> +- SecureManagementView
</span><span class='line'> | +- remote-org.jboss.deployers.spi.management.ManagementView
</span><span class='line'> | +- remote</span></code></pre></td></tr></table></div></figure>


<h3>Automatic datasources enumeration</h3>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ java -jar ASExplorer.jar --server localhost:1099 --type jboss --command enumds
</span><span class='line'>Found 1 datasource(s)
</span><span class='line'>MySqlDS - MySQL 5.5.13-log</span></code></pre></td></tr></table></div></figure>


<h3>Interaction with SQL datasources</h3>

<p>Assuming that your application server is exporting an Oracle-based datasource named <em>OracleDS</em>:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ java -jar ASExplorer.jar -s 127.0.0.1:7100 -t weblogic -c sql-select --sql 'SELECT * FROM session_privs' --datasource OracleDS
</span><span class='line'>| PRIVILEGE 
</span><span class='line'>| CREATE SESSION 
</span><span class='line'>| UNLIMITED TABLESPACE 
</span><span class='line'>| CREATE TABLE 
</span><span class='line'>| CREATE CLUSTER 
</span><span class='line'>| CREATE SEQUENCE 
</span><span class='line'>| CREATE PROCEDURE 
</span><span class='line'>| CREATE TRIGGER 
</span><span class='line'>| CREATE TYPE 
</span><span class='line'>| CREATE OPERATOR 
</span><span class='line'>| CREATE INDEXTYPE</span></code></pre></td></tr></table></div></figure>


<p>Parameters available:</p>

<table class="table table-condensed table-striped table-bordered">
<thead><tr><th>Parameter</th><th>Description</th></tr></thead>
<tbody>
    <tr><td>&#8211;datasource <em>name</em></td><td>datasource name to interact (<strong>required</strong>)</td></tr>
    <tr><td>&#8211;sql <em>string</em></td><td>SELECT command to issue (<strong>required</strong>)</td></tr>
    <tr><td>&#8211;colsize <em>num</em></td><td>limit all columns size to &#8216;num&#8217; (<em>optional</em>)</td></tr>
</tbody>
</table>


<h3>Inspect a class with reflection</h3>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>java -jar ASExplorer.jar --server localhost:1099 --type jboss --command inspect --class jmx/invoker</span></code></pre></td></tr></table></div></figure>


<h3>TODO</h3>

<ul>
<li>complete log4j integration</li>
<li>add GlassFish support</li>
<li>support for DQL queries</li>
</ul>


<p>Check it out at <a href="https://github.com/unixo/ASExplorer">GitHub</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Sistemi Operativi: vmbo]]></title>
    <link href="http://www.devzero.it/blog/2012/03/15/sistemi-operativi-vmbo/"/>
    <updated>2012-03-15T00:00:00+01:00</updated>
    <id>http://www.devzero.it/blog/2012/03/15/sistemi-operativi-vmbo</id>
    <content type="html"><![CDATA[<p>Continua la serie di progetti sviluppati a scopi didattici per l&#8217;Università di Urbino &ldquo;Carlo Bo&rdquo;.</p>

<h2>Specifica del problema</h2>

<p>Scrivere un programma multithread che consenta di valutare le performance, in termini di
numero di <em>page fault</em>, di algoritmi di rimpiazzamento delle pagine per la gestione della
memoria virtuale.</p>

<p>Il programma dovrà essere costituito da un’entità principale che operi come una Memory Management Unit
(MMU), un numero arbitrario (<em>n</em>) di thread, ove ogni thread emuli un singolo processo (PROCESSO)
e, infine, da un’entità che emuli un dispositivo di I/O (DISPOSITIVO I/O).</p>

<!-- more -->


<p>Il programma dovrà simulare una sessione di lavoro, nella quale sono presenti <em>n</em> processi che
possono accedere alla memoria e generare richieste di I/O. I processi dovranno generare indirizzi di memoria
casuali. Infine, il programma terminerà una volta raggiunto il numero prestabilito di accessi in memoria totali.</p>

<h3>MMU</h3>

<p>L’entità MMU sarà la base del sistema ed utilizzerà l’algoritmo di rimpiazzamento delle
pagine oggetto di test. Essa dovrà essere istanziata dal thread principale (<em>main</em>) e
sarà gestita come oggetto condiviso tra i diversi thread dei PROCESSI. In particolare essa
definirà la dimensione dello spazio di indirizzamento virtuale, la dimensione della memoria
fisica disponibile e la dimensione della pagina.</p>

<p>La MMU dovrà, inoltre, contenere una lista di tabelle della pagine ciascuna relativa ad
un PROCESSO. La definizione della specifica delle tabelle delle pagine sarà lasciata allo
studente, e naturalmente dipenderà dal particolare algoritmo di rimpiazza mento implementato.</p>

<p>I PROCESSI dovranno generare indirizzi verso la MMU invocandone un metodo pubblico.</p>

<p>L’accesso a tale metodo dovrà garantire la mutua esclusione (un solo PROCESSO alla volta
potrà invocare il suddetto metodo. La mutua esclusione dovrà essere ottenuta utilizzando le
primitive di sincronizzazione messe a disposizione dal linguaggio di programmazione eccezion
fatta per il costrutto monitor (per chiarezza, ad esempio, in java non sarà possibile utilizzare
il costrutto <em>synchronized</em>).</p>

<p>Il metodo in questione processerà la richiesta andando ad interrogare l’opportuna tabella
delle pagine. Nel caso in cui, l’indirizzo generato sia relativo ad una pagina già mappata in memoria
la MMU si limiterà ad incrementare un contatore statistico di <em>page hit</em>. D’altra parte, nel caso
in cui l’indirizzo generato dal PROCESSO faccia riferimento ad un indirizzo contenuto in una pagina non
mappata in memoria la MMU dovrà eseguire i seguenti passi:</p>

<ul>
<li>incrementare un contatore di <em>page fault</em></li>
<li>selezionare una pagina mappata da rimuovere (vittima) secondo la politica dell’algoritmo oggetto di test</li>
<li>aggiornare le opportune tabelle delle pagine</li>
<li>indicare come non valida la pagina che è appena stata rimossa</li>
<li>inserire una nuova entry nella tabella delle pagine del PROCESSO che ha generato il <em>page fault</em> (la pagina è stata appena caricata).</li>
</ul>


<h3>PROCESSO</h3>

<p>L’entità PROCESSO dovrà emulare un processo in esecuzione su di un sistema multi programmato.
Ogni processo dovrà essere emulato attraverso l’utilizzo di un singolo thread. Lo scheduling dei
thread sarà delegato alle librerie messe   a disposizione dal linguaggio di programmazione (configurazione
default).</p>

<p>Il comportamento di ogni PROCESSO può essere descritto da una macchina a stati finiti comprendente due
soli stati mutuamente esclusivi:</p>

<ul>
<li>Richiesta indirizzo di memoria (invocazione del metodo pubblico della MMU);</li>
<li>Richiesta operazione di I/O (invocazione del metodo pubblico del DISPOSITIVO di I/O).</li>
</ul>


<p>Le transizioni tra i due stati dovranno essere gestire in maniera probabilistica. In particolare, dovrà
essere definita una probabilità <em>p</em> (input fornito al momento del lancio dell’applicazione) di generare
indirizzi di memoria (“entrare nello stato a dato che ci si trovava nello stato b” = “rimanere nello stato a”)
e una probabilità <strong>q = 1-p</strong> di generare richieste di I/O (“entrare nello stato b dato che ci si trovava
nello stato a” = “rimanere nello stato b”).</p>

<p>I PROCESSI dovranno prevedere la possibilità di essere inizializzati con diversi valori di
probabilità <em>p</em>.</p>

<h3>DISPOSITIVO di I/O</h3>

<p>L’entità DISPOSITIVO di I/O dovrà essere gestita come un ulteriore thread. Questa avrà un metodo
pubblico attraverso il quale i PROCESSI potranno effettuare una richiesta di I/O.</p>

<p>Le richieste di I/O dovranno essere gestite con un coda di tipo <abbr title="First Input First Output">
FIFO</abbr>. Le richieste saranno, ovviamente,
bloccanti, mettendo il PROCESSO chiamante in uno stato di attesa fino al soddisfacimento della richiesta.</p>

<p>Il DISPOSITIVO di I/O determinerà il tempo di servizio di ciascuna richiesta in modo casuale estraendo a
caso un valore intero, espresso in millisecondi, compreso fra <em>Tmin</em> e <em>Tmax</em> (parametri di
inizializzazione del DISPOSITIVO di I/O).</p>

<h3>Dati di INPUT</h3>

<p>Il programma dovrà ricevere in input i seguenti parametri di inizializzazione:</p>

<ul>
<li>Numero di PROCESSI</li>
<li>Probabilità p di generare accessi in memoria (una p per ogni PROCESSO; la probabilità di accedere al dispositivo di I/O sarà pari a 1-p);</li>
<li>Tempi di servizio minimi e massimi del DISPOSITIVO di I/O (<em>Tmin</em> e <em>Tmax</em>);</li>
<li>Numero totale di accessi in memoria raggiunto il quale il programma dovrà terminare.</li>
</ul>


<h3>Dati di OUTPUT</h3>

<p>Al termine della simulazione il programma dovrà stampare a video la percentuale di <em>page fault</em>
totale (relativa a tutti i processi), la percentuale di <em>page fault</em> relativa a ciascun PROCESSO,
il tempo medio di servizio del DISPOSITIVO di I/O ed il tempo medio di attesa per una richiesta di I/O
relativo a ciascun PROCESSO.</p>

<p>Ciascun PROCESSO dovrà scrivere in un proprio file di log la successione di indirizzi generata e le
chiamate al dispositivo di I/O.</p>

<h2>Analisi del problema</h2>

<p>Il problema richiede di realizzare un simulatore elementare di memoria virtuale, utile all’analisi del
comportamento e relative prestazioni di un algoritmo di rimpiazzo delle pagine. Il sistema realizzato
simulerà un ambiente di lavoro multi programmato, nel quale operano più processi contemporaneamente.</p>

<p>Un’analisi iniziale ci suggerisce che questo problema sia di tipo <strong>decidibile</strong>, ovvero
presuppone l’esistenza di un algoritmo che lo risolva in tempo finito e per una qualunque istanza di dati,
espressa in termini di numero di processi contemporanei, dimensione della pagina e così via.</p>

<p>Come da specifica, il simulatore non avrà bisogno di alcun dato di ingresso per funzionare. Un insieme esteso
di parametri da riga di comando permetterà di alterare alcuni aspetti e funzionalità del simulatore.</p>

<p>L’output del programma sarà costituito da alcuni dati statistici, prodotti a seguito del numero prestabilito
di accessi alla memoria.</p>

<h2>Progettazione dell&#8217;algoritmo</h2>

<p>La scelta della struttura dati e del relativo algoritmo tiene conto dei parametri dettati dalla specifica
del problema: l’attenzione sarà dunque focalizzata sulla politica di rimpiazzo delle pagine, sulle strutture
dati necessarie ed sullo scenario che tali scelte determinano; l’analisi non terrà quindi in considerazione
l’impatto che il <em>paging</em> nella memoria secondaria possa avere sull’efficienza complessiva del sistema,
né dei tempi d’accesso alla memoria o di caricamento di una pagina.</p>

<p>Si è scelto di articolare il programma in tre fasi distinte:</p>

<ol>
<li>analisi dei parametri forniti su riga di comando: di particolare rilievo, la possibilità di modificare alcuni parametri di funzionamento del simulatore;</li>
<li>inizializzazione delle strutture dati e successiva esecuzione dei singoli thread;</li>
<li>attesa del completamento dei thread, relativa deallocazione delle strutture dati e successiva stampa delle statistiche.</li>
</ol>


<h3>Descrizione del simulatore</h3>

<p>Un sistema dotato del meccanismo di memoria virtuale consente ad un processo di allocare una quantità di
memoria superiore a quella effettivamente disponibile. La tecnica si basa sull’utilizzo di altri tipi di memoria,
detta <em>secondaria</em>, che entrano in gioco quando la memoria fisica risulta piena. Il meccanismo di memoria
virtuale implementato per il simulatore è quello della <strong>paginazione</strong>.</p>

<p>La paginazione prevede la suddivisione della memoria fisica in <em>frame</em>, tutti della stessa dimensione;
analogamente, anche la memoria allocata da un processo viene diviso in <em>pagine</em>, la cui dimensione è pari
a quella di un frame di memoria fisica: tale suddivisione avviene ad opera della mmu, in modo totalmente trasparente
al processo utente.</p>

<p>Al pari di un sistema operativo, il simulatore terrà aggiornata una tabella dei processi attivi: ogni voce nella
tabella è rappresentativa di un processo e delle pagine virtuali allocate.</p>

<p>Per semplicità, si suppone che la tabella dei processi e la relativa page table siano sempre residenti in memoria,
ovvero che queste non vengano mai paginate a loro volta.</p>

<p>Perché un processo possa accedere ad un’informazione contenuta in una determinata pagina virtuale, è necessario
che quest’ultima sia presente nella memoria fisica ovvero, nello specifico, che sia associata ad un frame. Quando
la lista dei frame disponibili non è esaurita, sarà sufficiente associare la pagina richiesta ad un frame disponibile;
nel caso contrario, si dovrà applicare una politica di rimpiazzo delle pagine, volta a selezionare una pagina tra
quelle presenti in memoria, spostarla nella memoria secondaria e associare il frame appena liberato alla pagina richiesta.</p>

<p>L’algoritmo di rimpiazzo delle pagine scelto è l’<strong>enhanced second chance</strong>,
noto anche come <em>algoritmo dell’orologio</em>: tale soluzione nasce come una naturale evoluzione della tecnica
<abbr title="First Input First Output">FIFO</abbr>, superando il problema di rimuovere le pagine usate più di frequente.</p>

<p>La realizzazione di tale algoritmo impone che ogni pagina contenuta nella <em>page table</em> del processo, oltre
le comuni informazioni, debba contenere due ulteriori bit:</p>

<ul>
<li>bit <em>reference</em> ( R): verrà posto al valore uno (1) quando si accederà alla pagina in questione, sia in scrittura che lettura: tale informazione permetterà di sapere se ad una pagina presente in memoria si sia acceduto di recente o meno;</li>
<li>bit <em>dirty</em> (D): verrà posto ad uno (1) quando si accederà alla pagina  in scrittura: quando una pagina dovrà essere rimossa dalla memoria, il valore uno di questo bit suggerirà al sistema operativo di fare una copia della pagina nella memoria secondaria, prima della rimozione dalla memoria principale.</li>
</ul>


<p>La ricerca della pagina virtuale da rimuovere dovrà tenere conto delle quattro possibili combinazioni ottenute
con questi due bit:</p>

<table class="table table-bordered table-condensed table-striped">
    <thead>
        <tr>
            <th>r</th>
            <th>d</th>
            <th>descrizione</th>
            <th>azione</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>0</td>
            <td>0</td>
            <td>*la pagina non è stata usata di recente e non è stata modificata*</td>
            <td>*rimpiazza la pagina*</td>
        </tr>
        <tr>
            <td>0</td>
            <td>1</td>
            <td>*la pagina non è stata usata di recente ma è stata modificata*</td>
            <td>*effettua un **write **back della pagina e imposta ad zero il bit D*</td>
        </tr>
        <tr>
            <td>1</td>
            <td>0</td>
            <td>*la pagina è stata usata di recente ma non è stata modificata*</td>
            <td>*imposta a zero il bit R*</td>
        </tr>
        <tr>
            <td>1</td>
            <td>1</td>
            <td>*la pagina è stata usata di recente ed è stata modificata*</td>
            <td>*imposta a zero il bit R ed effettua il write back della pagina*</td>
        </tr>
    </tbody>
</table>


<p>La ricerca della pagina migliore non solo si traduce nella selezione della pagina non usata di
recente, ma anche di quella che non sia stata modificata. In questo modo, le pagine utilizzate più
di frequente hanno alta probabilità di rimanere nella memoria principale, a discapito delle pagine
a cui si è acceduto meno frequentemente.</p>

<p>Quando una pagina presente in memoria risulta <em>sporca</em>, si dovranno quindi effettuare due
operazioni di I/O: il primo accesso alla memoria secondaria sarà necessario per effettuare il <em>page
out</em>, ovvero copiare la pagina <em>sporca</em> sul disco, mentre una seconda operazione di lettura
sarà necessaria per il <em>page in</em> della pagina che ha generato il <em>fault</em>. In questo scenario,
l’algoritmo scelto, analizzando periodicamente le pagine che risultano <em>sporche</em> e provvedendo ad
un preventivo <em>write back</em> nella memoria secondaria, migliora sensibilmente le prestazioni complessive,
nonché il tempo medio d’accesso alla memoria.</p>

<p>Tale algoritmo, tuttavia, ha lo svantaggio di partizionare l’insieme delle pagine in due classi:
quelle usate di recente e quelle usate con minor frequenza; quando termina la ricerca per il rimpiazzo,
non è detto che la pagina identificata sia la più vecchia in assoluto, ma semplicemente una delle pagine
meno utilizzate di recente.</p>

<p>Il caso migliore si verifica quando il primo frame analizzato ha i bit R e D posti a zero:
la ricerca termina immediatamente e non sarà nemmeno necessaria un’operazione di I/O volta a
fare una copia della pagina nella memoria secondaria.</p>

<p><em>Come da requisito, i processi effettuano soltanto l’operazione di lettura della memoria: è tuttavia
possibile alterare questo comportamento specificando il parametro “–w” da riga di comando, per ottenere
una simulazione che prevede l’uso del bit dirty.</em></p>

<p>Il caso peggiore dell’<em>enhanced second chance</em> si verifica quando tutte le pagine residenti in
memoria sono sia referenziate che modificate: in questo caso, l’MMU dovrà necessariamente scorrere interamente
la lista delle pagine presenti, ottenendo la medesima complessità dell’algoritmo <abbr title="First Input
First Output">FIFO</abbr>.</p>

<p>Da tali considerazioni, è facilmente comprensibile che la complessità dell’algoritmo sia <em>O(n)</em>,
ovvero lineare e proporzionale al numero di frame in cui è stata suddivisa la memoria.</p>

<p>Non meno importante è sottolineare che, essendo un’evoluzione della tecnica <abbr title="First Input First Output">
FIFO</abbr>, tale approccio soffre
dell’anomalia di Belady (si veda a tal proposito il test 7).</p>

<p>Nei sistemi moderni, alcune funzionalità utili all’implementazione di tale algoritmo vengono implementate
direttamente dall’hardware, quale, ad esempio, l’impostazione ad uno del bit <em>reference</em> e <em>dirty</em>
ogni qualvolta una pagina venga referenziata o modificata.</p>

<p>Un algoritmo di rimpiazzo può essere di tipo <em>locale</em> o <em>globale</em>: il simulatore proposto
effettua una ricerca <strong>globale</strong>, ovvero quando avviene un <em>page fault</em>, l’MMU cercherà la
pagina candidata alla rimozione dalla memoria tra le pagine di tutti i processi attivi e non limitandosi alle
pagine allocate del processo corrente. Sebbene una ricerca locale prevenga influenze da parte degli altri processi
in termini di <em>page fault</em>, un algoritmo globale risulta complessivamente più efficiente nonché più semplice
da implementare.</p>

<p>La modalità di generazione degli indirizzi, ad opera dei processi utente, è in linea con il <strong>principio
di località</strong>, secondo cui se la CPU sta accedendo ad uno specifico dato (o istruzione), con molta probabilità
i prossimi dati (o istruzioni) saranno ubicati nelle vicinanze di quella in corso: valutare tale principio ed i suoi
impatti è di fondamentale importanza per il funzionamento e le prestazioni della memoria virtuale gerarchica dei
moderni sistemi.</p>

<p>È stato, in ultimo, scelto un approccio di tipo <strong>pure demand paging</strong>, il quale
prevede di non assegnare alcun frame al processo fintanto che la pagina non venga referenziata.</p>

<p>I vantaggi di tale tecnica sono immediatamente percepibili:</p>

<ul>
<li>le pagine inutilizzate non vengono mai caricate in memoria, aumentando la quantità di memoria disponibile ad altri processi;</li>
<li>all’avvio di un programma, viene ridotta la latenza necessaria a caricare le pagine in memoria;</li>
<li>minor carico di I/O dovuto ad un minor numero di pagine da caricare.</li>
</ul>


<p>In presenza di un sistema con poca memoria fisica disponibile, il <em>demand paging</em> assicura un grado
più elevato di concorrenza di processi.</p>

<blockquote><p>Per semplicità, si è assunto che le pagine contenenti le istruzioni del processo siano sempre
residenti in memoria: soltanto le pagine contenenti dati verranno gestite dalla MMU e dalla
suddetta politica di rimpiazzo.</p></blockquote>

<p>Il sistema emulato farà uso di indirizzi a 20 bit: da un punto di vista fisico, un simile spazio
di indirizzamento consente di gestire una memoria fisica composta, al massimo, da 1,048,576 byte: il
simulatore sarà appunto dotato di questo quantitativo, sebbene sia possibile alterare tale aspetto
con l’opportuno parametro da riga di comando (-R).</p>

<p>Anche i processi utente utilizzano un indirizzamento a 20 bit; lo spazio d’indirizzamento virtuale
sarà ovviamente superiore a quello fisico in quanto si dovrà considerare anche la memoria secondaria.
Sono dunque possibili due scenari che, in assenza del meccanismo di memoria virtuale, non potrebbero
sussistere:</p>

<ul>
<li>più processi contemporanei, ognuno dei quali alloca il massimo della memoria fisica: la somma
      di tutti gli spazi d’indirizzamento risulta maggiore della memoria fisica;</li></li>
<li>un sistema dotato di una quantità ridotta di memoria fisica ma che consente ugualmente ad un
      processo di allocare 1Mb di memoria virtuale.</li></li>
</ul>


<p>Un indirizzo virtuale a 20 bit generato da un processo sarà suddiviso, in modo del tutto trasparente,
in due parti distinte: i otto bit più significativi (da 19° al 12°) verranno usati come indice per
consultare la <em>page table</em> del processo, mentre i restanti dodici bit rappresenteranno l’offset
da sommare all’indirizzo di partenza del frame associato.</p>

<p><img class="center" src="http://www.devzero.it/assets/images/posts/address.png"></p>

<p>Una simile suddivisione consente ad ogni processo di allocare un massimo di 256 pagine virtuali
(2<sup>8</sup>), la cui dimensione è pari a 4,096 byte (2<sup>12</sup>): ovviamente il numero di
pagine virtuali disponibili per un processo è indipendente dal numero di frame disponibili. Qualora
il rapporto tra i frame disponibili ed il numero massimo di processi concorrenti risulti vantaggioso,
il programma attiverà automaticamente la <strong>paginazione anticipata</strong>: l’MMU, infatti,
non si limiterà a caricare in memoria la pagina mancante, causa del <em>fault</em>, ma anche un
ristretto numero di pagine adiacenti. In pratica il simulatore cerca di prevedere quali pagine
saranno richieste in virtù della località dei dati e le carica prima di quando queste vengano
effettivamente richieste.</p>

<blockquote><p>La suddetta funzionalità è da considerarsi puramente dimostrativa ed embrionale.</p></blockquote>

<p>Di seguito vengono riassunte le scelte progettuali che caratterizzano il simulatore.</p>

<table>
<thead>
<tr>
<th>Ambito   </th>
<th align="left"> Proprietà  </th>
<th align="right"> Valore   </th>
</tr>
</thead>
<tbody>
<tr>
<td>Hardware </td>
<td align="left"> Dimensione indirizzo </td>
<td align="right"> <em>20 bit</em></td>
</tr>
<tr>
<td></td>
<td align="left"> Dimensione RAM       </td>
<td align="right"> <em>1,048,576 byte</em></td>
</tr>
<tr>
<td></td>
<td align="left"> Dimensione frame     </td>
<td align="right"> <em>4,096</em></td>
</tr>
<tr>
<td>Memoria virtuale </td>
<td align="left"> Tipo </td>
<td align="right"> <em>paginata</em></td>
</tr>
<tr>
<td></td>
<td align="left"> Politica di rimpiazzo </td>
<td align="right"> <em>enhanced second chance</em></td>
</tr>
<tr>
<td></td>
<td align="left"> Dimensione pagina </td>
<td align="right"> <em>4,096</em></td>
</tr>
<tr>
<td></td>
<td align="left"> Page table </td>
<td align="right"> <em>sempre in memoria</em></td>
</tr>
<tr>
<td></td>
<td align="left"> Max pagine/processo </td>
<td align="right"> <em>256</em></td>
</tr>
<tr>
<td>Dispositivo I/O </td>
<td align="left"> Tmin </td>
<td align="right"> <em>1</em></td>
</tr>
<tr>
<td></td>
<td align="left"> Tmax </td>
<td align="right"> <em>100</em></td>
</tr>
<tr>
<td>Processo </td>
<td align="left"> Probabilità accesso </td>
<td align="right"> <em>80%</em></td>
</tr>
<tr>
<td></td>
<td align="left"> Località temporale </td>
<td align="right"> <em>30%</em></td>
</tr>
<tr>
<td></td>
<td align="left"> Località spaziale </td>
<td align="right"> <em>Loop su un vettore</em></td>
</tr>
</tbody>
</table>


<h2>Descrizione moduli</h2>

<p>Di seguito verranno descritti,  con maggiore dettaglio, gli aspetti implementativi dei
singoli moduli: l’MMU, il dispositivo di I/O ed il processo.</p>

<p><img class="center" src="http://www.devzero.it/assets/images/posts/modules.png"></p>

<p>Ogni singolo modulo del simulatore viene inizializzato direttamente dal <em>main()</em> attraverso
le rispettive funzioni e sulla base dei parametri specificati da riga di comando. Terminata questa fase,
inizierà l’interazione tra i singoli thread.</p>

<h3>Memory Management Unit (MMU)</h3>

<p>Il thread che emula l’MMU è il primo ad essere istanziato dal simulatore, direttamente all’interno
del <em>main</em>: questo si occupa della traduzione di un indirizzo virtuale, generato da un processo,
in un equivalente indirizzo fisico di memoria.</p>

<p>La funzione mmu_init è incaricata di configurare l’ambiente del simulatore nonché di partizionare la
memoria fisica in frame. Ad ogni frame verranno associate le seguenti informazioni:</p>

<ul>
<li><strong>id</strong>: tale valore identifica univocamente un frame;</li>
<li><strong>physical_addr</strong>: questa variabile conterrà l’indirizzo di memoria fisica di partenza del frame; durante il ciclo di vita del simulatore, la lista dei frame non sarà ordinata per <em>id</em>: questo è il valore di base cui sommare l’offset dell’indirizzo virtuale;</li>
<li><strong>valid</strong>: il bit verrà posto ad uno (1) quando il frame è utilizzato;</li>
</ul>


<p>Ad ogni frame vengono inoltre associate due ulteriori campi, <em>pid</em> e <em>page_id</em>: sebbene
non siano necessari al funzionamento del simulatore, hanno il solo scopo di rendere più semplice il <em>debug</em>,
nonché offrono la possibilità di mantenere un’associazione frame &ndash;&gt; processo &ndash;&gt; pagina.</p>

<p><img class="center" src="http://www.devzero.it/assets/images/posts/frames.png" title="frames" ></p>

<p>L’MMU fa uso di due liste semplici: la prima, free_frames, per tenere traccia dei frame liberi (ovvero
non associati ad alcuna pagina) ed used_frames per i frame utilizzati. Terminata l’inizializzazione della
memoria, tutti i frame saranno presenti nella lista free_frames, condizione dettata dal <em>demand paging</em>.
Un’ulteriore lista, active_pages, conterrà solo le pagine presenti in memoria.</p>

<p>La funzione thread_mmu viene eseguita come thread e simula l’MMU: l’interazione tra questo thread ed i
processi è resa possibile dalla funzione memory_read, invocata direttamente dai processi che tentano un
accesso alla memoria. Quest’ultima si occuperà di inserire in una struttura temporanea i dati relativi al
processo chiamante, nonché l’indirizzo virtuale richiesto e segnalerà alla MMU la presenza di una richiesta;
l’MMU, nel vagliare la richiesta, sceglierà quale frame associare alla pagina equivalente ed, al termine,
restituirà l’indirizzo di memoria fisico.</p>

<p>Di seguito verrà illustrato lo schema a blocchi del funzionamento della MMU.</p>

<p><img class="center" src="http://www.devzero.it/assets/images/posts/mmu.png" title="MMU" ></p>

<p>L’algoritmo <em>enhanced second chance</em> viene applicato solo quando la pagina richiesta non è
presente in memoria ed, al contempo, tutti i frame risultano occupati. Ha quindi inizio una ricerca
della pagina candidata alla rimozione: i due bit precedentemente descritti, <em>reference</em> e
<em>dirty</em>, tengono traccia dell’uso e della modifica delle pagine.</p>

<blockquote><p>L’algoritmo prevede che l’elenco delle pagine utilizzate sia rappresentato da una lista circolare,
mentre è stata usata una lista doppiamente concatenata che, nel caso peggiore, viene visitata per intero.</p></blockquote>

<h3>Processo</h3>

<p>La funzione thread_proc, eseguita come thread, si occupa di simulare un processo utente.</p>

<p>La rappresentazione in memoria del singolo processo, nonché delle caratteristiche che lo contraddistinguono,
è affidata alla struttura proc. Avendo come riferimento un sistema operativo reale, al proprio interno, il simulatore
gestisce una lista di tutti i processi attivi, detta <em>process table</em>: ogni voce in questa tabella è di tipo
proc e contiene le seguenti informazioni:</p>

<ul>
<li><strong>pid</strong>: identificativo univoco del processo;</li>
<li><strong>tid</strong>: identificativo univoco del thread che simula il processo;</li>
<li><strong>page_count</strong>: numero di pagine virtuali allocate dal processo;</li>
<li><strong>page_table</strong>: tabella delle pagine del processo; questa informazione non deve essere accessibile al processo;</li>
<li><strong>percentile</strong>: probabilità del processo di effettuare un accesso alla memoria piuttosto che al dispositivo di I/O;</li>
<li><strong>io_cond/io_lock</strong>: condizione e relativo mutex nel quale il thread resta in attesa di completamento di una richiesta di I/O;</li>
<li><strong>log_file</strong>: file di log del processo;</li>
<li><strong>proc_stats</strong>: struttura per contenere le statistiche d’accesso del processo.</li>
</ul>


<p>Nei sistemi reali, un processo ha visibilità solo di alcune informazioni contenute nella <em>process
table</em> o relative al sistema ospite: per esempio, un processo potrà sapere qual è il proprio pid o
la dimensione della memoria virtuale, ma non potrà tuttavia accedere alla lista delle pagine o dei frame,
informazioni ad unico appannaggio del sistema operativo. Seguendo le implementazioni dei più comuni sistemi
<em>nix si è dunque scelto di non far gestire alla mmu la tabella delle pagine virtuali del processo, garantendo
opportunamente la protezione dello spazio d’indirizzamento: l’mmu farà piuttosto uso di una propria struttura
dati per gestire l’associazione delle pagine ai frame. Questa scelta trova ulteriore giustificazione nel fatto
che ogni processo può allocare una quantità variabile di memoria e l’mmu, che viene inizializzata prima della
</em>process table*, non può conoscere a priori tale quantità.</p>

<p>Poiché il simulatore non è stato implementato con un linguaggio orientato ad oggetti quale Java o C++,
le API di accesso alla memoria ed al dispositivo di I/O devono contenere necessariamente l’identificativo del
richiedente, nello specifico il pid.</p>

<p>La funzione proc_init ha il compito di creare <em>n</em> istanze del thread processo, per ognuno dei quali
associa un numero casuale di pagine virtuali.</p>

<blockquote><p>Il numero casuale di pagine virtuali è compreso tra 1 e 256, in modo tale che tutti i processi
abbiano almeno una pagina associata e comunque non superiore al limite massimo di 256. È tuttavia
possibile massimizzare tale valore per tutti i processi usando il parametro –M.</p></blockquote>

<p>La funzione thread_proc, si occupa di scegliere se effettuare un accesso alla memoria o al dispositivo di
I/O, scegliendo tra le due operazioni con una probabilità impostata dall’utente: quando la funzione memory_access,
utilizzata per accedere alla memoria, restituirà il valore -1, i processi termineranno la propria esecuzione.</p>

<p>L’accesso in memoria osserva il principio di località, secondo cui:</p>

<ul>
<li>se accedo ad un dato, probabilmente accederò anche a quelli vicini in un tempo non lontano (<strong>località spaziale</strong>);</li>
<li>se accedo ad un dato è probabile che debba accedervi nuovamente in breve tempo (<strong>località temporale</strong>).</li>
</ul>


<p><img class="center" src="http://www.devzero.it/assets/images/posts/locality.png" title="Locality" ></p>

<p>La realizzazione della località spaziale viene offerta dalla funzione simulate_loop che si occupa di
simulare un accesso ad un vettore di <em>n</em> elementi: poiché in C gli elementi di un vettore occupano
indirizzi di memoria contigui, simulare un accesso ad ognuno di essi coincide ad una località spaziale.</p>

<p>Quando il processo effettua invece un accesso pseudo casuale alla memoria, subentra la località temporale,
ovvero la possibilità di accedere ad un dato recentemente utilizzato. In quest’ottica, il processo avrà il 30%
di probabilità di accedere ad un indirizzo di memoria usato in precedenza.</p>

<p><em>Il parametro “–L” permette di variare la percentuale di località temporale, di default pari a 30%; ponendo
uguale a zero tale valore, si elimina l’effetto di località.</em></p>

<p>L’operazione di lettura merita ulteriori considerazioni:</p>

<ol>
<li>nel caso di accesso alla memoria, l’indirizzo virtuale è generato casualmente, ma è sempre
 compreso nello spazio d’indirizzamento virtuale del processo: qualora l’indirizzo fuoriuscisse
 da tale spazio, il simulatore avrebbe il compito di generare un fault e terminare il processo;</li>
<li>per una migliore simulazione dell’algoritmo scelto, che prevede l’uso del bit <em>dirty</em>,
 è stata implementata l’operazione di scrittura in una zona di memoria: la funzione che realizza
 tale operazione è sempre memory_access ma con il parametro <em>rw</em> posto ad uno; non sarà
 tuttavia presente un parametro utile a rappresentare l’informazione da scrivere in memoria, in
 quanto esula lo scopo della presente analisi;</li>
<li>per entrambe le tipologie di accesso, alla memoria od al dispositivo di I/O, il processo non
 ha visibilità diretta dei rispettivi thread: la possibilità di effettuare una richiesta viene
 offerta dall’uso di due funzioni pubbliche che svolgono il ruolo di intermediario.</li>
</ol>


<p>Sussiste una sottile differenza tra i due tipi di accesso che un processo utente può effettuare:
l’MMU rappresenta un oggetto condiviso tra più processi e può assolvere una richiesta per volta;
se <em>n </em>processi tentassero l’accesso alla memoria, soltanto uno riuscirà nell’intento mentre
gli altri “<em>n-1”</em> processi restano in attesa (mutua esclusione).</p>

<p>Di contro, l’accesso al dispositivo di I/O prevede che effettuare una richiesta d’accesso non sia
bloccante, per cui se <em>n</em> processi tentassero l’accesso al dispositivo, tutti quanti riuscirebbero
ad inserire la propria richiesta in coda: l’attesa avviene immediatamente dopo, non bloccando quindi gli
altri attori della contesa, ma solo il processo che attende il risultato.</p>

<p>Di seguito viene illustrato il diagramma a blocchi del funzionamento del thread processo.</p>

<p><img class="center" src="http://www.devzero.it/assets/images/posts/thread-580x423.png" title="Thread" ></p>

<p>La prima condizione, <em>uscita</em>, viene soddisfatta quando la MMU ha effettuato il numero richiesto
di accessi.</p>

<h2>Dispositivo di I/O</h2>

<p>Il dispositivo di I/O viene emulato dalla funzione thread_io_device, anch’essa eseguita come thread.
Questo viene inizializzato ed istanziato immediatamente dopo aver creato il sottostrato di memoria virtuale.</p>

<p>Il funzionamento del dispositivo di I/O, a differenza della MMU, si basa su una lista di tipo
<abbr title="First Input First Output">FIFO</abbr>:
i processi che effettuano una richiesta a tale dispositivo vengono inseriti in coda e serviti in modo
sequenziale. La richiesta è di tipo bloccante: un processo, in attesa che la richiesta venga soddisfatta,
non può effettuare altre operazioni.</p>

<p>La funzione io_device_read rappresenta il metodo pubblico per inserire una richiesta in coda,
al pari di memory_access per le lettura in memoria.</p>

<p>La coda di richieste di I/O costituisce una risorsa condivisa tra il thread (<em>lettore</em>)
e la funzione io_device_read (<em>scrittore</em>) ed, in tal senso, l’accesso alla <abbr
title="First Input First Output">FIFO</abbr> va gestito
all’interno di una sezione critica: il mutex fifo_lock viene utilizzato dalle due entità al fine di
mantenere coerente lo stato delle richieste.</p>

<p>Il thread terminerà la propria esecuzione su richiesta dell’MMU, quando questa avrà espletato il
numero di richieste previsto.</p>

<p>Di seguito viene illustrato il diagramma a blocchi del dispositivo.</p>

<p><img class="center" src="http://www.devzero.it/assets/images/posts/thread_io.png" title="Thread" ></p>

<p>Come da specifica, il dispositivo viene configurato con due parametri, <em>Tmin</em> e <em>Tmax</em>,
rispettivamente il tempo minimo e massimo perché una richiesta di lettura venga effettuata; il thread,
una volta esaminata la richiesta, si occuperà di generare un numero casuale compreso in tale intervallo
ed infine segnalerà al processo l’avvenuta operazione: il processo sarà nuovamente libero di effettuare
altre operazioni con le modalità precedentemente descritte.</p>

<h3>Prima fase: analisi dei parametri</h3>

<p>Il programma inizierà la propria esecuzione analizzando i parametri specificati su riga di comando;
sebbene questi non siano necessari per il funzionamento del simulatore, è disponibile un insieme di
parametri per modificare alcuni comportamenti predefiniti dell’applicativo.</p>

<p>Di seguito vengono riassunti i possibili parametri:</p>

<table class="table table-condensend table-bordered table-striped">
<thead>
    <tr><th>Breve</th><th>Lungo</th><th>Descrizione</th></tr>
</thead>
<tbody>
    <tr>
        <td>-v</td>
        <td>&#8211;version</td>
        <td>Stampa la versione del programma ed esce</td>
    </tr>
    <tr>
        <td>-d</td>
        <td>&#8211;debug</td>
        <td>Aumenta il livello di debug dell’output (disattivato per default)</td>
    </tr>
    <tr>
        <td>-a</td>
        <td>&#8211;anticipatory-paging</td>
        <td>Disabilita la paginazione anticipata</td>
    </tr>
    <tr>
        <td>-h</td>
        <td>&#8211;help</td>
        <td>Stampa la sinossi del programma ed esce</td>
    </tr>
    <tr>        
        <td>-l *lista*</td>
        <td>&#8211;probabilities=*lista*</td>
        <td>Specifica la probabilità d’accesso alla memoria per i processi</td>
    </tr>
    <tr>        
        <td>-L *num*</td>
        <td>&#8211;locality=*num*</td>
        <td>Specifica la località temporale (default: *30%*)</td>
    </tr>
    <tr>        
        <td>-M</td>
        <td>&#8211;all-memory</td>
        <td>Forza i processi ad allocare il massimo della memoria (default: *no*)</td>
    </tr>
    <tr>        
        <td>-m *num*</td>
        <td>&#8211;max-read=*num*</td>
        <td>Imposta il numero massimo di accessi alla memoria (default: *50*)</td>
    </tr>
    <tr>        
        <td>-p *num*</td>
        <td>&#8211;max-processes=*num*</td>
        <td>Imposta il numero massimo di processi concorrenti (default *5*)</td>
    </tr>
    <tr>        
        <td>-P *num*</td>
        <td>&#8211;probability=*num*</td>
        <td>Imposta la probabilità con cui un processo effettua un accesso alla memoria (default: *80%*)</td>
    </tr>
    <tr>        
        <td>-r *lista*</td>
        <td>&#8211;reference=*lista*</td>
        <td>Imposta la *reference string* per determinare gli accessi</td>
    </tr>
    <tr>        
        <td>-R *num*</td>
        <td>&#8211;ram-size=*num*</td>
        <td>Imposta la dimensione della RAM disponibile (default: *1,048,576*)</td>
    </tr>
    <tr>        
        <td>-s *num*</td>
        <td>&#8211;frame-size=*num*</td>
        <td>Imposta la dimensione della pagina e del frame (default: *4,096*)</td>
    </tr>
    <tr>        
        <td>-t *num*</td>
        <td>&#8211;Tmin=*num*</td>
        <td>Imposta il parametro Tmin del dispositivo di I/O (default: *1*)</td>
    </tr>
    <tr>        
        <td>-T *num*</td>
        <td>&#8211;Tmax=*num*</td>
        <td>Imposta il parametro Tmax del dispositivo di I/O (default: *100*)</td>
    </tr>
    <tr>        
        <td>-w</td>
        <td>&#8211;write-enabled</td>
        <td>Consente ai programmi di accedere alla memoria anche in scrittura (default: *no*)</td>
    </tr>
</tbody>
</table>


<h3>Seconda fase: inizializzazione ed esecuzione thread</h3>

<p>La corretta analisi dei parametri specificati su riga di comando permette di passare alla
inizializzazione delle singole strutture dati ed all’esecuzione dei thread finora descritti.</p>

<p>La prima entità istanziata è appunto l’MMU, seguita successivamente dalla creazione del thread per
il dispositivo di I/O ed in ultimo dai thread che simulano i processi utente.</p>

<h3>Terza fase: stampa dei risultati</h3>

<p>La terza fase ha inizio quando i processi utente hanno effettuato il  numero massimo di accessi
alla memoria: questa condizione determina la fine di tutti i thread istanziati, siano essi utente,
MMU o del dispositivo di I/O.</p>

<p>Una corretta conclusione prevede quindi di effettuare una pthread_join di tutti quanti i thread e
la relativa deallocazione delle strutture dati fino a quel momento utilizzate.</p>

<p>Al termine di questa operazione, il simulatore si dovrà preoccupare di stampare a video le statistiche
richieste. Oltre le suddette statistiche, saranno inoltre disponibili, nella directory di lavoro, i file di
log di ogni singolo processo, all’interno dei quali si potrà trovare la lista delle operazioni effettuate
dai processi utente.</p>

<p>Scarica l&#8217;intero progetto <a href="http://www.devzero.it/attachments/OSYS_F.Vitale.zip">qui</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Software Engineer]]></title>
    <link href="http://www.devzero.it/blog/2010/11/28/software-engineer/"/>
    <updated>2010-11-28T00:00:00+01:00</updated>
    <id>http://www.devzero.it/blog/2010/11/28/software-engineer</id>
    <content type="html"><![CDATA[<p>Another post about a project developed for Urbino University: consider it as didactic purpose only.</p>

<h2>Problem specifications</h2>

<p>The aim of this project is to realize an e-commerce tool, along with its database, for the final
client who wishes to buy some product.</p>

<p>The first need is classifying technology products, such as computers, monitors, accessories and
so on. To make products browsing easier, it is advisable to split items into categories, so that
customers will be able to find what they’re looking for faster and easier; for each product it is
known the id, the name and its description, as far as its price together with its availability.</p>

<!-- more -->


<p>Whenever a potential customer chooses an item from catalogue, the system should suggest a list
of configurations containing the selected product: for example, if a laptop is chosen, the system
will propose to buy some kind of mice or PCCARD which belong to the same configuration.</p>

<p>Only registered users are allowed to browse and buy items: for each user, it’s known the id,
name and surname, together with his credential to access the system and a shipping address. A
user must choose a unique login to be correctly registered.</p>

<p>A discount to total amount of customer order should be considered: total amount of an order
could be different from the sum of each item.
The system should allow the system administrator to delete an item from the catalogue: this
operation must be permitted only under the condition that the selected item is not part of any
previous orders, otherwise there must exist another way to hide the product from catalogue
browsing and leave old orders consistent.</p>

<p>As the user runs the tool, he can register himself as a new user or log into the system by
specifying his own credential.
The interface must implement the following operations to read data:</p>

<ul>
<li>Browsing product catalog by category;</li>
<li>Viewing details of the chosen product;</li>
<li>Browsing all the configurations which include a given item;</li>
<li>Browsing user’s profile and all the orders he made;</li>
<li>Placing a new order.</li>
</ul>


<p>The system should let the administrator issue the following operations, which may also alter data:</p>

<ul>
<li>Adding a new category;</li>
<li>Adding a new product;</li>
<li>Browsing proceeds of sales, grouped by month;</li>
<li>Preventing a user from log in (lock);</li>
<li>Deleting a product (even if it was already sold).</li>
</ul>


<p>Download the project, along with the relation, the sources and database schema
<a href="http://www.devzero.it/attachments/SENG_F.Vitale.zip">here</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[YABI meets MobileMe Calendar Beta]]></title>
    <link href="http://www.devzero.it/blog/2010/10/10/yabi-meets-mobileme-calendar-beta/"/>
    <updated>2010-10-10T00:00:00+02:00</updated>
    <id>http://www.devzero.it/blog/2010/10/10/yabi-meets-mobileme-calendar-beta</id>
    <content type="html"><![CDATA[<p>Apple have recently released the beta version of new MobileMe Calendar: it&rsquo;s cool, of course, but all calendars on your Mac won&rsquo;t be local anymore, as they are replaced by CalDav ones.
Unfortunately the Calendar Framework provided by Cocoa doesn&rsquo;t fully support CalDav: then YABI tries to recreate the calendar, a new local calendar is created instead of a CalDav one.</p>

<p>I&rsquo;ve already wrote the solution to this bug and soon I&rsquo;ll release the new version which
also includes a way to exclude person from sync.</p>

<div class="alert alert-block">
  <h4>Note!</h4>
  <p>I&#8217;m sorry to announce that YABI has been discontinued.</p>
  I&#8217;d like to thank you all for the support and the great opportunity you gave to enjoy Mac world.
</div>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Follow YABI on Facebook]]></title>
    <link href="http://www.devzero.it/blog/2010/09/12/follow-yabi-on-facebook/"/>
    <updated>2010-09-12T00:00:00+02:00</updated>
    <id>http://www.devzero.it/blog/2010/09/12/follow-yabi-on-facebook</id>
    <content type="html"><![CDATA[<p>If you &ldquo;Like&rdquo; YABI, follow it also on Facebook!</p>

<p>Please, visit the following link: <a href="http://www.facebook.com/pages/YABI/128985247144819"><a href="http://www.facebook.com/pages/YABI/">http://www.facebook.com/pages/YABI/</a></a></p>

<br/><br/>


<div class="alert alert-block">
  <h4>Note!</h4>
  <p>I&#8217;m sorry to announce that YABI has been discontinued.</p>
  I&#8217;d like to thank you all for the support and the great opportunity you gave to enjoy Mac world.
</div>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[YABI 1.0.4 released!]]></title>
    <link href="http://www.devzero.it/blog/2010/09/10/yabi-1-0-4-released/"/>
    <updated>2010-09-10T00:00:00+02:00</updated>
    <id>http://www.devzero.it/blog/2010/09/10/yabi-1-0-4-released</id>
    <content type="html"><![CDATA[<blockquote><p>&#8220;This changes everything. Again.&#8221;</p></blockquote>




<p>YABI core functions have been totally reimplemented and, above all, completed.
This version addresses few bugs, which caused YABI Agent crashes (e.g. when an event name is changed in AddressBook).</p>




<p>I&#8217;ve also been asked for new interesting features, I&#8217;ll work on them in spare time:
<ul>
    <li>use remote calendar as target</li>
    <li>excluding birthdays</li>
    <li>enhanced nickname support</li>
</ul></p>




<p><strong>Upgrade note</strong></p>


<p>We suggest to deactivate YABI before upgrading; follow these few steps:
<ul>
<li>Open YABI preference pane</li>
<li>Click on  Deactivate button and quit System Preferences</li>
<li>Upgrade YABI by double-clicking on the new icon</li>
</ul></p>


<p>Download YABI at <a href="http://www.devzero.it/attachments/YABI.dmg">YABI.dmg</a> and check it out!</p>

<br/><br/>


<div class="alert alert-block">
  <h4>Note!</h4>
  <p>I&#8217;m sorry to announce that YABI has been discontinued.</p>
  I&#8217;d like to thank you all for the support and the great opportunity you gave to enjoy Mac world.
</div>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[YABI 1.0.2 released]]></title>
    <link href="http://www.devzero.it/blog/2010/03/20/yabi-1-0-2-released/"/>
    <updated>2010-03-20T00:00:00+01:00</updated>
    <id>http://www.devzero.it/blog/2010/03/20/yabi-1-0-2-released</id>
    <content type="html"><![CDATA[<p>Say hello to YABI 1.0.2 and YABI Viewer.</p>




<p>Here some changes:
    <ul>
        <li>[FIX] Nicknames were not properly imported by from Sync Server and it was impossible to substitute in event title</li>
        <li>[FIX] Target calendar change is now saved</li>
        <li>[FIX] Event title changes are properly saved</li>
        <li>[FIX] Alarm icon column is no more bound to &#8220;data&#8221; binding (&#8220;value&#8221; is now used: no more warning in your console about this deprecated construct)</li>
        <li>[NEW] Agent deactivation removes application data file</li>
        <li>[NEW] Deactivate button is now disabled when a fresh-sync is issued</li>
        <li>[NEW] Added the new specifier &#8220;%yp&#8221; (equal to %y minus 1)</li>
    </ul>
</p>




<p>Here what must still be implemented:
<ul>
    <li>Software autoupdate</li>
</ul>
I&#8217;d like to thank all of you for your bug report and support.</p>




<p>Download YABI at <a href="http://www.devzero.it/attachments/YABI.dmg">YABI.dmg</a> and check it out!</p>




<br/><br/>


<div class="alert alert-block">
  <h4>Note!</h4>
  <p>I&#8217;m sorry to announce that YABI has been discontinued.</p>
  I&#8217;d like to thank you all for the support and the great opportunity you gave to enjoy Mac world.
</div>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[YABI 1.0.1 - minor bug fixes]]></title>
    <link href="http://www.devzero.it/blog/2010/01/01/yabi-1-0-1-minor-bug-fixes/"/>
    <updated>2010-01-01T00:00:00+01:00</updated>
    <id>http://www.devzero.it/blog/2010/01/01/yabi-1-0-1-minor-bug-fixes</id>
    <content type="html"><![CDATA[<p>A new minor release of preference pane version of YABI has been released.</p>




<p>Here some changes:
<ul>
    <li>64-bit enabled</li>
    <li>minor memory leaks fixed</li>
    <li>added &#8220;partner&#8221; attribute for anniversary cross-check</li>
    <li>UI updates</li>
    <li>removed unused frameworks</li>
</ul>
</p>




<p>Here what must still be implemented:
<ul>
    <li>Save/restore event titles</li>
    <li>Software autoupdate</li>
</ul>
</p>


<p>Download YABI at <a href="http://www.devzero.it/attachments/YABI.dmg">YABI.dmg</a> and check it out!</p>

<br/><br/>


<div class="alert alert-block">
  <h4>Note!</h4>
  <p>I&#8217;m sorry to announce that YABI has been discontinued.</p>
  I&#8217;d like to thank you all for the support and the great opportunity you gave to enjoy Mac world.
</div>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Selectable boxes]]></title>
    <link href="http://www.devzero.it/blog/2009/12/15/selectable-boxes/"/>
    <updated>2009-12-15T00:00:00+01:00</updated>
    <id>http://www.devzero.it/blog/2009/12/15/selectable-boxes</id>
    <content type="html"><![CDATA[<p>If you had ever used iSync, probably you&rsquo;ve been asked to resolve a sync conflict
at least one time: the panel shown to the user contains two boxes , mutually excluded
i.e. you can only choose one of them.</p>

<p>DZSelectableBox is a subclass of NSBox view which emulates this behavior. An instance
of this class comes with one more variable member, the box state: when the box is marked
as <em>selected</em>, an inner rounded path is drawn inside its bounds; DZSelectableBox
honors title position, if it&rsquo;s visible. You can use this class in two different manners: 
standalone or as part of a radio group.</p>

<!-- more -->


<h3>Standalone version</h3>

<p><img class="center" src="http://www.devzero.it/assets/images/box-standalone.png"></p>

<p>A standalone box works as described before: the only thing you&rsquo;ve to do is open
Interface Builder, place a common NSBox in your window, change its class name into
DZSelectableBox and start using it.
You can change box state programmatically by using the <code>toggleState</code>
message, the <code>setSelected</code> method to set its state or simply by clicking
on it.</p>

<p><img class="center" src="http://www.devzero.it/assets/images/box-standalone.png"></p>

<h3>Radio group version</h3>

<p><img class="center" src="http://www.devzero.it/assets/images/box-radiogroup.png"></p>

<p>Whenever you need a group of boxes and the opportunity to select only one of them at
time, you&rsquo;ve to set a radio group; after you followed the steps described before to create
your boxes, you&rsquo;ve to add the following sample code to your application:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="n">leftBox</span><span class="p">.</span><span class="n">radioGroup</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSNumber</span> <span class="nl">numberWithInt:</span><span class="mi">1</span><span class="p">];</span>
</span><span class='line'><span class="n">rightBox</span><span class="p">.</span><span class="n">radioGroup</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSNumber</span> <span class="nl">numberWithInt:</span><span class="mi">1</span><span class="p">];</span>
</span><span class='line'><span class="p">[</span><span class="n">leftBox</span> <span class="nl">setSelected:</span><span class="n">YES</span><span class="p">];</span>
</span><span class='line'><span class="p">[</span><span class="n">rightBox</span> <span class="nl">setSelected:</span><span class="n">NO</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<p>(we suppose you created two boxes and connected them to two outlets called leftBox 
and rightBox)</p>

<p>When a box belongs to a radio group, it listens for group changes notification: for
example, if you select the right box (by clicking on it), the left one will be automatically
unselected.</p>

<p>Code is available on <a href="http://github.com/unixo/Selectable-Box">GitHubg</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Wordpress themes and page-links]]></title>
    <link href="http://www.devzero.it/blog/2009/07/06/wordpress-themes-and-page-links/"/>
    <updated>2009-07-06T00:00:00+02:00</updated>
    <id>http://www.devzero.it/blog/2009/07/06/wordpress-themes-and-page-links</id>
    <content type="html"><![CDATA[<p>Wordpress offers a cool feature to split a single post into different web pages, by using <em>&lt;!&mdash;nextpage&mdash;&gt;</em> keyword.
The problem arises when you use a theme different from the default one: that&rsquo;s why many theme writers forget to add the right code to the theme;</p>

<!-- more -->


<p>if you have this problem, follow these steps:</p>

<ol>
    <li>Go to the theme directory (DOC_ROOT/wp-contents/themes/<em>yourtheme</em>)</li>
    <li>Look for file named <em>single.php</em></li>
    <li>Look for the template tag named <em>the_content</em></li>
    <li>Add a new line below and attach the following istructions:</li>
</ol>


<div id="_mcePaste" style="position: absolute; left: -10000px; top: 35px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><code>?php wp_link_pages(array('before' =&gt; '&lt;p&gt;&lt;strong&gt;Pages:&lt;/strong&gt; ',</code></div>


<p><code></p>

<div id="_mcePaste" style="position: absolute; left: -10000px; top: 35px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">'after' =&gt; '&lt;/p&gt;', 'next_or_number' =&gt; 'number')); ?&gt;</div>


<p></code></p>

<p><span style="font-family: monospace, 'Times New Roman', 'Bitstream Charter', Times, fantasy;"><span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; line-height: 18px; font-size: 12px; white-space: pre;">&lt;</span>?php wp_link_pages(array(&lsquo;before&rsquo; =&gt; &lsquo;&lt;p&gt;&lt;strong&gt;Pages:&lt;/strong&gt; &rsquo;,&lsquo;after&rsquo; =&gt; &lsquo;&lt;/p&gt;&rsquo;, &lsquo;next_or_number&rsquo; =&gt; &lsquo;number&rsquo;)); ?&gt;</span></p>

<p>Try to reload the single post page and enjoy page-links.</p>

<p>For further informations about page-links, <a href="http://codex.wordpress.org/Styling_Page-Links">read this document</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Alberi Rosso Neri]]></title>
    <link href="http://www.devzero.it/blog/2009/06/07/red-black-trees/"/>
    <updated>2009-06-07T02:00:00+02:00</updated>
    <id>http://www.devzero.it/blog/2009/06/07/red-black-trees</id>
    <content type="html"><![CDATA[<p>Continua la serie di progetti sviluppati a scopi didattici per l&#8217;Università di Urbino &ldquo;Carlo Bo&rdquo;.<br/></p>

<h1>Specifica del problema</h1>

<p>Sia dato un semplice database che rappresenta un elenco di studenti che hanno sostenuto un esame.</p>

<p>Il database è organizzato sotto forma di file di testo su 3 colonne contenenti informazioni relative a
(Cognome, Matricola, Voto) come ad esempio:</p>

<table class="table table-bordered table-striped table-condensed">
<thead><tr><th>Cognome</th><th>Matricola</th><th>Voto</th></tr></thead>
<tbody>
    <tr><td>Bianchi</td><td>212</td><td>21</td></tr>
    <tr><td>Rossi</td><td>128</td><td>30</td></tr>
    <tr><td>Verdi</td><td>54</td><td>22</td></tr>
</tbody>
</table>


<p>Scrivere un programma ANSI C che acquisisce il database da file, ne effettua un ordinamento in base
alla chiave primaria (Cognome) o alle chiavi secondarie (Matricola, Voto) sulla base della scelta
dell’utente e produce in uscita il database ordinato. L’ordinamento sulle chiavi secondarie deve conservare
l’ordine relativo prodotto dalla chiave primaria.</p>

<!-- more -->


<h1>Analisi del problema</h1>

<p>Il problema richiede di ordinare una tabella mediante l’uso di un algoritmo stabile, ovvero un
procedimento che, in presenza di più chiavi di ordinamento, preservi l’ordine relativo prodotto da
altre chiavi; è facilmente intuibile che il problema posto sia <strong>decidibile</strong>, ovvero che esiste un
algoritmo che lo risolve in tempo finito e per una qualunque istanza di dati.</p>

<p>Come da specifica, il dato di ingresso per il programma è costituito da un file, quale
rappresentazione testuale della tabella del database; il programma impone che il formato del file
sia CSV, ovvero delimitato da un determinato separatore di campo.</p>

<blockquote>
    Per semplicità, si assume che il file sia sintatticamente corretto, ovvero che non esistano 
    righe (record) che non abbiano i tre campi valorizzati correttamente.
</blockquote>


<p>L’output del programma sarà la medesima tabella, opportunamente formattata, ordinata secondo i
criteri che l’utente potrà specificare da riga di comando, ed eventuali messaggi d’errore.</p>

<h1>Progettazione dell&#8217;algoritmo</h1>

<p>La scelta della struttura dati e del relativo algoritmo tiene conto dei parametri dettati
dalla specifica del problema: l’efficacia dell’algoritmo di ordinamento sarà il parametro
fondamentale per la scelta del modus operandi; l’analisi non terrà conto delle comuni problematiche
relative alla gestione di una base dati, quale la gestione degli indici, un’efficiente gestione
dello storage o la disponibilità del dato a fronte di crash applicativi.</p>

<p>Si è scelto di articolare il programma in tre fasi distinte:</p>

<ol>
    * analisi dei parametri forniti su riga di comando: di particolare rilievo, la possibilità 
        di definire un criterio di ordinamento;
    * lettura del file contenente i dati e relativa creazione della struttura dati in memoria;
    * stampa dei dati ordinati e successiva deallocazione della struttura dati.
</ol>


<h2>Struttura dati</h2>

<p>Al fine di risolvere il problema fornito in modo ottimale, si è scelto di adottare una
struttura dati del tipo <strong>albero rosso nero</strong>, particolare evoluzione dell’albero binario.</p>

<p>La modalità di rappresentazione del dato in memoria non può essere affidata ad una struttura
statica quale il vettore1: tale soluzione, infatti, risulterebbe inefficiente in termini
computazionali, in quanto gli algoritmi di ordinamento di vettori sono caratterizzati, nel caso
migliore, da una complessità pari a <em>n·log(n)</em>; non è inoltre noto a priori il numero di record
che il vettore dovrebbe contenere, il che renderebbe la soluzione poco flessibile e scalabile.</p>

<blockquote>
    La struttura dati originale prevede l’uso di un particolare nodo chiamato “sentinella”, in 
    modo tale che non esistano foglie e tutti i nodi puntino alla sentinella: l’implementazione 
    proposta farà uso di un puntatore nullo piuttosto che allocare un nodo.
</blockquote>


<h2>Algoritmo</h2>

<p>Il metodo di ordinamento scelto è di tipo <strong>interno</strong>, in quanto il file da ordinare può essere
contenuto in memoria: questo approccio permette di accedere direttamente ad un record generico
della tabella, riducendo sensibilmente i tempi di ordinamento; al contrario, un ordinamento <em>esterno</em>
prevede che i dati risiedano su disco e si possa accedere ad essi solo in modo sequenziale o al più per grandi
blocchi.</p>

<p>Sebbene l’implementazione di un albero rosso-nero risulti complessa, questo offre un eccellente tempo
di esecuzione anche nel caso peggiore.
L’implementazione proposta segue il paradigma di massimizzare l’efficienza in termini temporali di
esecuzione, a discapito di un maggiore utilizzo di memoria: questa scelta progettuale si basa sulla
considerazione che il sistema operativo, sfruttando diverse tecniche di virtualizzazione e gestione della
memoria di sistema, metta a disposizione di un programma in esecuzione un quantitativo di memoria praticamente
illimitato, al contrario del fattore “tempo” che non può essere riutilizzato e condiviso.
L’algoritmo di ordinamento proposto prevede di memorizzare il record della tabella all’interno di un nodo
dell’albero: ne consegue che l’operazione di lettura del file, la relativa creazione dei nodi e l’inserimento
degli stessi all’interno dell’albero, generi un albero perfettamente bilanciato ed ordinato secondo i criteri
richiesti.
Nella tabella seguente vengono riassunte le principali proprietà, in termini di efficienza di algoritmo:</p>

<table class="table table-condensed table-striped table-bordered">
    <thead><tr><th>Proprietà</th><th>Valore</th></tr></thead>
    <tbody>
        <tr><td>Altezza albero</td><td>O(log n)</td></tr>
        <tr><td>Inserimento</td><td>O(log n)</td></tr>
        <tr><td>Cancellazione</td><td>O(log n)</td></tr>
        <tr><td>Ricerca</td><td>O(log n)</td></tr>
    </tbody>
</table>




<blockquote>
Si fa riferimento ad un albero contenente “n” nodi. I suddetti valori rappresentano il caso peggiore 
che si può verificare.
</blockquote>


<p>Le operazioni di lettura su un albero rosso-nero non richiedono particolari considerazioni rispetto
a quelle utilizzate per gli alberi binari di ricerca, poiché gli alberi rosso-neri sono una loro
specializzazione.</p>

<h2>Prima fase: analisi dei parametri</h2>

<p>Il programma inizierà la sua esecuzione inizializzando le strutture dati e le variabili necessarie
al suo funzionamento.
Successivamente verranno analizzati i parametri specificati su riga di comando, necessari per
definire il nome del file contenente la tabella, nonché per modificare alcuni comportamenti predefiniti
dell’applicativo.</p>

<h2>Seconda fase: lettura del file di input</h2>

<p>La lettura del file di input corrisponde alla fase più rilevante dell’applicazione: durante questa
fase, in corrispondenza di ogni record letto dal file, verrà creato un nuovo nodo ed effettuato un
inserimento nell’albero, qualora questa operazione risulti possibile.</p>

<p>L’implementazione della struttura dati e delle funzioni necessarie al suo mantenimento costituiscono
una parte statica ed immutabile del programma; al contrario, la funzione preposta al confronto di due
nodi generici tiene conto dei criteri di ordinamento specificati dall’utente.</p>

<p>Si è scelto di creare tre funzioni differenti (<em>compare_name</em>, <em>compare_mark</em> e
<em>compare_registration</em>)
preposte al confronto di due generici nodi dell’albero, ognuna delle quali tiene conto di uno solo
dei tre campi del record; un vettore di puntatori a funzione verrà opportunamente inizializzato
durante la prima fase con queste tre funzioni, seguendo l’ordine specificato dai criteri di
ordinamento indicati dall’utente; in ultimo, la funzione che dovrà effettuare il confronto tra due
nodi dell’albero, scorrerà il vettore ed userà la sotto-funzione specifica.</p>

<p>Le funzioni di ordinamento sono necessarie per individuare il punto esatto dell’albero nel
quale inserire il nuovo nodo; il risultato immediato di un inserimento o di una cancellazione
può corrispondere ad una violazione di una delle quattro proprietà fondamentali dell&#8217;albero
rosso-nero: ristabilire tali proprietà richiede un numero limitato di operazioni, che possono
avere una complessità costante nel caso medio, logaritmica nel caso peggiore.</p>

<h2>Terza fase: stampa dei risultati</h2>

<p>La terza fase si limita ad una ricorsione sull’albero per stampare i nodi presenti ed a
una successiva fase di deallocazione della struttura dati utilizzata.
Va sottolineato che la visita ricorsiva dell’albero per la cancellazione di un nodo,
è di tipo non lineare: non è pertanto possibile ottimizzare ulteriormente l’implementazione
a meno di non perdere di leggibilità e semplicità di gestione del codice (al contrario,
una ricorsione lineare potrebbe essere sostituita con un’iterazione, portando ad una
riduzione della complessità).</p>

<blockquote>
    Si è scelto di non implementare in forma iterativa la funzione “node_traverse”: 
    sebbene questa forma risulti più efficiente, si vuole dare esempio di visita ricorsiva 
    in ordine simmetrico e posticipato (node_dealloc).
</blockquote>


<h1>Testing del programma</h1>

<p>Unitamente ai sorgenti che compongono il progetto, sono stati inclusi anche alcuni
file contenenti dati di esempio; questi rappresentano istanze di input con dimensioni
differenti, di modo che sia possibile un test più esaustivo dello strumento proposto.</p>

<p>Di seguito verrà incluso qualche test significativo ed il relativo output del programma;
i seguenti test sono stati effettuati usando questi parametri da riga di comando:</p>

<ul>
<li><strong>-i file</strong>: Legge i dati dal file specificato</li>
<li><strong>-o output.txt</strong>: Scrive la tabella ordinata nel file specificato</li>
<li><strong>-s criterio</strong>: Criterio di ordinamento</li>
</ul>


<h2>Test 1. lettura da un file inesistente</h2>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>./rb-sorter -i not-exist.txt
</span><span class='line'>[INFO] Creazione struttura dati
</span><span class='line'>[INFO] Lettura dati dal file 'not-exist.txt' [ERR ] impossibile aprire il file 'not-exist.txt'</span></code></pre></td></tr></table></div></figure>


<h2>Test 2. database di 15 linee, duplicati presenti</h2>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ time ./rb-sorter -i database_15_linee.txt -o output.txt -s c+m+v [INFO] Creazione struttura dati
</span><span class='line'>[INFO] Lettura dati dal file 'database_15_linee.txt'
</span><span class='line'>[INFO] Record letti : 15
</span><span class='line'>[INFO] Nodi inseriti: 15
</span><span class='line'>[INFO] Scrittura risultati
</span><span class='line'>[INFO] Distruzione struttura dati
</span><span class='line'>real  0m0.005s
</span><span class='line'>user  0m0.001s
</span><span class='line'>sys   0m0.003s</span></code></pre></td></tr></table></div></figure>


<h2>Test 3. database con 1,7 milioni di linee, duplicati non presenti</h2>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ time ./rb-sorter -i database_1.7M_linee.txt -o output.txt -s c+m+v [INFO] Creazione struttura dati
</span><span class='line'>[INFO] Lettura dati dal file 'database_1.7M_linee.txt'
</span><span class='line'>[INFO] Record letti : 1699062
</span><span class='line'>[INFO] Nodi inseriti: 1699062
</span><span class='line'>[INFO] Scrittura risultati
</span><span class='line'>[INFO] Distruzione struttura dati
</span><span class='line'>real  0m10.839s
</span><span class='line'>user  0m8.470s
</span><span class='line'>sys   0m0.665s</span></code></pre></td></tr></table></div></figure>


<h1>Valutazione della complessità del programma</h1>

<p>Per calcolare il tempo di esecuzione del programma nonché l’ordine di grandezza
della complessità, si è scelto di adoperare due approcci distinti: in prima istanza,
utilizzando un metodo analitico e, successivamente, uno sperimentale.</p>

<h2>Approccio analitico</h2>

<p>Sono stati identificati, all’interno del codice, tre macro blocchi di istruzioni:
ad ognuno di questi è stato associato un costo, calcolando dapprima il numero effettivo
di passi base eseguiti e derivando in seguito la classe dell’ordine di grandezza.
Il primo blocco, la funzione loadfile, legge i dati dal file contenente il database;
facendo coincidere il numero di righe del file con il numero di nodi che possibilmente
verranno inseriti nell’albero, possiamo esprimere l’intero costo del programma in
funzione del numero di record letti.
Il costo del suddetto blocco sarà equivalente al prodotto di n record per il costo
della funzione di inserimento di un nodo nell’albero, ovvero O(log n).
Il secondo ed il terzo blocco del programma equivalgono alla visita dell’intero
albero per stamparne i nodi ed alla deallocazione della struttura dati: entrambi hanno
una complessità proporzionale al numero di nodi (record) presenti nell’albero, quindi
pari ad O(n).</p>

<p>Di seguito, il riepilogo di quanto esposto:</p>

<table class="table table-bordered table-condensed table-striped">
<thead><tr><th>Funzione</th><th>Costo</th></tr></thead>
<tbody>
    <tr><td>LOAD_FILE</td><td>O(n&times;log n)</td></tr>
    <tr><td>TREE_TRAVERSE</td><td>O(n)</td></tr>
    <tr><td>TREE_DESTROY</td><td>O(n)</td></tr>
</tbody>
</table>


<p>La complessità totale quindi è pari a 2&times;n + n&times;log n, assimilabile alla
classe di complessità pseudo lineare T(n) = O(n&times;log n).</p>

<h2>Approccio sperimentale</h2>

<p>L’approccio empirico proposto si basa sulla misurazione dei tempi di esecuzione
del programma, fornendo istanze di input progressivamente maggiori.</p>

<blockquote>Per ogni istanza di input, il programma è stato eseguito più volte: 
si è quindi valutato e riportato il valore medio.</blockquote>


<p>Mettendo in relazione il numero di record processati ed il numero di secondi impiegati,
si è notato come l’andamento della complessità temporale (espressa in secondi) seguisse
la curva espressa dalla complessità calcolata con l’approccio analitico.</p>

<p>Di seguito i valori rilevati e loro rappresentazione grafica.</p>

<table class="table table-bordered table-condensed table-striped">
<thead><tr><th>N. Record</th><th>Secondi</th><th>2&times;n&times;LOG n</th></tr></thead>
<tbody>
    <tr><td>183.300</td><td>1,022</td><td>783.904</td></tr>
    <tr><td>367.650</td><td>2,164</td><td>1.678.482</td></tr>
    <tr><td>735.300</td><td>4,546</td><td>3.578.311</td></tr>   
    <tr><td>1.470.600</td><td>9,562</td><td>7.599.317</td></tr>
    <tr><td>2.941.200</td><td>15,838</td><td>16.084.024</td></tr>
    <tr><td>5.882.400</td><td>36,617</td><td>33.938.827</td></tr>   
    <tr><td>11.764.800</td><td>71,812</td><td>71.419.213</td></tr>      
</tbody>
</table>


<p><img class="center" src="http://www.devzero.it/assets/images/posts/log_graph.png" title="Grafico tempi di esecuzione" ></p>

<p>Scarica il progetto <a href="http://www.devzero.it/attachments/rb-sorter.tar.gz">rb-sorter.tar.gz</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[ALU]]></title>
    <link href="http://www.devzero.it/blog/2009/06/07/alu/"/>
    <updated>2009-06-07T00:00:00+02:00</updated>
    <id>http://www.devzero.it/blog/2009/06/07/alu</id>
    <content type="html"><![CDATA[<h2>ALU circuit</h2>

<p>In computing, an <strong>arithmetic logic unit</strong> (<em>ALU</em>) is a digital
circuit that performs arithmetic and logical operations. The ALU is a fundamental building
block of the central processing unit (CPU) of a computer, and even the simplest microprocessors 
contain one for purposes such as maintaining timers.</p>

<!-- more -->


<p>This project is an example of an ALU realized with Tkgate for university purposes.
The following operators are implemented:</p>

<ul>
<li>adder</li>
<li>multiplier</li>
<li>divider</li>
<li>left/right and circular shift</li>
</ul>


<p>It works with 8-bit unsigned numbers.</p>

<p>Download <a href="http://www.devzero.it/attachments/ALU.tgz">ALU.tgz</a></p>
]]></content>
  </entry>
  
</feed>
