<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Google Inc. &#8211; stoimen&#039;s web log</title>
	<atom:link href="/tag/google-inc/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>on web development</description>
	<lastBuildDate>Tue, 13 Feb 2018 08:18:15 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.0.3</generator>
	<item>
		<title>Computer Algorithms: Longest Increasing Subsequence</title>
		<link>/2012/12/03/computer-algorithms-longest-increasing-subsequence/</link>
		<comments>/2012/12/03/computer-algorithms-longest-increasing-subsequence/#comments</comments>
		<pubDate>Mon, 03 Dec 2012 13:22:08 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[data structures]]></category>
		<category><![CDATA[dynamic programming]]></category>
		<category><![CDATA[Graphs]]></category>
		<category><![CDATA[Bellman–Ford algorithm]]></category>
		<category><![CDATA[Directed acyclic graph]]></category>
		<category><![CDATA[Dynamic programming]]></category>
		<category><![CDATA[equal sub-solutions]]></category>
		<category><![CDATA[Facebook Inc]]></category>
		<category><![CDATA[Google Inc.]]></category>
		<category><![CDATA[graph algorithms]]></category>
		<category><![CDATA[Graph theory]]></category>
		<category><![CDATA[Longest increasing subsequence]]></category>
		<category><![CDATA[Mathematical optimization]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Network theory]]></category>
		<category><![CDATA[Operations research]]></category>
		<category><![CDATA[Richard Bellman]]></category>
		<category><![CDATA[Routing algorithms]]></category>
		<category><![CDATA[Shortest path problem]]></category>
		<category><![CDATA[sub-solution]]></category>
		<category><![CDATA[Theoretical computer science]]></category>
		<category><![CDATA[Yahoo! Inc.]]></category>

		<guid isPermaLink="false">/?p=3478</guid>
		<description><![CDATA[Introduction A very common problem in computer programming is finding the longest increasing (decreasing) subsequence in a sequence of numbers (usually integers). Actually this is a typical dynamic programming problem. Dynamic programming can be described as a huge area of computer science problems that can be categorized by the way they can be solved. Unlike &#8230; <a href="/2012/12/03/computer-algorithms-longest-increasing-subsequence/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Longest Increasing Subsequence</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2012/10/28/computer-algorithms-shortest-path-in-a-directed-acyclic-graph/" rel="bookmark" title="Computer Algorithms: Shortest Path in a Directed Acyclic Graph">Computer Algorithms: Shortest Path in a Directed Acyclic Graph </a></li>
<li><a href="/2012/10/15/computer-algorithms-dijkstra-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Dijkstra Shortest Path in a Graph">Computer Algorithms: Dijkstra Shortest Path in a Graph </a></li>
<li><a href="/2012/10/22/computer-algorithms-bellman-ford-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Bellman-Ford Shortest Path in a Graph">Computer Algorithms: Bellman-Ford Shortest Path in a Graph </a></li>
<li><a href="/2012/12/10/computer-algorithms-topological-sort-revisited/" rel="bookmark" title="Computer Algorithms: Topological Sort Revisited">Computer Algorithms: Topological Sort Revisited </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>A very common problem in computer programming is finding the longest increasing (decreasing) subsequence in a sequence of numbers (usually integers). Actually this is a typical dynamic programming problem.</p>
<p>Dynamic programming can be described as a huge area of computer science problems that can be categorized by the way they can be solved. Unlike divide and conquer, where we were able to merge the fairly equal sub-solutions in order to receive one single solution of the problem, in dynamic programming we usually try to find an optimal sub-solution and then grow it.</p>
<p>Once we have an optimal sub-solution on each step we try to upgrade it in order to cover the whole problem. Thus a typical member of the dynamic programming class is finding the longest subsequence.</p>
<p>However this problem is interesting because it can be related to graph theory. Let’s find out how.<span id="more-3478"></span></p>
<h2>Overview</h2>
<p>We already know various ways to calculate the shortest paths in a graph. Indeed finding the single-source shortest path is a typical graph problem. To model such kind of solutions we definitely need a graph represented in our solution. </p>
<p>However the single-source shortest path isn’t a straight-forward problem. It depends on many factors. Thus for positive edges <a href="/2012/10/15/computer-algorithms-dijkstra-shortest-path-in-a-graph/" title="Computer Algorithms: Dijkstra Shortest Path in a Graph">the algorithm of Edsger Dijkstra</a> can be a perfect solution, but when the graph contains negative edges his algorithm is no longer useful. </p>
<p>In the presence of negative edges the Dijkstra’s algorithm doesn’t work and we’d better use the <a href="/2012/10/22/computer-algorithms-bellman-ford-shortest-path-in-a-graph/" title="Computer Algorithms: Bellman-Ford Shortest Path in a Graph">Bellman-Ford algorithm</a>. It is interesting to note, that it was exactly <a href="http://en.wikipedia.org/wiki/Richard_E._Bellman" title="Richard E. Bellman" target="_blank">Richard Bellman</a> who first introduced the term “dynamic programming” in the 1940s.</p>
<p>In fact the Bellman-Ford algorithm was able to detect negative cycles. That’s too important, because in presence of negative cycles the shortest path problem is no longer well defined. </p>
<p>In the other hand when we’re talking about <a href="/2012/10/28/computer-algorithms-shortest-path-in-a-directed-acyclic-graph/" title="Computer Algorithms: Shortest Path in a Directed Acyclic Graph">shortest paths in a DAG</a> (Directed Acyclic Graph) we can find a faster (linear) solution. That’s because we’re sure that there are no cycles (not even negative cycles)! </p>
<figure id="attachment_3498" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/12/1.-Toplogical-Sort.png"><img src="/wp-content/uploads/2012/12/1.-Toplogical-Sort.png" alt="Toplogical Sort" title="Toplogical Sort" width="620" height="399" class="size-full wp-image-3498" srcset="/wp-content/uploads/2012/12/1.-Toplogical-Sort.png 620w, /wp-content/uploads/2012/12/1.-Toplogical-Sort-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>Finding the shortest paths in a DAG is closely related to the topological sorting of the DAG. This gives us a linear representation of the vertices of the DAG and we can clearly calculate the distances from the starting node to all other nodes. Note that in a DAG we have one or more nodes that can be considered as starting nodes – which means they don’t have predecessors (incoming edges).</p>
<figure id="attachment_3497" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/12/2.-Toplogical-Sort-2.png"><img src="/wp-content/uploads/2012/12/2.-Toplogical-Sort-2.png" alt="Toplogical Sort 2" title="Toplogical Sort 2" width="620" height="399" class="size-full wp-image-3497" srcset="/wp-content/uploads/2012/12/2.-Toplogical-Sort-2.png 620w, /wp-content/uploads/2012/12/2.-Toplogical-Sort-2-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>Following the words above is pretty hard to find what all these graph algorithms have to do with finding the longest increasing (decreasing) subsequence. Actually this problem is very closely related to the toplogical sort of the DAG and the problem of finding shortest paths in a DAG.</p>
<p>That’s because we can represent our sequence as a DAG. The only thing we must care about is to “connect” with directed edges those elements that form an increasing (decreasing) pair. </p>
<figure id="attachment_3496" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/12/3.-Integer-Sequence.png"><img src="/wp-content/uploads/2012/12/3.-Integer-Sequence.png" alt="Integer Sequence as a DAG" title="Integer Sequence" width="620" height="399" class="size-full wp-image-3496" srcset="/wp-content/uploads/2012/12/3.-Integer-Sequence.png 620w, /wp-content/uploads/2012/12/3.-Integer-Sequence-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>Thus the sequence from our example [1, 8, 2, 7, 3, 4, 1, 6] is going to look like this.</p>
<figure id="attachment_3495" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/12/4.-Longest-subsequence.png"><img src="/wp-content/uploads/2012/12/4.-Longest-subsequence.png" alt="Longest subsequence" title="Longest subsequence" width="620" height="399" class="size-full wp-image-3495" srcset="/wp-content/uploads/2012/12/4.-Longest-subsequence.png 620w, /wp-content/uploads/2012/12/4.-Longest-subsequence-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>Another important thing to note is that we don’t search for shortest, but for longest path, since our task is to find the longest subsequence.</p>
<h2>Pseudo Code</h2>
<p>Our pseudo code for finding the shortest paths in a DAG was something like that.</p>
<pre>
1. Get the toplogically sorted list L of the DAG;
2. The starting node is s;
3. The distance to s equals to 0;
4. All other distances are initialized to &#8734;
5. For each node (v) in L\{s} do:
5.1. If dist(v) > dist(u) + w(u, v) then
5.1.1.  dist(v) := dist(u) + w(u, v)
</pre>
<p>In the above pseudo code &#8220;u&#8221; is every predecessor of &#8220;v&#8221;!</p>
<p>Now we must “reverse” the solution above in order to find the longest increasing subsequence. Note that we don&#8217;t care any more about the weight of the edges, thus we can simply substitute them with 1.</p>
<pre>
1. Get the sequence (L) as a toplogically sorted DAG;
2. For each (i) in L do:
2.1. S(i) := 1 + max(S(j), where (i, j) is an edge from the DAG);
</pre>
<h2>Application</h2>
<p>Finding the longest increasing subsequence can be very useful not only at the Google/Yahoo/Facebook interview, but also in various fields of statistics.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2012/10/28/computer-algorithms-shortest-path-in-a-directed-acyclic-graph/" rel="bookmark" title="Computer Algorithms: Shortest Path in a Directed Acyclic Graph">Computer Algorithms: Shortest Path in a Directed Acyclic Graph </a></li>
<li><a href="/2012/10/15/computer-algorithms-dijkstra-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Dijkstra Shortest Path in a Graph">Computer Algorithms: Dijkstra Shortest Path in a Graph </a></li>
<li><a href="/2012/10/22/computer-algorithms-bellman-ford-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Bellman-Ford Shortest Path in a Graph">Computer Algorithms: Bellman-Ford Shortest Path in a Graph </a></li>
<li><a href="/2012/12/10/computer-algorithms-topological-sort-revisited/" rel="bookmark" title="Computer Algorithms: Topological Sort Revisited">Computer Algorithms: Topological Sort Revisited </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2012/12/03/computer-algorithms-longest-increasing-subsequence/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Computer Algorithms: Data Compression with Prefix Encoding</title>
		<link>/2012/02/06/computer-algorithms-data-compression-with-prefix-encoding/</link>
		<comments>/2012/02/06/computer-algorithms-data-compression-with-prefix-encoding/#respond</comments>
		<pubDate>Mon, 06 Feb 2012 20:50:58 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[Apple Inc.]]></category>
		<category><![CDATA[Computer science]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Data compression]]></category>
		<category><![CDATA[Decoder]]></category>
		<category><![CDATA[Delta encoding]]></category>
		<category><![CDATA[Dictionary coder]]></category>
		<category><![CDATA[Google Inc.]]></category>
		<category><![CDATA[Johnson Clarkson Jackson]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[mobile device]]></category>
		<category><![CDATA[same algorithm]]></category>
		<category><![CDATA[Technology/Internet]]></category>
		<category><![CDATA[Trie]]></category>
		<category><![CDATA[United Kingdom]]></category>
		<category><![CDATA[Yahoo! Inc.]]></category>

		<guid isPermaLink="false">/?p=2699</guid>
		<description><![CDATA[Overview Prefix encoding, sometimes called front encoding, is yet another algorithm that tries to remove duplicated data in order to reduce its size. Its principles are simple, however this algorithm tend to be difficult to implement. To understand why, first let’s take a look of its nature. Please, have a look on the following dictionary. &#8230; <a href="/2012/02/06/computer-algorithms-data-compression-with-prefix-encoding/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Data Compression with Prefix Encoding</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2012/01/30/computer-algorithms-data-compression-with-relative-encoding/" rel="bookmark" title="Computer Algorithms: Data Compression with Relative Encoding">Computer Algorithms: Data Compression with Relative Encoding </a></li>
<li><a href="/2012/01/09/computer-algorithms-data-compression-with-run-length-encoding/" rel="bookmark" title="Computer Algorithms: Data Compression with Run-length Encoding">Computer Algorithms: Data Compression with Run-length Encoding </a></li>
<li><a href="/2012/01/23/computer-algorithms-data-compression-with-diagram-encoding-and-pattern-substitution/" rel="bookmark" title="Computer Algorithms: Data Compression with Diagram Encoding and Pattern Substitution">Computer Algorithms: Data Compression with Diagram Encoding and Pattern Substitution </a></li>
<li><a href="/2012/01/16/computer-algorithms-data-compression-with-bitmaps/" rel="bookmark" title="Computer Algorithms: Data Compression with Bitmaps">Computer Algorithms: Data Compression with Bitmaps </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Overview</h2>
<p>Prefix encoding, sometimes called front encoding, is yet another algorithm that tries to remove duplicated data in order to reduce its size. Its principles are simple, however this algorithm tend to be difficult to implement. To understand why, first let’s take a look of its nature.</p>
<p>Please, have a look on the following dictionary.</p>
<pre lang="PHP">
use
used
useful
usefully
usefulness
useless
uselessly
uselessness
</pre>
<p>Instead of keeping all these words in plain text or transferring all them over a network, we can compress (encode) them with prefix encoding. </p>
<p><figure id="attachment_2700" style="width: 299px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/02/Prefixencoding.png"><img src="/wp-content/uploads/2012/02/Prefixencoding.png" alt="Prefix Encoding" title="Prefix encoding" width="299" height="457" class="size-full wp-image-2700" srcset="/wp-content/uploads/2012/02/Prefixencoding.png 299w, /wp-content/uploads/2012/02/Prefixencoding-196x300.png 196w" sizes="(max-width: 299px) 100vw, 299px" /></a><figcaption class="wp-caption-text"> </figcaption></figure><br />
<span id="more-2699"></span><br />
It’s clear that each of these words begin with the prefix “use” which is also the first word from the list. So we can easily compress them into the following array.</p>
<pre lang="PHP">
$data = array(
0 => 'use',
1 => '0d',
2 => '0ful',
3 => '0fully',
4 => '0less',
5 => '0lessly',
6 => '0lessness',
);
</pre>
<p>It’s clear that this is not the best compression and we can go even further by using not only the first word as prefix.</p>
<pre lang="PHP">
$data = array(
0 => 'use',
1 => '0d',
2 => '0ful',
3 => '2ly',
4 => '0less',
5 => '4ly',
6 => '4ness',
);
</pre>
<p>Now the compression is better and the good news is that decompression is a fairly simple process. However the tricky part is compression itself. The problem is that it is quite difficult to chose an appropriate prefix. In our first example this is simple, but most of the times in practice we can have more heterogeneous data. Indeed the process of compression can be very difficult for randomly generated data and the algorithm will be not only slow, but difficult to implement.</p>
<p>The good thing is that this algorithm can be used in many cases once we know the data format in advance. So let’s see three examples where this algorithm can be very handy.</p>
<h2>Application</h2>
<p>Here are three examples of prefix encoding. As I said above the process of compression can be very difficult for random data, so it is a good practice to use only it if you know in advance the format of the input data.</p>
<h3>Date and time prefixes</h3>
<p>We humans often skip the first two digits of an year, so for instance we don’t always write 1995 or 1996, but we use the shorter &#8211; ‘95 and ‘96. Thus years can be encoded with shorter strings.</p>
<pre lang="PHP">
input: 	(1991, 1992, 1993, 1994, 1995, 1996)
output:	(91, 92, 93, 94, 95, 96)
</pre>
<p>The problem is that with small changes of the input stream we can confuse the decoder. Thus if we add years from the 21st century we lose the uniqueness of the data.</p>
<pre lang="PHP">
input:	(1998, 1992, 1999, 2011, 2012)
output: (98, 92, 99, 11, 12)
</pre>
<p>Now the decoder can decode the last two values as (1911, 1912) as “19” is considered to be the prefix. So we must know in advance that our prefix is absolutely equal for each of the values. If not the encoding format must be different. For instance we can encode also the prefix, with some special maker.</p>
<pre lang="PHP">
input:	(1998, 1992, 1932, 1924, 2001, 2012)
output:	(#19, 98, 92, 32, 24, #20, 01, 12)
</pre>
<p>Once the decoder reads the # character it will know to decode the following number as prefix.</p>
<p>This can be used in practice for date and time formats. Let’s say we have some datetime values, but we know that all of them are in the same day.</p>
<pre lang="PHP">
2012-01-31 15:33:45
2012-01-31 16:12:11
2012-01-31 17:32:35
2012-01-31 18:54:34
</pre>
<p>Obviously we can omit the date part of these strings and send (keep) only the time. Once again, we must be absolutely sure that all these values are in the same day. If not, we can use the encoding strategy of the previous example.</p>
<h3>Phone numbers</h3>
<p>Phone numbers are the typical case of prefix encoding. Not only the international code, but also the mobile network operators use prefixes for their phone numbers. Thus if we have to transfer phone numbers from, let’s say the <strong>UK</strong>, we can replace the leading <strong>“+44”</strong> with something shorter. </p>
<p>If you happen to code a phone book for a mobile device you can spend some space by compressing the data using prefix encoding and thus the user will have more space and will store more phone numbers on his mobile.</p>
<p>Phone number prefixes can be also used for database normalization. Thus you can store them in a separate db table and leave only the unique numbers from the phonebook.</p>
<h3>Geo Coordinates</h3>
<p>Using the same example from <a href="/2012/01/30/computer-algorithms-data-compression-with-relative-encoding/" title="Computer Algorithms: Data Compression with Relative Encoding">my previous post</a> we can send GEO coordinates by removing a common prefix, for large levels of zoom. Indeed when you’ve to send lots of markers to your map application you can expect all of these markers to be fairly close to each other in large zoom level.</p>
<figure id="attachment_2701" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/02/NY-map.png"><img src="/wp-content/uploads/2012/02/NY-map.png" alt="NY Subway Map" title="NY Subway Map" width="620" class="size-full wp-image-2701" srcset="/wp-content/uploads/2012/02/NY-map.png 843w, /wp-content/uploads/2012/02/NY-map-300x199.png 300w" sizes="(max-width: 843px) 100vw, 843px" /></a><figcaption class="wp-caption-text">On large zoom levels we can expect markers to be with the same prefix.</figcaption></figure>
<p>Now the coordinates of those points can have a common prefix, like the example bellow with the Subway stations.</p>
<pre lang="PHP">
LatLon(40.762959,-73.985989)
LatLon(40.761886,-73.983629)
LatLon(40.762861,-73.981612)
LatLon(40.764616,-73.98056)
</pre>
<p>We can see that all of these GEO points have the same prefix (40.76x, -73.98x), so we can send the prefix only once.</p>
<pre lang="PHP">
Prefix: (40.76, -73.98)
Data: 
LatLon(2959,5989)
LatLon(1886,3629)
LatLon(2861,1612)
LatLon(4616,056)
</pre>
<p>These are only three examples of prefix encoding and this algorithm must be considered as very useful when transferring homogeneous data. </p>
<h2>Suffix Encoding</h2>
<p>Suffix encoding practically the same algorithm as prefix encoding, with the small difference that we use to encode duplicating suffixes. Like the examples bellow suffix encoding can be useful is replacing repeating last name suffixes.</p>
<pre lang="PHP">
Johnson
Clarkson
Jackson
</pre>
<p>Or company names.</p>
<pre lang="PHP">
Apple Inc.
Google Inc.
Yahoo! Inc.
</pre>
<p>Here we can replace “ Inc.” with something else, but shorter.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2012/01/30/computer-algorithms-data-compression-with-relative-encoding/" rel="bookmark" title="Computer Algorithms: Data Compression with Relative Encoding">Computer Algorithms: Data Compression with Relative Encoding </a></li>
<li><a href="/2012/01/09/computer-algorithms-data-compression-with-run-length-encoding/" rel="bookmark" title="Computer Algorithms: Data Compression with Run-length Encoding">Computer Algorithms: Data Compression with Run-length Encoding </a></li>
<li><a href="/2012/01/23/computer-algorithms-data-compression-with-diagram-encoding-and-pattern-substitution/" rel="bookmark" title="Computer Algorithms: Data Compression with Diagram Encoding and Pattern Substitution">Computer Algorithms: Data Compression with Diagram Encoding and Pattern Substitution </a></li>
<li><a href="/2012/01/16/computer-algorithms-data-compression-with-bitmaps/" rel="bookmark" title="Computer Algorithms: Data Compression with Bitmaps">Computer Algorithms: Data Compression with Bitmaps </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2012/02/06/computer-algorithms-data-compression-with-prefix-encoding/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Computer Algorithms: Data Compression with Relative Encoding</title>
		<link>/2012/01/30/computer-algorithms-data-compression-with-relative-encoding/</link>
		<comments>/2012/01/30/computer-algorithms-data-compression-with-relative-encoding/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 18:27:26 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[Africa]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[Algorithmic efficiency]]></category>
		<category><![CDATA[Application This algorithm]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Data compression]]></category>
		<category><![CDATA[data compression algorithm]]></category>
		<category><![CDATA[Google Inc.]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Lossless data compression]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Run-length encoding]]></category>
		<category><![CDATA[San Francisco]]></category>
		<category><![CDATA[Technology/Internet]]></category>
		<category><![CDATA[web server]]></category>
		<category><![CDATA[west coast]]></category>
		<category><![CDATA[Yahoo! Communications Europe Ltd.]]></category>

		<guid isPermaLink="false">/?p=2658</guid>
		<description><![CDATA[Overview Relative encoding is another data compression algorithm. While run-length encoding, bitmap encoding and diagram and pattern substitution were trying to reduce repeating data, with relative encoding the goal is a bit different. Indeed run-length encoding was searching for long runs of repeating elements, while pattern substitution and bitmap encoding were trying to “map” where &#8230; <a href="/2012/01/30/computer-algorithms-data-compression-with-relative-encoding/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Data Compression with Relative Encoding</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2012/01/09/computer-algorithms-data-compression-with-run-length-encoding/" rel="bookmark" title="Computer Algorithms: Data Compression with Run-length Encoding">Computer Algorithms: Data Compression with Run-length Encoding </a></li>
<li><a href="/2012/02/06/computer-algorithms-data-compression-with-prefix-encoding/" rel="bookmark" title="Computer Algorithms: Data Compression with Prefix Encoding">Computer Algorithms: Data Compression with Prefix Encoding </a></li>
<li><a href="/2012/01/16/computer-algorithms-data-compression-with-bitmaps/" rel="bookmark" title="Computer Algorithms: Data Compression with Bitmaps">Computer Algorithms: Data Compression with Bitmaps </a></li>
<li><a href="/2012/01/23/computer-algorithms-data-compression-with-diagram-encoding-and-pattern-substitution/" rel="bookmark" title="Computer Algorithms: Data Compression with Diagram Encoding and Pattern Substitution">Computer Algorithms: Data Compression with Diagram Encoding and Pattern Substitution </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Overview</h2>
<p>Relative encoding is another data compression algorithm. While <a href="/2012/01/09/computer-algorithms-data-compression-with-run-length-encoding/" title="Computer Algorithms: Data Compression with Run-length Encoding">run-length encoding</a>, <a href="/2012/01/16/computer-algorithms-data-compression-with-bitmaps/" title="Computer Algorithms: Data Compression with Bitmaps">bitmap encoding</a> and <a href="/2012/01/23/computer-algorithms-data-compression-with-diagram-encoding-and-pattern-substitution/" title="Computer Algorithms: Data Compression with Diagram Encoding and Pattern Substitution">diagram and pattern substitution</a> were trying to reduce repeating data, with relative encoding the goal is a bit different. Indeed run-length encoding was searching for long runs of repeating elements, while pattern substitution and bitmap encoding were trying to “map” where the repetitions happen to occur. </p>
<p>The only problem with these algorithms is that not always the input stream of data is constructed out of repeating elements. It is clear that if the input stream contains many repeating elements there must be some way of reducing them. However that doesn’t mean that we cannot compress data if there are no repetitions. It all depends on the data. Let’s say we have the following stream to compress.</p>
<pre lang="PHP">
1, 2, 3, 4, 5, 6, 7
</pre>
<p>We can hardly imagine how this stream of data can be compressed. The same problem may occur when trying to compress the alphabet. Indeed the alphabet letters the very base of the words so it is the minimal part for word construction and it&#8217;s hard to compress them.</p>
<p>Fortunately this isn’t true always. An algorithm that tryies to deal with non repeating data is relative encoding. Let’s see the following input stream &#8211; years from a given decade (the 90&#8217;s).</p>
<pre lang="PHP">
1991,1991,1999,1998,1991,1993,1992,1992
</pre>
<p>Here we have 39 characters and we can reduce them. A natural approach is to remove the leading “19” as we humans often do.</p>
<pre lang="PHP">
91,91,99,98,91,93,92,92
</pre>
<p>Now we have a shorter string, but we can go even further with keeping only the first year. All other years will as relative to this year.</p>
<pre lang="PHP">
91,0,8,7,0,2,1,1
</pre>
<p>Now the volume of transferred data is reduced a lot (from 39 to 16 &#8211; more than 50%). However there are some questions we need to answer first, because the stream wont be always formatted in such pretty way. How about the next character stream?</p>
<pre lang="PHP">
91,94,95,95,98,100,101,102,105,110
</pre>
<p>We see that the value 100 is somehow in the middle of the interval and it is handy to use it as a base value for the relative encoding. Thus the stream above will become:</p>
<pre lang="PHP">
-9,-6,-5,-5,-2,100,1,2,5,10
</pre>
<p>The problem is that we can’t decide which value will be the <strong>base value</strong> so easily. What if the data was dispersed in a different way.</p>
<pre lang="PHP">
96,97,98,99,100,101,102,103,999,1000,1001,1002
</pre>
<p>Now the value of “100” isn’t useful, because compressing the stream will get something like this:</p>
<pre lang="PHP">
-4,-3,-2,-1,100,1,2,3,899,900,901,902
</pre>
<p>To group the relative values around “some” base values will be far more handy.</p>
<pre lang="PHP">
(-4,-3,-2,-1,100,1,2,3)(-1,1000,1,2)
</pre>
<p>However to decide which value will be the base value isn’t that easy. Also the encoding format is not so trivial. In the other hand this type of encoding can be useful in som specific cases as we can see bellow.<br />
<span id="more-2658"></span></p>
<h2>Implementation</h2>
<p>The implementation of this algorithm depends on the specific task and the format of the data stream. Assuming that we’ve to transfer the stream of years in JSON from a web server to a browser, here’s a short PHP snippet.</p>
<pre lang="PHP">
// JSON: [1991,1991,1999,1998,1999,1998,1995,1997,1994,1993]
$years = array(1991,1991,1999,1998,1999,1998,1995,1997,1994,1993);

function relative_encoding($input)
{
	$output = array();
	$inputLength = count($input);
	
	$base = $input[0];
	
	$output[] = $base;
	
	for ($i = 1; $i < $inputLength; $i++) {
		$output[] = $input[$i] - $base;
	}
	
	return $output;
}

// JSON: [1991,0,8,7,8,7,4,6,3,2]
echo json_encode(relative_encoding($years));
</pre>
<h2>Application</h2>
<p>This algorithm may be very useful in many cases, but here’s one of them. There are plenty of map applications around the web. Some products as <a href="http://maps.google.com/" title="Google Maps" target="_blank">Google Maps</a>, <a href="http://maps.yahoo.com/" title="Yahoo! Maps" target="_blank">Yahoo! Maps</a>, <a href="http://www.bing.com/maps/" title="Bing Maps" target="_blank">Bing Maps</a> are quite famous, while there are very useful open source projects as <a href="http://www.openstreetmap.org/" title="OpenStreetMap" target="_blank">OpenStreetMap</a>. The web sites using these apps are thousands. </p>
<p>A typical use case is to transfer lots of Geo coordinates from web server to a browser using JSON. Indeed any GEO point on Earth is relative to the point (0,0), which is located near the west coast of Africa, however on large zoom levels, when there are tons of markers we can transfer the information with relative encoding.</p>
<p>For instance the following diagram shows San Francisco with some markers on it. Their coordinates are be relative to the point (0,0) on Earth.</p>
<figure id="attachment_2682" style="width: 819px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/01/FullLatLononSanFrancisco.png"><img src="/wp-content/uploads/2012/01/FullLatLononSanFrancisco.png" alt="San Francisco map with full lat and lon markers" title="FullLatLononSanFrancisco" width="819" height="456" class="size-full wp-image-2682" srcset="/wp-content/uploads/2012/01/FullLatLononSanFrancisco.png 819w, /wp-content/uploads/2012/01/FullLatLononSanFrancisco-300x167.png 300w" sizes="(max-width: 819px) 100vw, 819px" /></a><figcaption class="wp-caption-text">Map markers can be relative to the (0, 0) point on Earth, which can be sometimes useless.</figcaption></figure>
<p>Far more useful may be to encode those markers, relative to the center of the city, thus we can save some space.</p>
<figure id="attachment_2681" style="width: 819px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/01/SanFranciscoMap.png"><img src="/wp-content/uploads/2012/01/SanFranciscoMap.png" alt="San Francisco map with relative encoded markers" title="SanFranciscoMap" width="819" height="456" class="size-full wp-image-2681" srcset="/wp-content/uploads/2012/01/SanFranciscoMap.png 819w, /wp-content/uploads/2012/01/SanFranciscoMap-300x167.png 300w" sizes="(max-width: 819px) 100vw, 819px" /></a><figcaption class="wp-caption-text">Relative encoding can be useful for map markers on large zoom level!</figcaption></figure>
<p>However this type of compression can be tricky, for example when dragging the map and updating the marker array. In the other hand we must group markers if we have to load more than one city. That’s why we must be careful when implementing it. But in the other hand it can be very useful - for instance on initial load of the map we can reduce data and speed up the load time. </p>
<p>The thing is that with relative encoding we can save only changes to base value (data) - something like version control systems and thus reducing data transfer and load. Here's a graphical example. In the first case on the diagram bellow we can see that each item is stored on its own. It doesn't depend on the adjacent items and it can be completely independent of them.</p>
<figure id="attachment_2694" style="width: 600px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/01/chart_11.png"><img src="/wp-content/uploads/2012/01/chart_11.png" alt="Non-relative encoding" title="Non-relative encoding" width="600" height="371" class="size-full wp-image-2694" srcset="/wp-content/uploads/2012/01/chart_11.png 600w, /wp-content/uploads/2012/01/chart_11-300x185.png 300w" sizes="(max-width: 600px) 100vw, 600px" /></a><figcaption class="wp-caption-text"> </figcaption></figure>
<p>However we can keep full info only for the first item and any other item will be relative to it, like on the diagram bellow.</p>
<figure id="attachment_2695" style="width: 600px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/01/chart_21.png"><img src="/wp-content/uploads/2012/01/chart_21.png" alt="Relative encoding" title="Relative encoding" width="600" height="371" class="size-full wp-image-2695" srcset="/wp-content/uploads/2012/01/chart_21.png 600w, /wp-content/uploads/2012/01/chart_21-300x185.png 300w" sizes="(max-width: 600px) 100vw, 600px" /></a><figcaption class="wp-caption-text"> </figcaption></figure>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2012/01/09/computer-algorithms-data-compression-with-run-length-encoding/" rel="bookmark" title="Computer Algorithms: Data Compression with Run-length Encoding">Computer Algorithms: Data Compression with Run-length Encoding </a></li>
<li><a href="/2012/02/06/computer-algorithms-data-compression-with-prefix-encoding/" rel="bookmark" title="Computer Algorithms: Data Compression with Prefix Encoding">Computer Algorithms: Data Compression with Prefix Encoding </a></li>
<li><a href="/2012/01/16/computer-algorithms-data-compression-with-bitmaps/" rel="bookmark" title="Computer Algorithms: Data Compression with Bitmaps">Computer Algorithms: Data Compression with Bitmaps </a></li>
<li><a href="/2012/01/23/computer-algorithms-data-compression-with-diagram-encoding-and-pattern-substitution/" rel="bookmark" title="Computer Algorithms: Data Compression with Diagram Encoding and Pattern Substitution">Computer Algorithms: Data Compression with Diagram Encoding and Pattern Substitution </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2012/01/30/computer-algorithms-data-compression-with-relative-encoding/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Computer Algorithms: Data Compression with Run-length Encoding</title>
		<link>/2012/01/09/computer-algorithms-data-compression-with-run-length-encoding/</link>
		<comments>/2012/01/09/computer-algorithms-data-compression-with-run-length-encoding/#comments</comments>
		<pubDate>Mon, 09 Jan 2012 09:08:06 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[Algorithmic efficiency]]></category>
		<category><![CDATA[binary search]]></category>
		<category><![CDATA[Bzip2]]></category>
		<category><![CDATA[Data compression]]></category>
		<category><![CDATA[data compression algorithm]]></category>
		<category><![CDATA[data compression algorithms]]></category>
		<category><![CDATA[faster services]]></category>
		<category><![CDATA[Google Inc.]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Lossless data compression]]></category>
		<category><![CDATA[lossless data compression algorithm]]></category>
		<category><![CDATA[Lossy compression]]></category>
		<category><![CDATA[programmer]]></category>
		<category><![CDATA[run-length algorithm]]></category>
		<category><![CDATA[Run-length encoding]]></category>
		<category><![CDATA[search algorithms]]></category>
		<category><![CDATA[Technology/Internet]]></category>
		<category><![CDATA[This algorithm]]></category>
		<category><![CDATA[virtual machine]]></category>
		<category><![CDATA[web server]]></category>

		<guid isPermaLink="false">/?p=2594</guid>
		<description><![CDATA[Introduction No matter how fast today&#8217;s computers and networks are, the users will constantly need faster and faster services. To reduce the volume of the transferred data we usually use some sort of compression. That is why this computer sciences area will be always interesting to research and develop. There are many data compression algorithms, &#8230; <a href="/2012/01/09/computer-algorithms-data-compression-with-run-length-encoding/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Data Compression with Run-length Encoding</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2012/05/03/computer-algorithms-lossy-image-compression-with-run-length-encoding/" rel="bookmark" title="Computer Algorithms: Lossy Image Compression with Run-Length Encoding">Computer Algorithms: Lossy Image Compression with Run-Length Encoding </a></li>
<li><a href="/2012/01/30/computer-algorithms-data-compression-with-relative-encoding/" rel="bookmark" title="Computer Algorithms: Data Compression with Relative Encoding">Computer Algorithms: Data Compression with Relative Encoding </a></li>
<li><a href="/2012/01/16/computer-algorithms-data-compression-with-bitmaps/" rel="bookmark" title="Computer Algorithms: Data Compression with Bitmaps">Computer Algorithms: Data Compression with Bitmaps </a></li>
<li><a href="/2012/01/23/computer-algorithms-data-compression-with-diagram-encoding-and-pattern-substitution/" rel="bookmark" title="Computer Algorithms: Data Compression with Diagram Encoding and Pattern Substitution">Computer Algorithms: Data Compression with Diagram Encoding and Pattern Substitution </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>No matter how fast today&#8217;s computers and networks are, the users will constantly need faster and faster services. To reduce the volume of the transferred data we usually use some sort of compression. That is why this computer sciences area will be always interesting to research and develop.</p>
<p>There are many data compression algorithms, some of them lossless, others lossy, but their main goal aways will be to spare storage space and traffic. These algorithms are very useful when talking about data transfer between two distant places. Perhaps the best example is the transfer between a web server and a browser.</p>
<p>In the last few years a lot of research has been done on compressing files, executed on the client side. Such files are javascript, css, htmls and images. In fact servers and clients already have some techniques to compress data, like using <a href="http://www.gzip.org/" title="The gzip home page" target="_blank">GZIP</a> for instance, that can dramatically decrease the transfer. In the other hand there are lots of tools and tricks in order to decrease the size of the data.</p>
<p>Actually when a file is executed by the client&#8217;s virtual machine, it doesn&#8217;t matter how &#8220;beautifully&#8221; it is formatted from a programmer&#8217;s point of view. Thus the spaces, tabs and the new lines don&#8217;t bring any significant information for the environment. That is why such compressing tools like <a href="http://developer.yahoo.com/yui/compressor/" title="YUI Compressor" target="_blank">YUI Compressor</a>, <a href="http://code.google.com/closure/compiler/" title="Closure Compiler - Google Code" target="_blank">Google Closure Compiler</a>, etc. remove those symbols. Well, they can achieve even more in order to improve the compression rate. In this post I won&#8217;t cover this, but this shows how important data compression algorithms are.</p>
<p>It would be great if we could just compress data with some tool. Unfortunately this is not the case and usually the compression rate depends on the data itself. It is obvious that the choice of data compression algorithm depends mainly on the data and first of all we must explore the data.</p>
<p>Here I&#8217;ll cover one very simple lossless data compression algorithm called &#8220;run-length encoding&#8221; that can be very useful in some cases.</p>
<figure id="attachment_2618" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/01/Run-lengthEncoding1.png"><img src="/wp-content/uploads/2012/01/Run-lengthEncoding1.png" alt="Run-length Encoding" title="Run-length Encoding" width="620" class="size-full wp-image-2618" srcset="/wp-content/uploads/2012/01/Run-lengthEncoding1.png 978w, /wp-content/uploads/2012/01/Run-lengthEncoding1-300x129.png 300w" sizes="(max-width: 978px) 100vw, 978px" /></a><figcaption class="wp-caption-text"> </figcaption></figure>
<h2>Overview</h2>
<p>This algorithm consists of replacing large sequences of repeating data with only one item of this data followed by a counter showing how many times this item is repeated. To become clearer let’s see a string example.</p>
<pre lang="PHP">
aaaaaaaaaabbbaxxxxyyyzyx
</pre>
<p>This string&#8217;s length is <strong>24</strong> and as we can see there are lots of repetitions. Using the run-length algorithm, we replace any run with shorter string followed by a counter.</p>
<pre lang="PHP">
a10b3a1x4y3z1y1x1
</pre>
<p>The length of this string is <strong>17</strong>, which is approximately <strong>70%</strong> of the initial length. <span id="more-2594"></span>Obviously this is not the optimal way to compress the given string. For instance we don&#8217;t need to use the digit “1” when the character is repeated only once. In some cases this approach can increase the length of the initial string which is exactly the opposite of what we need. In this case we’ll get the string bellow.</p>
<pre lang="PHP">
a10b3ax4y3zyx
</pre>
<p>Now the length of the resulting string is <strong>13</strong>, which is <strong>54%</strong> of the initial length! A variation of the example above is not to keep a counter of the repetitions of the character, but their position instead. Thus the initial string will be compressed as follows.</p>
<pre lang="PHP">
a0b10a13x14y18z21y22x23
</pre>
<p>Which of these two approaches you&#8217;ll use depends on the goal. In the second case we can achieve a good optimization of <a href="/2011/12/26/computer-algorithms-binary-search/" title="Computer Algorithms: Binary Search">binary search</a>.</p>
<p>It is clear that this algorithm is not only applicable on strings. We can achieve very good results on arrays. A typical example is the transfer of <a href="http://www.json.org/" title="JSON" target="_blank">JSON</a> from a server to a client. Then if there are large sequences of repeating data we can achieve great results.</p>
<h2>Implementation</h2>
<p>The implementation bellow is assuming that we&#8217;re compressing a string and it&#8217;s written on PHP. However the nature of this algorithm doesn&#8217;t restrict us to use only strings. As I said before with slight modifications we can use it with other data structures. It is important only to understand that the run-length algorithm is very useful on large sequences of repeating elements, no matter characters or array items.</p>
<pre lang="PHP">
$message = 'aaaaaaaaaabbbaxxxxyyyzyx';

function run_length_encode($msg)
{
	$i = $j = 0;
	$prev = '';
	$output = '';
	
	while ($msg[$i]) {
		if ($msg[$i] != $prev) {
			
			if ($i) 
				$output .= $j;
				
			$output .= $msg[$i];
				
			$prev = $msg[$i];
			
			$j = 0;
		}
		$j++;
		$i++;
	}
	
	$output .= $j;
	
	return $output;
}

// a10b3a1x4y3z1y1x1
echo run_length_encode($message);
</pre>
<p>And slightly optimized.</p>
<pre lang="PHP">
$message = 'aaaaaaaaaabbbaxxxxyyyzyx';

function run_length_encode($msg)
{
	$i = $j = 0;
	$prev = '';
	$output = '';
	
	while ($msg[$i]) {
		if ($msg[$i] != $prev) {
			
			if ($i && $j > 1) 
				$output .= $j;
				
			$output .= $msg[$i];
				
			$prev = $msg[$i];
			
			$j = 0;
		}
		$j++;
		$i++;
	}
	
	if ($j > 1)
		$output .= $j;
	
	return $output;
}

// a10b3ax4y3zyx
echo run_length_encode($message);
</pre>
<p>Finally a small change &#8211; now we store the position of the character.</p>
<pre lang="PHP">
$message = 'aaaaaaaaaabbbaxxxxyyyzyx';

function run_length_encode($msg)
{
	$i = 0;
	$prev = '';
	$output = '';
	
	while ($msg[$i]) {
		if ($msg[$i] != $prev) {
				
			$output .= $msg[$i] . $i;
				
			$prev = $msg[$i];
			
		}

		$i++;
	}
	
	return $output;
}

// a0b10a13x14y18z21y22x23
echo run_length_encode($message);
</pre>
<h2>Complexity and Data Compression</h2>
<p>We&#8217;re used to talk about complexity of an algorithm measuring time and we usually try to find the fastest implementation, like in search algorithms. Here it is not so important to compress data quickly, but to compress as much as possible so the output is as small as possible without lossing data. A great feature of run-length encoding is that this algorithm is easy to implement.</p>
<h2>Application</h2>
<p>We can use run-length encoding in many cases. It is commonly used to compress images and is very successful when we deal only with black and white images. Here I&#8217;ll cover another use case that I only mentioned above. Let&#8217;s say we have to transfer a very large array of data to our AJAX-powered application using JSON. Let&#8217;s say also that the data are some years, for instance the years of the premiere of a movie. There are lots of movies with a premiere in the same year, thus although the data is sorted, we actually can&#8217;t have any benefit. More important is that we have large sequences of data. Here we can use run-length encoding.</p>
<pre lang="PHP">
$data = array(
	0 	=> 1991,
	1 	=> 1991,
	...
	2223 	=> 1991,
	2224 	=> 1992,
	...
	19298 	=> 1995,
	19299 	=> 1996,
	...
);
</pre>
<p>As you can see to transfer the whole array can be a nightmare, especially on slow networks. It is better to compress it (i.e. with PHP&#8217;s <a href="http://php.net/manual/en/function.json-encode.php" title="PHP: json_encode" target="_blank">json_encode</a>).</p>
<pre lang="PHP">
// {"0":1991,"1":1991, ..., "2223":1991,"2224":1992, ..., "19298":1995,"19299":1996, ...}
echo json_encode($data);
</pre>
<p>After running run-length encoding we can receive something like the following array (note that these are only sample data and it&#8217;s up to you to decide which is the best format to store data).</p>
<pre lang="PHP">
$data = array(
	0 => array(1991, 2224),
	1 => array(1992, 3948),
	2 => array(1995, 2398),
	3 => array(1996, 3489),
);
</pre>
<p>And the JSON output.</p>
<pre lang="PHP">
// [[1991,2224],[1992,3948],[1995,2398],[1996,3489]]
echo json_encode($data);
</pre>
<p>Note that if the data is sorted we can achieve great success compressing it!!! This approach can be used for images, graphics or map coordinates.</p>
<p>This is only one example of how data compression can be useful in our daily work. Although the communication between the server and the client can be optimized and compressed, we can improve it. In other words we&#8217;re not always sure that the opposite side supports compression.</p>
<p>Well, it&#8217;s true that the client has to decompress the data, which can also be slow. Now in the first case we have only the time to transfer, as on the diagram bellow.</p>
<figure id="attachment_2609" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/01/DataTransferWithoutCompression.png"><img src="/wp-content/uploads/2012/01/DataTransferWithoutCompression.png" alt="Data Transfer Without Compression" title="Data Transfer Without Compression" width="620" class="size-full wp-image-2609" srcset="/wp-content/uploads/2012/01/DataTransferWithoutCompression.png 957w, /wp-content/uploads/2012/01/DataTransferWithoutCompression-300x54.png 300w" sizes="(max-width: 957px) 100vw, 957px" /></a><figcaption class="wp-caption-text">Time to transfer data without compression!</figcaption></figure>
<p>In the second case, we should sum the time for compression, transfer and decompression.</p>
<figure id="attachment_2610" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/01/DataTransferwithCompression.png"><img src="/wp-content/uploads/2012/01/DataTransferwithCompression.png" alt="Data Transfer with Compression" title="Data Transfer with Compression" width="620" class="size-full wp-image-2610" srcset="/wp-content/uploads/2012/01/DataTransferwithCompression.png 953w, /wp-content/uploads/2012/01/DataTransferwithCompression-300x59.png 300w" sizes="(max-width: 953px) 100vw, 953px" /></a><figcaption class="wp-caption-text">Time to send data with compression!</figcaption></figure>
<p>All this is important, but in general data compression can be handy in many cases in our daily work. </p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2012/05/03/computer-algorithms-lossy-image-compression-with-run-length-encoding/" rel="bookmark" title="Computer Algorithms: Lossy Image Compression with Run-Length Encoding">Computer Algorithms: Lossy Image Compression with Run-Length Encoding </a></li>
<li><a href="/2012/01/30/computer-algorithms-data-compression-with-relative-encoding/" rel="bookmark" title="Computer Algorithms: Data Compression with Relative Encoding">Computer Algorithms: Data Compression with Relative Encoding </a></li>
<li><a href="/2012/01/16/computer-algorithms-data-compression-with-bitmaps/" rel="bookmark" title="Computer Algorithms: Data Compression with Bitmaps">Computer Algorithms: Data Compression with Bitmaps </a></li>
<li><a href="/2012/01/23/computer-algorithms-data-compression-with-diagram-encoding-and-pattern-substitution/" rel="bookmark" title="Computer Algorithms: Data Compression with Diagram Encoding and Pattern Substitution">Computer Algorithms: Data Compression with Diagram Encoding and Pattern Substitution </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2012/01/09/computer-algorithms-data-compression-with-run-length-encoding/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Adding a Custom Button to TinyMCE</title>
		<link>/2011/02/16/adding-a-custom-button-to-tinymce/</link>
		<comments>/2011/02/16/adding-a-custom-button-to-tinymce/#comments</comments>
		<pubDate>Wed, 16 Feb 2011 08:31:04 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[micro tutorial]]></category>
		<category><![CDATA[CKEditor]]></category>
		<category><![CDATA[Computer programming]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[editor]]></category>
		<category><![CDATA[FCKEditor]]></category>
		<category><![CDATA[Google Inc.]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[JavaScript programming language]]></category>
		<category><![CDATA[online based editor]]></category>
		<category><![CDATA[opinion]]></category>
		<category><![CDATA[Software engineering]]></category>
		<category><![CDATA[TinyMCE]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[WYSIWYG]]></category>
		<category><![CDATA[yahoo]]></category>

		<guid isPermaLink="false">/?p=2176</guid>
		<description><![CDATA[TinyMCE First thing to say TinyMCE is a very popular WYSIWYG online based editor. It&#8217;s very widely used in the web, as may already know it it&#8217;s part of the default WordPress installation. Out of the web, of course, there are some other editors as well. The most used and well developed projects are the &#8230; <a href="/2011/02/16/adding-a-custom-button-to-tinymce/" class="more-link">Continue reading <span class="screen-reader-text">Adding a Custom Button to TinyMCE</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2011/02/17/adding-a-custom-button-to-tinymce-revised/" rel="bookmark" title="Adding a Custom Button to TinyMCE &#8211; REVISED">Adding a Custom Button to TinyMCE &#8211; REVISED </a></li>
<li><a href="/2010/01/31/speed-up-the-javascript-it-can-change-dramatically-the-user-experience/" rel="bookmark" title="Speed up the JavaScript. It can change dramatically the user experience.">Speed up the JavaScript. It can change dramatically the user experience. </a></li>
<li><a href="/2010/02/11/javascript-optimization-lazy-loading/" rel="bookmark" title="JavaScript optimization. Lazy loading.">JavaScript optimization. Lazy loading. </a></li>
<li><a href="/2011/04/05/jquery-unbind/" rel="bookmark" title="jQuery.unbind()">jQuery.unbind() </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>TinyMCE</h2>
<p>First thing to say <a title="TinyMCE Homepage" href="http://tinymce.moxiecode.com/" target="_blank">TinyMCE</a> is a very popular <a title="WYSIWYG Wikipedia page" href="http://en.wikipedia.org/wiki/WYSIWYG" target="_blank">WYSIWYG</a> online based editor. It&#8217;s very widely used in the web, as may already know it it&#8217;s part of the default WordPress installation. Out of the web, of course, there are some other editors as well. The most used and well developed projects are the <a title="YUI 2 Rich Text Editor Homepage" href="http://developer.yahoo.com/yui/editor/" target="_blank">Yahoo!&#8217;s YUI 2 Rich Text Editor</a> and <a title="CKEditor Homepage" href="http://ckeditor.com/" target="_blank">CKEditor</a> also known with his past name &#8211; FCKEditor.<a href="/wp-content/uploads/2011/02/TinyMCE_Full_Featured.png"><img class="aligncenter size-full wp-image-2206" title="TinyMCE_Full_Featured" src="/wp-content/uploads/2011/02/TinyMCE_Full_Featured.png" alt="TinyMCE Full Featured Example" width="640" height="528" srcset="/wp-content/uploads/2011/02/TinyMCE_Full_Featured.png 640w, /wp-content/uploads/2011/02/TinyMCE_Full_Featured-300x247.png 300w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>
<p>Before I proceed with this post, let me say that I&#8217;m working and this tutorial is based on <strong>version 3.1.1</strong> released on <strong>18 Aug 2008</strong>.<span id="more-2176"></span></p>
<h2>Including TinyMCE</h2>
<p>The only thing you&#8217;ve to do is to include a TinyMCE javascript file and write a simple init. The examples of installing it come with the compressed version of the javascript file:</p>
<pre lang="html4strict">
<script src="/scripts/tinymce/jscripts/tiny_mce/tiny_mce.js"></script>
<script>
tinyMCE.init({
	mode : "textareas",
	theme : "advanced",
	force_br_newlines : true,
	theme_advanced_buttons1 : "link,unlink,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|",
	theme_advanced_buttons2 : "",
	theme_advanced_buttons3 : "",
	theme_advanced_buttons4 : "",
	theme_advanced_toolbar_location : "top",
	theme_advanced_toolbar_align : "left",
	theme_advanced_statusbar_location : "",
	theme_advanced_resizing : true
});
</script>
</pre>
<p>The result of this code is shown on the picture:</p>
<p><a href="/wp-content/uploads/2011/02/TinyMCE_Before.png"><img class="aligncenter size-full wp-image-2207" title="TinyMCE_Before" src="/wp-content/uploads/2011/02/TinyMCE_Before.png" alt="TinyMCE Before" width="653" height="313" srcset="/wp-content/uploads/2011/02/TinyMCE_Before.png 653w, /wp-content/uploads/2011/02/TinyMCE_Before-300x143.png 300w" sizes="(max-width: 653px) 100vw, 653px" /></a></p>
<p>However for this tutorial you&#8217;ve to include the uncompressed file, because the compressed one is impossible to read and modify. At the end of all this you can compress yet again the resulting file with some js compressor as <a title="YUI Compressor Homepage" href="http://developer.yahoo.com/yui/compressor/" target="_blank">YUI Compressor</a>, <a title="JSMin" href="http://www.crockford.com/javascript/jsmin.html" target="_blank">JSMin</a> or <a title="Google Closure Compiler Homepage" href="http://code.google.com/closure/compiler/" target="_blank">Google Closure Compiler</a>. So instead of including the file above, you&#8217;ve to include the _src version as it is:</p>
<pre lang="html4strict">
<script src="/scripts/tinymce/jscripts/tiny_mce/tiny_mce_src.js"></script>
</pre>
<h2>Adding the Button</h2>
<p>Now there is a small configuration object passed to the init function. First you&#8217;ve to modify it a bit:</p>
<pre lang="javascript">
tinyMCE.init({
	mode : "textareas",
	theme : "advanced",
	force_br_newlines : true,
	theme_advanced_buttons1 : "link,unlink,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,mybutton",
	theme_advanced_buttons2 : "",
	theme_advanced_buttons3 : "",
	theme_advanced_buttons4 : "",
	theme_advanced_toolbar_location : "top",
	theme_advanced_toolbar_align : "left",
	theme_advanced_statusbar_location : "",
	theme_advanced_resizing : true
});
</pre>
<p>Usually in the /tinymce/jscripts/tiny_mce/themes/advanced/editor_template_src.js file there are some buttons described:</p>
<pre lang="javascript">
tinymce.create('tinymce.themes.AdvancedTheme', {
	// Control name lookup, format: title, command
	controls : {
		bold : ['bold_desc', 'Bold'],
		italic : ['italic_desc', 'Italic'],
		underline : ['underline_desc', 'Underline'],
		strikethrough : ['striketrough_desc', 'Strikethrough'],
		justifyleft : ['justifyleft_desc', 'JustifyLeft'],
		justifycenter : ['justifycenter_desc', 'JustifyCenter'],
		justifyright : ['justifyright_desc', 'JustifyRight'],
		justifyfull : ['justifyfull_desc', 'JustifyFull'],
		bullist : ['bullist_desc', 'InsertUnorderedList'],
		numlist : ['numlist_desc', 'InsertOrderedList'],
		outdent : ['outdent_desc', 'Outdent'],
		indent : ['indent_desc', 'Indent'],
...
</pre>
<p>What you need to do is simply to add a new line to this config array:</p>
<pre lang="javascript">
...
        blockquote : ['blockquote_desc', 'mceBlockQuote'],
	mybutton : ['mybutton_desc','myFunc']
},
</pre>
<p>That&#8217;s not enough of course! Now TinyMCE sees this definition, but nothing happens. It cannot build the new button yet. What&#8217;s next?</p>
<h2>Styling the Button</h2>
<p>After giving the new button a name, TinyMCE constructs a markup with the given name into the controlbar:</p>
<p><a href="/wp-content/uploads/2011/02/TinyMCE_Button_Step-_1.png"><img class="aligncenter size-full wp-image-2208" title="TinyMCE_Button_Step _1" src="/wp-content/uploads/2011/02/TinyMCE_Button_Step-_1.png" alt="TinyMCE Button Step 1" width="654" height="315" srcset="/wp-content/uploads/2011/02/TinyMCE_Button_Step-_1.png 654w, /wp-content/uploads/2011/02/TinyMCE_Button_Step-_1-300x144.png 300w" sizes="(max-width: 654px) 100vw, 654px" /></a></p>
<pre lang="html4strict">
<td>
	<a title="advanced.mybutton_desc" onclick="return false;" onmousedown="return false;" class="mceButton mceButtonEnabled mce_mybutton" href="javascript:;" id="mce_0_mybutton">
		<span class="mceIcon mce_mybutton"></span>
	</a>
</td>
</pre>
<p>This name can be simply used in the CSS file (/tinymce/jscripts/tiny_mce/themes/advanced/skins/default/ui.css) to style the button. Because TinyMCE uses sprite for its background images, you can copy/paste the style from some other button and than adjust the background position, only after you&#8217;ve added the new icon to the sprite. Here&#8217;s simply a copy of the style from another button:</p>
<pre lang="css">
...
.defaultSkin span.mce_numlist {background-position:-80px 0}
.defaultSkin span.mce_mybutton {background-position:-460px 0}
.defaultSkin span.mce_justifyleft {background-position:-460px 0}
...
</pre>
<p>You can see how the button appears in the control bar!</p>
<p><a href="/wp-content/uploads/2011/02/TinyMCE_Button_Step_2.png"><img class="aligncenter size-full wp-image-2209" title="TinyMCE_Button_Step_2" src="/wp-content/uploads/2011/02/TinyMCE_Button_Step_2.png" alt="TinyMCE Button Step 2" width="655" height="313" srcset="/wp-content/uploads/2011/02/TinyMCE_Button_Step_2.png 655w, /wp-content/uploads/2011/02/TinyMCE_Button_Step_2-300x143.png 300w" sizes="(max-width: 655px) 100vw, 655px" /></a></p>
<h2>Binding the Button</h2>
<p>The final job to do is to bind the button with some action. This thing happens again in /tinymce/jscripts/tiny_mce/themes/advanced/editor_template_src.js. You just have to search for other bindings &#8211; let&#8217;s say mceCleanup. There you can write your new function &#8211; myFunc:</p>
<pre lang="javascript">
FormatBlock : function(ui, val) {
	...
},

myFunc : function() {
	this.editor.selection.setContent('Hello World!');
},

mceCleanup : function() {
	...
},
</pre>
<p>Now after clicking the button the method will be executed. <a href="/wp-content/uploads/2011/02/TinyMCE_Button_Step_3.png"><img class="aligncenter size-full wp-image-2210" title="TinyMCE_Button_Step_3" src="/wp-content/uploads/2011/02/TinyMCE_Button_Step_3.png" alt="TinyMCE Button Step 3" width="653" height="312" srcset="/wp-content/uploads/2011/02/TinyMCE_Button_Step_3.png 653w, /wp-content/uploads/2011/02/TinyMCE_Button_Step_3-300x143.png 300w" sizes="(max-width: 653px) 100vw, 653px" /></a></p>
<p>Note that the name of the method should be exactly the same as described in the controls array in /tinymce/jscripts/tiny_mce/themes/advanced/editor_template_src.js. If not the button wont work ever.</p>
<h2>Final Steps</h2>
<p>Now you&#8217;ve to compress (if you wish) the js files and deploy your editor.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2011/02/17/adding-a-custom-button-to-tinymce-revised/" rel="bookmark" title="Adding a Custom Button to TinyMCE &#8211; REVISED">Adding a Custom Button to TinyMCE &#8211; REVISED </a></li>
<li><a href="/2010/01/31/speed-up-the-javascript-it-can-change-dramatically-the-user-experience/" rel="bookmark" title="Speed up the JavaScript. It can change dramatically the user experience.">Speed up the JavaScript. It can change dramatically the user experience. </a></li>
<li><a href="/2010/02/11/javascript-optimization-lazy-loading/" rel="bookmark" title="JavaScript optimization. Lazy loading.">JavaScript optimization. Lazy loading. </a></li>
<li><a href="/2011/04/05/jquery-unbind/" rel="bookmark" title="jQuery.unbind()">jQuery.unbind() </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2011/02/16/adding-a-custom-button-to-tinymce/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Few Thoughts on Web Video</title>
		<link>/2011/01/27/few-thoughts-on-web-video/</link>
		<comments>/2011/01/27/few-thoughts-on-web-video/#comments</comments>
		<pubDate>Thu, 27 Jan 2011 09:19:00 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[micro tutorial]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[Adobe Flash]]></category>
		<category><![CDATA[Application software]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Container formats]]></category>
		<category><![CDATA[FFmpeg]]></category>
		<category><![CDATA[Flash Video]]></category>
		<category><![CDATA[Google Inc.]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[M&A]]></category>
		<category><![CDATA[MPEG-4]]></category>
		<category><![CDATA[Ogg]]></category>
		<category><![CDATA[On2 Technologies]]></category>
		<category><![CDATA[On2 Technologies Inc]]></category>
		<category><![CDATA[player]]></category>
		<category><![CDATA[Plex]]></category>
		<category><![CDATA[Technology/Internet]]></category>
		<category><![CDATA[Theora]]></category>
		<category><![CDATA[Video codecs]]></category>
		<category><![CDATA[VP8]]></category>
		<category><![CDATA[web video field]]></category>

		<guid isPermaLink="false">/?p=2145</guid>
		<description><![CDATA[On Air It&#8217;s really full of video sharing websites out there, but in fact almost all of them use Flash player to display their video files. This is the reality now, but with the coming of HTML5, perhaps the things are changing a bit! First of all if you start dealing with video sharing platforms &#8230; <a href="/2011/01/27/few-thoughts-on-web-video/" class="more-link">Continue reading <span class="screen-reader-text">Few Thoughts on Web Video</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2010/03/05/video-sites-must-use-mp4-and-only-mp4/" rel="bookmark" title="Video sites must use &#8230; mp4 and only mp4!">Video sites must use &#8230; mp4 and only mp4! </a></li>
<li><a href="/2010/03/04/does-firefox-play-mp4-h-264-within-the-html5-video-tag/" rel="bookmark" title="Does Firefox play mp4 h.264 within the HTML5 video tag?">Does Firefox play mp4 h.264 within the HTML5 video tag? </a></li>
<li><a href="/2010/11/12/how-to-make-mp4-progressive-with-qt-faststart/" rel="bookmark" title="How to Make MP4 Progressive with qt-faststart">How to Make MP4 Progressive with qt-faststart </a></li>
<li><a href="/2011/02/04/reading-gps-latitude-and-longitude-from-image-and-video-files/" rel="bookmark" title="Reading GPS Latitude and Longitude from Image and Video Files">Reading GPS Latitude and Longitude from Image and Video Files </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>On Air</h2>
<p><a href="/wp-content/uploads/2011/01/975857_64336474.jpg"><img src="/wp-content/uploads/2011/01/975857_64336474.jpg" alt="" title="Few Thoughts on Web Video" width="450" height="368" class="alignleft size-full wp-image-2156" srcset="/wp-content/uploads/2011/01/975857_64336474.jpg 450w, /wp-content/uploads/2011/01/975857_64336474-300x245.jpg 300w" sizes="(max-width: 450px) 100vw, 450px" /></a><br />
It&#8217;s really full of video sharing websites out there, but in fact almost all of them use Flash player to display their video files. This is the reality now, but with the coming of HTML5, perhaps the things are changing a bit!</p>
<p>First of all if you start dealing with video sharing platforms the first thing to do maybe is to find a good Flash (.flv) player and to convert all your video content in FLV.</p>
<p>Few things to know with Flash video players:</p>
<ol>
<li>The user can play those videos only after installing the Flash Plugin to his browser;</li>
<li>The video must be encoded either in FLV (or FLash Video) or in MPEG-4 with h.264 codec. Only than the Flash player can play it;</li>
</ol>
<p>The HTML5, which can be described as variety of new &#8220;things&#8221; in the HTML comes with a native &lt;video&gt; tag. Something like the &lt;img&gt; tag where you can just point the source of the image in the src attribute.<span id="more-2145"></span></p>
<h2>First Question &#8211; How Does it Look Like?</h2>
<p>To get more fluent with the &lt;video&gt; tag you must simply thing of it as a &#8220;complex&#8221; &lt;img&gt; tag. You just point to the video and the browser will do the rest. To be more exact let me send you to the <a title="HTML5 Video" href="http://www.w3schools.com/html5/html5_video.asp" target="_blank">w3schools page</a>, but the important thing as they say:</p>
<blockquote><p>Until now, there has never been a standard for showing video on a web  page.</p></blockquote>
<p>However to start from somewhere here&#8217;s a little snippet showing you the basic, but very basic usage of the HTML5 video tag:</p>
<pre lang="html4stict" escaped="true">
&lt;video src="path_to_the_video" controls="controls"&gt;&lt;/video&gt;
</pre>
<h2>Second Question &#8211; Is Every Video Playable?</h2>
<p>But of course not! There are different browser &#8211; different video formats. Currently there are three formats, supported by the different browsers.</p>
<ol>
<li>H.264</li>
<li>VP8</li>
<li>Theora</li>
</ol>
<p>Note that these are <span style="text-decoration: underline;">video</span> codecs and a video files does not consists of only a video codec, but also of an audio codec. This makes the video file a container of several things. As you may know already H.264 is used with MPEG-4 video format, which results in .mp4 extended files, Theora is used in OGG, which are all those .ogg files out in the web, and finaly VP8 is used in WebM &#8230; or in .webm videos.</p>
<p>First thing to know FLV files (.flv) can also be encoded with H.264. Actually Flash player has a h.264 decoder so this makes it possible to play both .mp4 and .flv files encoded with H.264.</p>
<p>Second thing to notice &#8211; where are those .webm files? I&#8217;ve never seen them!</p>
<h2>Third Question &#8211; What is WebM and VP8?</h2>
<p>Behind <a title="The WebM Project" href="http://www.webmproject.org/" target="_blank">WebM</a> and VP8 is Google. This is a new video format based again on Theora. Actually it pretends to be as good in compressing as H.264, which by the way is meant to be the best. But let me take a look at <a title="The state of the video on the web" href="http://net.tutsplus.com/articles/the-state-of-video-on-the-web/" target="_blank">Nettuts+</a>:</p>
<blockquote><p>VP8, a relatively new codec, is the brainchild of On2 — the same guys  behind Theora. Google acquired On2 in 2010, and opened up all the  underlying patents for the codec into the public domain.</p>
<p>WebM, the container of choice for most current browsers, utilizes VP8  for compressing its video content and Vorbis for its audio. It produces  content similar in quality to H.264.</p>
<p>It is completely royalty free, now and for the future. On the  downside, though, it has limited hardware decoding support as well as  third party device/mobile support.</p></blockquote>
<h2>Final Question &#8211; How Can I Convert a Video in WebM?</h2>
<p>This answer is given by <a title="FFMPEG and WebM" href="http://paulrouget.com/e/funwithwebm" target="_blank">this article</a>, where as it is said after having the ffmpeg version &gt;= 0.6 you simply can use this command:</p>
<pre lang="bash">ffmpeg -i girltalk.mp4 -f webm -vcodec libvpx -acodec libvorbis -aq 90 -ac 2 girltalk.webm
</pre>
<h2>Conclusion</h2>
<p>It&#8217;s interesting to see what will happen one day. There is going to be either a harmonious life in the web video field or the codecs/formats will be as much as the browser? Who knows?</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2010/03/05/video-sites-must-use-mp4-and-only-mp4/" rel="bookmark" title="Video sites must use &#8230; mp4 and only mp4!">Video sites must use &#8230; mp4 and only mp4! </a></li>
<li><a href="/2010/03/04/does-firefox-play-mp4-h-264-within-the-html5-video-tag/" rel="bookmark" title="Does Firefox play mp4 h.264 within the HTML5 video tag?">Does Firefox play mp4 h.264 within the HTML5 video tag? </a></li>
<li><a href="/2010/11/12/how-to-make-mp4-progressive-with-qt-faststart/" rel="bookmark" title="How to Make MP4 Progressive with qt-faststart">How to Make MP4 Progressive with qt-faststart </a></li>
<li><a href="/2011/02/04/reading-gps-latitude-and-longitude-from-image-and-video-files/" rel="bookmark" title="Reading GPS Latitude and Longitude from Image and Video Files">Reading GPS Latitude and Longitude from Image and Video Files </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2011/01/27/few-thoughts-on-web-video/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Google Analytics for Nokia &#8230; and Mobiles</title>
		<link>/2011/01/21/google-analytics-for-nokia-and-mobiles/</link>
		<comments>/2011/01/21/google-analytics-for-nokia-and-mobiles/#comments</comments>
		<pubDate>Fri, 21 Jan 2011 10:08:19 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[web development]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Economy of Finland]]></category>
		<category><![CDATA[Google Analytics]]></category>
		<category><![CDATA[Google Inc.]]></category>
		<category><![CDATA[Nokia]]></category>
		<category><![CDATA[Nokia E71 Smartphone]]></category>
		<category><![CDATA[Ovi]]></category>
		<category><![CDATA[Smartphones]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Technology/Internet]]></category>
		<category><![CDATA[tiny web app]]></category>

		<guid isPermaLink="false">/?p=2136</guid>
		<description><![CDATA[Is There an Analytics Interface for Mobile? The last few months I was searching about some kind of mobile interface of Google Analytics for my Nokia e71. However I did not find one?! Please correct me if I&#8217;m wrong. In the same time I knew there is a GA API, which is free to use, &#8230; <a href="/2011/01/21/google-analytics-for-nokia-and-mobiles/" class="more-link">Continue reading <span class="screen-reader-text">Google Analytics for Nokia &#8230; and Mobiles</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2010/01/18/google-closure-compiler/" rel="bookmark" title="Google Closure Compiler?">Google Closure Compiler? </a></li>
<li><a href="/2010/01/20/google-closure-compiler-doesnt-work/" rel="bookmark" title="Google Closure Compiler doesn&#8217;t work?!">Google Closure Compiler doesn&#8217;t work?! </a></li>
<li><a href="/2010/03/16/retrieving-youtube-channels-videos-with-zend_gdata_youtube/" rel="bookmark" title="Retrieving YouTube Channel&#8217;s Videos with Zend_Gdata_YouTube">Retrieving YouTube Channel&#8217;s Videos with Zend_Gdata_YouTube </a></li>
<li><a href="/2010/03/10/change-the-viewport-be-ready-for-the-iphone/" rel="bookmark" title="Change the Viewport, be Ready for the iPhone!">Change the Viewport, be Ready for the iPhone! </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Is There an Analytics Interface for Mobile?</h2>
<p>The last few months I was searching about some kind of mobile interface of Google Analytics for my Nokia e71. However I did not find one?! Please correct me if I&#8217;m wrong.</p>
<p>In the same time I knew there is a GA API, which is free to use, so finally I wrote a tiny web app allowing the reading of basic information about your Google Analytics accounts.<a href="/wp-content/uploads/2011/01/nokia.jpg"><img class="alignleft size-full wp-image-2149" title="nokia" src="/wp-content/uploads/2011/01/nokia.jpg" alt="" width="430" height="322" srcset="/wp-content/uploads/2011/01/nokia.jpg 430w, /wp-content/uploads/2011/01/nokia-300x224.jpg 300w" sizes="(max-width: 430px) 100vw, 430px" /></a></p>
<p><em>Note that your username and password are <strong>NOT SAVED!</strong> However it&#8217;s up to you to try. </em></p>
<p>An important note is that the API has a limitation in requests so yet again, it&#8217;s possible to be unavailable in case of too many requests.</p>
<h2>Visit with Your Mobile Browser</h2>
<p>this link:</p>
<p><a title="Google Analytics for Nokia and Mobile Phones" href="http://www.stoimen.com/ga/" target="_blank">http://www.stoimen.com/ga/</a></p>
<p>Note that I made it primary about my Nokia, so any screenshots will be welcomed as well.</p>
<p>It is still beta so be careful. In fact any suggestions are welcome. Either for improving the security and error handling as well as new data exports.</p>
<p>There are lots of things to be done, but this is really basic.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2010/01/18/google-closure-compiler/" rel="bookmark" title="Google Closure Compiler?">Google Closure Compiler? </a></li>
<li><a href="/2010/01/20/google-closure-compiler-doesnt-work/" rel="bookmark" title="Google Closure Compiler doesn&#8217;t work?!">Google Closure Compiler doesn&#8217;t work?! </a></li>
<li><a href="/2010/03/16/retrieving-youtube-channels-videos-with-zend_gdata_youtube/" rel="bookmark" title="Retrieving YouTube Channel&#8217;s Videos with Zend_Gdata_YouTube">Retrieving YouTube Channel&#8217;s Videos with Zend_Gdata_YouTube </a></li>
<li><a href="/2010/03/10/change-the-viewport-be-ready-for-the-iphone/" rel="bookmark" title="Change the Viewport, be Ready for the iPhone!">Change the Viewport, be Ready for the iPhone! </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2011/01/21/google-analytics-for-nokia-and-mobiles/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Diving into Node.js &#8211; Introduction &#038; Installation</title>
		<link>/2010/11/16/diving-into-node-js-introduction-and-installation/</link>
		<comments>/2010/11/16/diving-into-node-js-introduction-and-installation/#comments</comments>
		<pubDate>Tue, 16 Nov 2010 08:17:32 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[web development]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[Apache Corporation]]></category>
		<category><![CDATA[Apache HTTP Server]]></category>
		<category><![CDATA[application/server]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[classical chat server]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Google Chrome]]></category>
		<category><![CDATA[Google Inc.]]></category>
		<category><![CDATA[Inter-process communication]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[JavaScript programming language]]></category>
		<category><![CDATA[Node.js]]></category>
		<category><![CDATA[normal server]]></category>
		<category><![CDATA[normal web server]]></category>
		<category><![CDATA[operating system]]></category>
		<category><![CDATA[Push technology]]></category>
		<category><![CDATA[Server-side JavaScript]]></category>
		<category><![CDATA[Software engineering]]></category>
		<category><![CDATA[Technology/Internet]]></category>
		<category><![CDATA[typical web server]]></category>
		<category><![CDATA[Web browser]]></category>
		<category><![CDATA[web developer team]]></category>
		<category><![CDATA[web server]]></category>
		<category><![CDATA[web server example]]></category>
		<category><![CDATA[web serving functionality]]></category>
		<category><![CDATA[World Wide Web]]></category>

		<guid isPermaLink="false">/?p=2037</guid>
		<description><![CDATA[Why I Need Something Like Node.js? First of all the use of some software is needed not because of itself, but because of the need of some specific functionality. In my case this was the need of real time news feed. Of course there is a way to make this without Node.js, as I&#8217;ll describe &#8230; <a href="/2010/11/16/diving-into-node-js-introduction-and-installation/" class="more-link">Continue reading <span class="screen-reader-text">Diving into Node.js &#8211; Introduction &#038; Installation</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2010/12/02/diving-into-node-js-a-long-polling-example/" rel="bookmark" title="Diving into Node.js &#8211; A Long Polling Example">Diving into Node.js &#8211; A Long Polling Example </a></li>
<li><a href="/2010/11/19/diving-into-node-js-very-first-app/" rel="bookmark" title="Diving into Node.js &#8211; Very First App">Diving into Node.js &#8211; Very First App </a></li>
<li><a href="/2010/01/31/speed-up-the-javascript-it-can-change-dramatically-the-user-experience/" rel="bookmark" title="Speed up the JavaScript. It can change dramatically the user experience.">Speed up the JavaScript. It can change dramatically the user experience. </a></li>
<li><a href="/2010/01/11/what-should-be-optimized-in-one-web-page/" rel="bookmark" title="What should be optimized in one web page?">What should be optimized in one web page? </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Why I Need Something Like Node.js?</h2>
<p>First of all the use of some software is needed not because of itself, but because of the need of some specific functionality. In my case this was the need of real time news feed. Of course there is a way to make this without <a title="Node.js" href="http://nodejs.org/" target="_blank">Node.js</a>, as I&#8217;ll describe later in this post, but there are several disadvantages. However to begin from somewhere, let me explain what is Node.js.</p>
<h2>Introducing Node.js</h2>
<p>Perhaps the best way do describe what is Node.js is from its <a title="Node.js" href="http://nodejs.org/#about" target="_blank">about page</a>.</p>
<blockquote><p>Node&#8217;s goal is to provide an easy way to build scalable network programs. In the &#8220;hello world&#8221; web server example above, many client connections can be handled concurrently. Node tells the operating system (through epoll, kqueue, /dev/poll, or select) that it should be notified when a new connection is made, and then it goes to sleep. If someone new connects, then it executes the callback. Each connection is only a small heap allocation.</p>
<p>&#8230;</p></blockquote>
<p>In general Node is a program using the Google Chrome&#8217;s <a title="V8 JavaScript engine" href="http://code.google.com/p/v8/" target="_blank">V8 JavaScript</a> engine, which in turn is a program that can parse and execute code written in JavaScript. V8 is a very very interesting project itself. First of all from Google have developed this engine especially for one of his products &#8211; their browser <a title="Google Chrome" href="http://www.google.com/chrome" target="_blank">Chrome</a>. It pretends to be and by no means is one of the masterpieces of Google. It is fast and reliable engine, written in C++ and JavaScript, as <a title="V8 JavaScript engine on Wikipedia" href="http://en.wikipedia.org/wiki/V8_%28JavaScript_engine%29" target="_blank">Wikipedia&#8217;s page</a> says. Actually this code is open source and can be embedded in whatever application written in C++. Thus you can have in your application a JavaScript engine.<span id="more-2037"></span></p>
<p>Such kind of application/server is Node.js. With V8 embedded into, Node is intended to run on a machine and to serve some requests. Just like a normal web server, but with few differences. First of all Node is not only serving HTTP requests, but also TCP. Well I&#8217;m not so deep into this yet, but so far that works for me. What I need for now is its web serving functionality.</p>
<p>The way Node works, however is different from what we know from every other web server. Here it is a normal server in general:</p>
<p><a href="/wp-content/uploads/2010/11/client-server.png"></a><a href="/wp-content/uploads/2010/11/client-server.png"><img class="alignleft size-full wp-image-2053" title="client-server" src="/wp-content/uploads/2010/11/client-server.png" alt="Client Server" width="600" height="150" srcset="/wp-content/uploads/2010/11/client-server.png 600w, /wp-content/uploads/2010/11/client-server-300x75.png 300w" sizes="(max-width: 600px) 100vw, 600px" /></a></p>
<p>Whenever a request comes to the server, it tries to return the response as fast as possible. This is one of the main goals of every web developer team &#8211; to make the application as fast as possible. However in Node the things work different:</p>
<p><a href="/wp-content/uploads/2010/11/node-client-server.png"><img class="alignleft size-full wp-image-2058" title="node-client-server" src="/wp-content/uploads/2010/11/node-client-server.png" alt="Node.js Client Server Application" width="600" height="150" srcset="/wp-content/uploads/2010/11/node-client-server.png 600w, /wp-content/uploads/2010/11/node-client-server-300x75.png 300w" sizes="(max-width: 600px) 100vw, 600px" /></a></p>
<p>Here the server doesn&#8217;t return immediately the response, but holds as long as possible until some &#8220;event&#8221; occurs. You can thing of Node as a classical chat server. Until one of the peers doesn&#8217;t write a message, the other doesn&#8217;t receive anything.</p>
<blockquote><p>Some may be confused as how you can use both the typical web server, as Apache, with Node as another web server within the same page. The answer is &#8211; with AJAX. As you know thus you can have only one chunk of your page talking with the server &#8211; in this case the entire page is returned by Apache, but inside the page you can have a chat app using Node as a server, working perhaps on a different port on the same machine.</p></blockquote>
<p>Typically this scenario can be simulated without Node, but as I said, with some disadvantages. Let&#8217;s say you have two browsers and one server &#8211; you can infinitely loop AJAX calls to the server and whenever there is new message on the server return it to the browser &#8211; this is quite inefficient. There are two approaches in this case.</p>
<ol>
<li>You can make those AJAX calls too recently and you can have a call every N seconds. In that case if N is to short you&#8217;ll have too many calls and in case the other peer doesn&#8217;t make anything the server will be unusually loaded with no practical effect.</li>
<li>In the second case you can choose to make N too long &#8211; for instance 20 seconds. This is also bad, because during this period of time the peers may want to interact and chat.</li>
</ol>
<p>In that case Node is a web server, but simply doesn&#8217;t return the response until a specific event doesn&#8217;t occur. How does this look like in a web browser. You may know how looking into the <a title="Firebug" href="https://addons.mozilla.org/en-US/firefox/addon/1843/" target="_blank">Firebug console</a> for every AJAX call you see the request and how many seconds it has taken. If you make an AJAX call to a Node server app the request just doesn&#8217;t respond immediately.</p>
<h2>Installing Node.js</h2>
<p>The process of installation is <a title="Node.js Build" href="http://nodejs.org/#build" target="_blank">described quite well</a>, so I&#8217;m going to describe it in few steps.</p>
<ol>
<li>Download the application from Git, note that V8 is embedded inside. The version while this post was written and of course was stable is <a title="Node.js v0.2.4" href="http://nodejs.org/dist/node-v0.2.4.tar.gz" target="_blank">v0.2.4</a></li>
<li>For those familiar with Unix/Linux systems, there are three simple steps following, however without <a title="Gnu Compiler Collection" href="http://gcc.gnu.org/" target="_blank">GCC (Gnu Compiler Collection)</a> you wont be able to proceed! I&#8217;m writing this especially for the Mac OS users, as they may know there is no built-in GCC there.</li>
<li>./configure</li>
<li>make</li>
<li>make install</li>
<li>make test (optional)</li>
</ol>
<p>This in general is enough. After all that you can write the node command in your terminal. However if there are some problems while compiling it you may refer to Git and the Node community for more help. Don&#8217;t forget that V8 can work only on x86, x64 and ARM architectures.</p>
<h2>Summary</h2>
<p>There are few things that can be summarized now:</p>
<ol>
<li>First of all Node can be a web server, as Apache is, but with the option to respond on event firing.</li>
<li>You can request it either with a web page loaded in your browser or within a chunk of the page via AJAX.</li>
<li>To install Node you need GCC. It comes with V8 JavaScript engine inside, which can run only on x86, x64 and ARM.</li>
</ol>
<p>So far so good! Now we have Node installed, practically useless, because there is no application running on it. In my next post I&#8217;ll describe how to run your first application.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2010/12/02/diving-into-node-js-a-long-polling-example/" rel="bookmark" title="Diving into Node.js &#8211; A Long Polling Example">Diving into Node.js &#8211; A Long Polling Example </a></li>
<li><a href="/2010/11/19/diving-into-node-js-very-first-app/" rel="bookmark" title="Diving into Node.js &#8211; Very First App">Diving into Node.js &#8211; Very First App </a></li>
<li><a href="/2010/01/31/speed-up-the-javascript-it-can-change-dramatically-the-user-experience/" rel="bookmark" title="Speed up the JavaScript. It can change dramatically the user experience.">Speed up the JavaScript. It can change dramatically the user experience. </a></li>
<li><a href="/2010/01/11/what-should-be-optimized-in-one-web-page/" rel="bookmark" title="What should be optimized in one web page?">What should be optimized in one web page? </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2010/11/16/diving-into-node-js-introduction-and-installation/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>How to Overcome Zend_Cache_Frontend_Page&#8217;s Problem with Cookies</title>
		<link>/2010/11/03/how-to-overcome-zend_cache_frontend_pages-problem-with-cookies/</link>
		<comments>/2010/11/03/how-to-overcome-zend_cache_frontend_pages-problem-with-cookies/#comments</comments>
		<pubDate>Wed, 03 Nov 2010 14:19:25 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[micro tutorial]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[Apache Corporation]]></category>
		<category><![CDATA[Cache]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[Computer memory]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[CPU cache]]></category>
		<category><![CDATA[Cross-platform software]]></category>
		<category><![CDATA[database server]]></category>
		<category><![CDATA[Google Inc.]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[HTTP cookie]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[MySQL Americas Inc.]]></category>
		<category><![CDATA[Page cache]]></category>
		<category><![CDATA[PHP programming language]]></category>
		<category><![CDATA[script interpreter]]></category>
		<category><![CDATA[Technology/Internet]]></category>
		<category><![CDATA[web app]]></category>
		<category><![CDATA[web application caching]]></category>
		<category><![CDATA[Web application frameworks]]></category>
		<category><![CDATA[web server]]></category>
		<category><![CDATA[Zend Technologies]]></category>

		<guid isPermaLink="false">/?p=2024</guid>
		<description><![CDATA[Zend_Cache_Frontend_Page First of all there are several things to know about Zend Framework and caching. Whenever you work on a big web application caching is one of the mostly used mechanisms of speeding up the app and improve user performance. In general the task and the solution are pretty simple and natural. As the application &#8230; <a href="/2010/11/03/how-to-overcome-zend_cache_frontend_pages-problem-with-cookies/" class="more-link">Continue reading <span class="screen-reader-text">How to Overcome Zend_Cache_Frontend_Page&#8217;s Problem with Cookies</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2011/01/17/a-memcached-zend_cache/" rel="bookmark" title="A Memcached Zend_Cache">A Memcached Zend_Cache </a></li>
<li><a href="/2010/01/27/theory-of-caching-zend_cache-zend-optimizer/" rel="bookmark" title="Theory of caching. Zend_Cache &#038; Zend Optimizer.">Theory of caching. Zend_Cache &#038; Zend Optimizer. </a></li>
<li><a href="/2010/07/21/setting-up-global-cache-in-zend-framework/" rel="bookmark" title="Setting Up Global Cache in Zend Framework">Setting Up Global Cache in Zend Framework </a></li>
<li><a href="/2010/07/19/zend-framework-cache-database-table-schemes/" rel="bookmark" title="Zend Framework: Cache Database Table Schemes">Zend Framework: Cache Database Table Schemes </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Zend_Cache_Frontend_Page</h2>
<p>First of all there are several things to know about Zend Framework and caching. Whenever you work on a big web application caching is one of the mostly used mechanisms of speeding up the app and improve user performance. In general the task and the solution are pretty simple and natural.</p>
<p>As the application grows up the visitors become more and more impatient about what they receive. A single page is becoming slower and slower and the result is painful. First of all every time a user hits a page the application server uses the web server, a script interpreter, a database server and potentially the file system. But that&#8217;s not all. After all this output is generated on the server, as HTML in the most cases, it is sent to the client where again CSS and JavaScript engines parse and execute them.</p>
<p>In this scenario it&#8217;s easy to imagine how many time is spent. While there are several techniques to optimize the client side by optimizing JavaScript, CSS and the static images used for the design of the site, here I&#8217;m going to talk more about the backend.</p>
<h2>Beside the Optimization</h2>
<p>Let&#8217;s assume we&#8217;ve one of the very used combination between Apache (as a webserver), PHP (as server scripting language) and MySQL (as database server). Here you can choose to optimize all three of them. However beside the optimization of them one of the most simple steps you can do is to cache the output generated by these three branches of your web app.</p>
<h2>Caching the Content</h2>
<p>In fact you can cache only single parts of the whole process. For instance you can cache only the result returned by some slow database query. Let&#8217;s imagine a query takes about 2 seconds to execute. Now you can cache the result into a file and during the cache is active, i.e. it has not expired, the application takes it from a file stored somewhere in the file system.</p>
<p>In a typical Zend Framework scenario you can first setup the frontend and backend options of the cache.</p>
<pre lang="php">
$frontendOptions = array(
	'lifetime'                => 600, // in seconds - this is 10 seconds
	'automatic_serialization' => true,
);
$backendOptions = array('cache_dir' => 'cache/');
$cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);
		
$cacheKey = md5('mykey');

if (!$cache->load($cacheKey)) {
	$slowQueryResult = $article->fetchAll();
	$cache->save($slowQueryResult, $cacheKey);
} else {
	$slowQueryResult = $cache->load($cacheKey);
}
</pre>
<p>You can setup different options here by setting up the cache directory, lifetime, etc.</p>
<p><em>Note that the cache directory must exists and with write permissions and Zend Framework doesn&#8217;t create it for you and will throw error.</em></p>
<p>The problem here is that now you cache only part of the generated content and in many cases this is still too slow for most of the users. However all the work (in most of the cases) of the web server, the script interpreter and the database server result in a simple HTML output. What if you have this output generated or cached for you and when the user hit the page the server will return this pre-generated code?</p>
<p>This is indeed very fast, because it&#8217;s similar to return a text file, as the HTML is simply formatted text.</p>
<h2>Caching the Entire Page</h2>
<p>Before I proceed, I&#8217;d like to say that I work with Zend Framework 1.9.x. Now in the latest versions of ZF there are new mechanisms of caching the output even Zend_Cache_Frontend_Page works fine on them.</p>
<p>You can simply setup the page cache within few simple lines of code:</p>
<pre lang="php">
$fo = array(
    'lifetime' => 600,
    'regexps' => array(
        '^/' => array(
	'cache' => true,
         'cache_with_cookie_variables' => true,
        ),
    )
);

$bo = array(
    'cache_dir' => 'cache/'
);

$cache = Zend_Cache::factory('Page', 'File', $fo, $bo);
$cache->start();
</pre>
<p>However my advise is to place this code as high as possible, because this will cache everything generated as output. It&#8217;s a good practice if you place this even in the bootstrap before you make the connection with the database. Actually you don&#8217;t need a database connection when you&#8217;ve to return a simple text(html) file.</p>
<p>This will improve your app&#8217;s performance a lot!</p>
<p>However there are few things to know. When you setup the cache to work even with cookie variables, you can see that hitting the page with different browsers Zend Framework will generated different cache pages. This is quite useless because than you don&#8217;t have any benefit of caching the content.</p>
<p>First of all let me say that THIS IS NOT A BUG! of ZF. Simply the framework will use the cookie variables to generate the cache key. It&#8217;s obvious that different browsers, even more different users, will have different cookie set and the framework will generate different cache keys for them.</p>
<p>Thus you&#8217;ve to change the setting to generate the cache key from cookie variable by explicitly set this option to false:</p>
<pre lang="php">
$fo = array(
    'lifetime' => 600,
    'regexps' => array(
        '^/' => array(
		 'cache' => true,
         'cache_with_cookie_variables' => true,
         'make_id_with_cookie_variables' => false,
        ),
    )
);

$bo = array(
    'cache_dir' => 'cache/'
);

$cache = Zend_Cache::factory('Page', 'File', $fo, $bo);
$cache->start();
</pre>
<p>Note that in this example we cache every single page generated by the framework explained in the regexps. This is not so good especially when the users have the possibility to login and to see customized content for them, so you can be careful what you cache.</p>
<p>A typical problem that this solution solves is when your application uses Google Analytics. As you may know Google Analytics sets up a cookie every time when an user hits the page, so every time the framework will generate a different cache for him and in result he won&#8217;t see any benefit and performance improvement from your site.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2011/01/17/a-memcached-zend_cache/" rel="bookmark" title="A Memcached Zend_Cache">A Memcached Zend_Cache </a></li>
<li><a href="/2010/01/27/theory-of-caching-zend_cache-zend-optimizer/" rel="bookmark" title="Theory of caching. Zend_Cache &#038; Zend Optimizer.">Theory of caching. Zend_Cache &#038; Zend Optimizer. </a></li>
<li><a href="/2010/07/21/setting-up-global-cache-in-zend-framework/" rel="bookmark" title="Setting Up Global Cache in Zend Framework">Setting Up Global Cache in Zend Framework </a></li>
<li><a href="/2010/07/19/zend-framework-cache-database-table-schemes/" rel="bookmark" title="Zend Framework: Cache Database Table Schemes">Zend Framework: Cache Database Table Schemes </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2010/11/03/how-to-overcome-zend_cache_frontend_pages-problem-with-cookies/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>PHP: What is More Powerful Than list()</title>
		<link>/2010/08/27/php-what-is-more-powerful-than-list/</link>
		<comments>/2010/08/27/php-what-is-more-powerful-than-list/#comments</comments>
		<pubDate>Fri, 27 Aug 2010 12:18:39 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[micro tutorial]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Binary search algorithm]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[C syntax]]></category>
		<category><![CDATA[Computer programming]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Data types]]></category>
		<category><![CDATA[Google Inc.]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[paging]]></category>
		<category><![CDATA[search result page]]></category>
		<category><![CDATA[search results]]></category>
		<category><![CDATA[Technology/Internet]]></category>
		<category><![CDATA[Type theory]]></category>
		<category><![CDATA[Variables]]></category>
		<category><![CDATA[web system]]></category>

		<guid isPermaLink="false">/?p=1933</guid>
		<description><![CDATA[First of all list() is not an unknown method in the PHP community, where almost every PHP developer knows what it does. The pity is that it has, perhaps, remained useless, although there is hidden power in it! What is list()? Let&#8217;s assume you&#8217;ve two variables and one array with two elements: $arr = array(1, &#8230; <a href="/2010/08/27/php-what-is-more-powerful-than-list/" class="more-link">Continue reading <span class="screen-reader-text">PHP: What is More Powerful Than list()</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2010/08/31/php-what-is-more-powerful-than-list-perhaps-extract/" rel="bookmark" title="PHP: What is More Powerful Than list() &#8211; Perhaps extract()">PHP: What is More Powerful Than list() &#8211; Perhaps extract() </a></li>
<li><a href="/2010/09/29/construct-a-sorted-php-linked-list/" rel="bookmark" title="Construct a Sorted PHP Linked List">Construct a Sorted PHP Linked List </a></li>
<li><a href="/2011/08/18/powerful-php-less-known-string-manipulation/" rel="bookmark" title="Powerful PHP: Less Known String Manipulation">Powerful PHP: Less Known String Manipulation </a></li>
<li><a href="/2010/06/11/friday-algorithms-quicksort-difference-between-php-and-javascript/" rel="bookmark" title="Friday Algorithms: Quicksort &#8211; Difference Between PHP and JavaScript">Friday Algorithms: Quicksort &#8211; Difference Between PHP and JavaScript </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<p>First of all <a title="PHP list" href="http://php.net/manual/en/function.list.php" target="_blank">list()</a> is not an unknown method in the PHP community, where almost every PHP developer knows what it does. The pity is that it has, perhaps, remained useless, although there is hidden power in it!</p>
<h2>What is list()?</h2>
<p>Let&#8217;s assume you&#8217;ve two variables and one array with two elements:</p>
<pre lang="php">
$arr = array(1, 2);
$a = $arr[0];
$b = $arr[1];
// now a == 1, and b == 2
</pre>
<p>Maybe the easiest way to assign to the first variable the value of the first element of the array, and to the second variable the value of the second element of the array is to use list():</p>
<pre lang="php">
list($a, $b) = array(1, 2);
// again a == 1, and b == 2
</pre>
<p>Note that you can do the same with as many variables/array elements you want.</p>
<p>The funny thing is that nobody use it, while I see at least one perfect usage. You can think of a typical admin panel of any web system. For sure any developer has programmed the typical table page containing a list of &#8220;things&#8221; and a paging to switch the result set page. It&#8217;s like the posts page from the WordPress admin panel, or a search result page in Google, where you&#8217;ve one page of results and at the bottom &#8211; a number of pages where you can go to another page of the search results.</p>
<p>What I&#8217;ve seen in almost every project is that typically the developers prefer to set the results for the page into one list returned from one method and the count of the entire result set is returned by another method.</p>
<p>Thus most of the times there are two methods, performing most commonly a database queries. Something like &#8211; getList($offset, $limit) and getCount() where the first one returns the page and the second one returns the count of the result set.</p>
<p>This will result into two methods, two calls and two lines of code:</p>
<pre lang="php">
function getList($offset, $limit)
{
	...
	// although the entire result set contains
	// 5 elements by limiting it from the parameters
	// only three are returned
	return $list; // where $list = array('title1', 'title2', 'title3');	
}

function getCount()
{
	...
	// here's returned the count
	// of the entire result set
	return $count; // where $count = 5;	
}

$list  = getList(0, 3);
$count = getCount();
</pre>
<p>What actually you can do is to perform both queries in one method, perhaps called getItems($offset, $limit) where the returned value is an array containing both the list of results and the count:</p>
<pre lang="php">
function getItems($offset, $limit)
{
	...
	return array('list' => $list, 'count' => $count);
}
</pre>
<p>And finally when calling this method to list() that into the two variables &#8211; single lined.</p>
<pre lang="php">
list($list, $count) = getItems(0, 3);
</pre>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2010/08/31/php-what-is-more-powerful-than-list-perhaps-extract/" rel="bookmark" title="PHP: What is More Powerful Than list() &#8211; Perhaps extract()">PHP: What is More Powerful Than list() &#8211; Perhaps extract() </a></li>
<li><a href="/2010/09/29/construct-a-sorted-php-linked-list/" rel="bookmark" title="Construct a Sorted PHP Linked List">Construct a Sorted PHP Linked List </a></li>
<li><a href="/2011/08/18/powerful-php-less-known-string-manipulation/" rel="bookmark" title="Powerful PHP: Less Known String Manipulation">Powerful PHP: Less Known String Manipulation </a></li>
<li><a href="/2010/06/11/friday-algorithms-quicksort-difference-between-php-and-javascript/" rel="bookmark" title="Friday Algorithms: Quicksort &#8211; Difference Between PHP and JavaScript">Friday Algorithms: Quicksort &#8211; Difference Between PHP and JavaScript </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2010/08/27/php-what-is-more-powerful-than-list/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
