Search Results: "jam"

4 July 2012

Johannes Schauer: enumerating elementary circuits of a directed_graph

For my GSoC project this year I need to be able to enumerate all elementary circuits of a directed graph. My code is written in Ocaml but neither the ocamlgraph library nor graph libraries for other languages seem to implement a well tested algorithm for this task. In lack of such a well tested solution to the problem, I decided to implement a couple of different algorithms. Since it is unlikely that different algorithms yield the same wrong result, I can be certain enough that each individual algorithm is working correctly in case they all agree on a single solution. As a result I wrote a testsuite, containing an unholy mixture of Python, Ocaml, D and Java code which implements algorithms by D. B. Johnson, R. Tarjan, K. A. Hawick and H. A. James.

Algorithm by R. Tarjan The earliest algorithm that I included was published by R. Tarjan in 1973.
Enumeration of the elementary circuits of a directed graph
R. Tarjan, SIAM Journal on Computing, 2 (1973), pp. 211-216
http://dx.doi.org/10.1137/0202017
I implemented the pseudocode given in the paper using Python. The git repository can be found here: https://github.com/josch/cycles_tarjan

Algorithm by D. B. Johnson The algorithm by D. B. Johnson from 1975 improves on Tarjan's algorithm by its complexity.
Finding all the elementary circuits of a directed graph.
D. B. Johnson, SIAM Journal on Computing 4, no. 1, 77-84, 1975.
http://dx.doi.org/10.1137/0204007
In the worst case, Tarjan's algorithm has a time complexity of O(n e(c+1)) whereas Johnson's algorithm supposedly manages to stay in O((n+e)(c+1)) where n is the number of vertices, e is the number of edges and c is the number of cycles in the graph. I found two implementations of Johnson's algorithm. One was done by Frank Meyer and can be downloaded as a zip archive. The other was done by Pietro Abate and the code can be found in a blog entry which also points to a git repository. The implementation by Frank Meyer seemed to work flawlessly. I only had to add code so that a graph could be given via commandline. The git repository of my additions can be found here: https://github.com/josch/cycles_johnson_meyer Pietro Abate implemented an iterative and a functional version of Johnson's algorithm. It turned out that both yielded incorrect results as some cycles were missing from the output. A fixed version can be found in this git repository: https://github.com/josch/cycles_johnson_abate

Algorithm by K. A. Hawick and H. A. James The algorithm by K. A. Hawick and H. A. James from 2008 improves further on Johnson's algorithm and does away with its limitations.
Enumerating Circuits and Loops in Graphs with Self-Arcs and Multiple-Arcs.
Hawick and H.A. James, In Proceedings of FCS. 2008, 14-20
www.massey.ac.nz/~kahawick/cstn/013/cstn-013.pdf
In contrast to Johnson's algorithm, the algorithm by K. A. Hawick and H. A. James is able to handle graphs containing edges that start and end at the same vertex as well as multiple edges connecting the same two vertices. I do not need this functionality but add the code as additional verification. The paper posts extensive code snippets written in the D programming language. A full, working version with all pieces connected together can be found here: https://github.com/josch/cycles_hawick_james The algorithm was verified using example output given in the paper. The project README states how to reproduce it.

Input format All four codebases have been modified to produce executables that take the same commandline arguments which describes the graphs to investigate. The first argument is the number of vertices of the graph. Subsequent arguments are ordered pairs of comma separated vertices that make up the directed edges of the graph. Lets look at the following graph as an example: cycle example The DOT source for this graph is:
digraph G  
  0;
  1;
  2;
  0 -> 1;
  0 -> 2;
  1 -> 0;
  2 -> 0;
  2 -> 1;
   
To generate the list of elementary circuits using Tarjan's algorithm for the graph above, use:
$ python cycles.py 3 0,1 0,2 1,0 2,0 2,1
0 1
0 2
0 2 1
The commandline arguments are the exact same for the other three methods and yield the same result in the same order. If the DOT graph is in a format as simple as above, the following sed construct can be used to generate the commandline argument that represents the graph:
$ echo  sed -n -e '/^\s*[0-9]\+;$/p' graph.dot   wc -l   sed -n -e 's/^\s*\([0-9]\) -> \([0-9]\);$/\1,\2/p' graph.dot 

Testsuite As all four codebases take the same input format and have the same output format, it is now trivial to write a testsuite that compares the individual output of each algorithm for the same input and checks for differences. The code of the testsuite is available via this git repository: https://github.com/josch/cycle_test The other four repositories exist as submodules of the testsuite repository.
$ git clone git://github.com/josch/cycle_test.git
$ cd cycle_test
$ git submodule update --init
A testrun is done via calling:
$ ./test.sh 11
The argument to the shell script is an integer denoting the maximum number N of vertices for which graphs will be generated. The script will compile the Ocaml, Java and D sourcecode of the submodules as well as an ocaml script called rand_graph.ml which generates random graphs from v = 1..N vertices where N is given as a commandline argument. For each number of vertices n, e = 1..M number of edges are chosen where M is maximum number of edges given the number of vertices. For every combination of number of vertices v and number of edges e, a graph is randomly generated using Pack.Digraph.Rand.graph from the ocamlgraph library. Each of those generated graphs is checked for cycles and written to a file graph-v-e.dot if the graph contains a cycle. test.sh then loops over all generated dot files. It uses the above sed expression to convert each dot file to a commandline argument for each of the algorithms. The outputs of each algorithm are then compared with each other and only if they do not differ, does the loop continue. Otherwise the script returns with an exit code. The tested algorithms are the Python implementation of Tarjan's algorithm, the iterative and functional Ocaml implementation as well as the Java implementation of Johnson's algorithm and the D implementation of the algorithm by Hawick and James.

Future developments Running the testsuite with a maximum of 12 vertices takes about 33 minutes on a 2.53GHz Core2Duo and produces graphs with as much as 1.1 million cycles. It seems that all five implementations agree on the output for all 504 generated graphs that were used as input. If there should be another implementation of an algorithm that enumerates all elementary circuits of a directed graph, I would like to add it. There are some more papers that I would like to read but I lack access to epubs.siam.org and ieeexplore.ieee.org and would have to buy them. Benchmarks seem a bit pointless as not only the algorithms are very different from each other (and there are many ways to tweak each of them) but also the programming languages differ. Though for the curious kind, it follows the time each algorithm takes to enumerate all cycles for all generated graphs up to 11 vertices.
algorithmtime (s)
Johnson, Abate, Ocaml, iterative137
Johnson, Abate, Ocaml, functional139
Tarjan, Python153
Hawick, D175
Johnson, Meyer, Java357
The iterative Ocaml code performs as well as the functional one. In practice, the iterative code should probably be preferred as the functional code is not tail recursive. On the other hand it is also unlikely that cycles ever grow big enough to make a difference in the used stack space. The Python implementation executes surprisingly fast, given that Tarjan's algorithm is supposedly inferior to Johnson's and given that Python is interpreted but the Python implementation is also the most simple one with the least amount of required datastructures. The D code potentially suffers from the bigger datastructures and other bookkeeping that is required to support multi and self arcs. The java code implements a whole graph library which might explain some of its slowness.

2 July 2012

Benjamin Mako Hill: Wiki Conferencing

I am in Berlin for the Wikipedia Academy, a very cool hybrid free culture community plus refereed academic conference organized, in part, by Wikimedia Deutschland. On Friday, I was very excited to have been invited to give the conference's opening keynote based on my own hybrid take on learning from failures in peer production and incorporating a bunch of my own research. Today, I was on a panel at the conference about free culture and sharing practices. I'll post talks materials and videos when the conference puts them online. I will be in Berlin for the next week or so before I head to directly to Washington, DC for Wikimania between the 11th and 15th. I'll be giving three talks there: Between then and now, I'm taking the next week in Berlin to catch up on work, and with friends. If you're in either place and want to meet up, please get in touch and lets try to arrange something.

25 June 2012

Raphaël Hertzog: Test Driven Development with CppUTest, now in Debian

I have recently read Test Driven Development with Embedded C by James W. Grenning and published by Pragmatic Programmers. I really enjoyed the book: while I was aware of the huge benefits of having a comprehensive test suite, I never studied seriously the principles behind Test Driven Development (TDD) and this book makes a good introduction to the topic. At the same time it focuses on the C language and contains lots of examples on how you can create tests even for projects which have to interact with hardware or other unpredictable components (the key is to create many abstractions) using all the possibilities that C offers. The author convincingly argues that developing code with TDD forces you to create a modular design that is easier to evolve when the underlying requirements change. He also highlights how the tests serve as reference documentation of the API. James W. Grenning recommends CppUTest as his xUnit test framework of choice. When I wanted to try this test framework, I discovered that it was not available in Debian. I decided to package it because it has some interesting features not offered by the contenders (at least not to my knowledge). It s now available in Debian and in Ubuntu. First, it doesn t require any explicit registration of tests and has a very lightweight syntax. The small downside is that CppUTest requires the usage of C++ for the tests. But C++ is compatible with C so it doesn t matter much if you have a C++ compiler for your target. On the contrary, usage of variables and methods scoped to the test group makes it easy to write clear tests. Here s a short sample of test code:
extern "C"  
#include "timer.h"
#include "timefn.h"
 
 
#include "CppUTest/TestHarness.h"
 
static Time the_time;
static const int start_sec = 123;
static const int start_nsec = 456789000;
static const int delay_sec = 8;
static const int delay_nsec = 111111000; // start_nsec + delay_nsec < 10^9
 
TEST_GROUP(Timer)
 
    /* Class variables available to all tests in the group */
    Timer timer;
    Delay remaining;
 
    /* Standard setup/teardown methods of xUnit tests */
    void setup()  
        timer = timer_new();
        time_set(&the_time, start_sec, start_nsec);
        /* [...] */
     
 
    void teardown()  
        timer_free(timer);
        /* [...] */
     
 
    /* Helper functions specific to the test group */
    void start_timer_with_delay(long sec, long nsec)
     
        timer_set_real_delay(timer, sec, nsec);
        timer_start(timer);
     
 
    void ensure_remaining_is(long sec, long nsec)
     
        CHECK_EQUAL(sec, delay_get_seconds(remaining));
        CHECK_EQUAL(nsec, delay_get_nanoseconds(remaining));
     
 ;
 
TEST(Timer, NewIsNotStarted)
 
    CHECK(!timer->started);
 
/* [...] */
TEST(Timer, GetRemainingTimeWithNanosecondPrecision_ShiftOfSeconds)
 
    start_timer_with_delay(delay_sec, delay_nsec);
    time_set(&the_time, start_sec + delay_sec - 5, start_nsec + delay_nsec + 1000);
 
    remaining = timer_get_remaining_time(timer);
 
    ensure_remaining_is(4, 999999000);
 
To run those tests, you just need this boilerplate code in a main.cpp:
#include "CppUTest/CommandLineTestRunner.h"
 
int main(int argc, char** argv)
 
   return CommandLineTestRunner::RunAllTests(argc, argv);
 
Another interesting feature is its integrated memory leak detection system. Any test that hasn t released allocated memory at the end of the teardown process will be marked as failed. The upstream developers have made some unusual choices (static library only, installation in a private directory) but this will likely change with the switch to an automake and autoconf-based build system. I have reported the oddities that I found and I requested them to provide a pkg-config file to make it easier to compile and link unit tests exploiting CppUTest. I already used CppUTest to develop a small application running on an embedded Linux. At some point, I might try to use CppUTest for dpkg development. I believe that it makes for a good fit. dpkg is already C++ ready since dselect is written in C++ and reuses a good part of dpkg s code. In any case, if you like Test Driven Development and are writing C or C++ based applications, I invite you to try CppUTest.

No comment Liked this article? Click here. My blog is Flattr-enabled.

19 June 2012

Jo Shields: Enormity

(This blog post is a more firm version of a series of tweets and forum posts I made a few weeks ago. This should also be considered a refresh of this post by Mirco Bauer a few years ago) It has been said that Mono is bloated, and that people should use lighter frameworks that don t pull in hundreds of meg . How much basis in reality is there for those comments? Well, let s do a little thought exercise. How much space is the minimum space needed for several languages to work? For this experiment, we will be looking at the required installation size on disk of several language frameworks, each time installing the bare minimum for a command-line hello world app in that language to run. For example, the Ruby result is the minimum install required to run:
puts 'Hello world'
and the Mono result is the minimum install required to run the following code, which has been compiled on a different machine using dmcs :
public class Hello1
 
   public static void Main()
    
      System.Console.WriteLine("Hello, World!");
    
 
Obviously, for dynamic languages like Ruby and Python, there is no compiler step needed. For languages like C# and Java, it is fair to compile these on a different machine as end-users of packages running these frameworks receive binaries, not source they do not need a development environment. So, on to the test environment. This is a bare bootstrapped AMD64 Debian Unstable system, as of today (i.e. debootstrap sid /tmp/badger ). Its install size is 275MB. So how much space? Ruby 1.9 Test code is as follows:
puts 'Hello world'
Install requirements are as follows:
root@dream:/# aptitude install ruby1.9.1
The following NEW packages will be installed:
  libffi5 a  libruby1.9.1 a  libyaml-0-2 a  ruby1.9.1 
0 packages upgraded, 4 newly installed, 0 to remove and 0 not upgraded.
Need to get 4703 kB of archives. After unpacking 13.1 MB will be used.
OpenJDK 7 Test code is as follows:
class HelloWorldApp  
    public static void main(String[] args)  
        System.out.println("Hello world");
     
 
Install requirements are as follows:
root@dream:/# aptitude install openjdk-7-jre-headless
The following NEW packages will be installed:
  ca-certificates a  ca-certificates-java a  dbus a  fontconfig-config a  
  icedtea-7-jre-cacao a  icedtea-7-jre-jamvm a  java-common a  
  krb5-locales a  libavahi-client3 a  libavahi-common-data a  
  libavahi-common3 a  libcap2 a  libcups2 a  libdbus-1-3 a  libexpat1 a  
  libffi5 a  libfontconfig1 a  libfreetype6 a  libglib2.0-0 a  
  libglib2.0-data a  libgssapi-krb5-2 a  libjpeg8 a  libk5crypto3 a  
  libkeyutils1 a  libkrb5-3 a  libkrb5support0 a  liblcms2-2 a  libnspr4 a  
  libnss3 libnss3-1d a  libpcre3 a  libpcsclite1 a  libsystemd-login0 a  
  libxml2 a  openjdk-7-jre-headless openjdk-7-jre-lib a  openssl a  
  sgml-base a  shared-mime-info a  ttf-dejavu-core a  tzdata-java a  ucf a  
  xml-core a  
0 packages upgraded, 43 newly installed, 0 to remove and 0 not upgraded.
Need to get 51.5 MB of archives. After unpacking 137 MB will be used.
Python 3.2 Test code is as follows:
print ("Hello world")
Install requirements are as follows:
root@dream:/# aptitude install python3.2-minimal
The following NEW packages will be installed:
  file a  libexpat1 a  libffi5 a  libmagic1 a  mime-support a  python3.2 a  python3.2-minimal 
0 packages upgraded, 7 newly installed, 0 to remove and 0 not upgraded.
Need to get 4853 kB of archives. After unpacking 17.7 MB will be used.
Mono 2.10 (C#) Test code is as follows:
public class Hello
 
   public static void Main()
    
      System.Console.WriteLine("Hello world");
    
 
Install requirements are as follows:
root@dream:/# aptitude install mono-runtime
The following NEW packages will be installed:
  binfmt-support a  cli-common a  libmono-corlib4.0-cil a  libmono-i18n-west4.0-cil a  libmono-i18n4.0-cil a  
  libmono-security4.0-cil a  libmono-system-configuration4.0-cil a  libmono-system-security4.0-cil a  
  libmono-system-xml4.0-cil a  libmono-system4.0-cil a  mono-4.0-gac a  mono-gac a  mono-runtime 
0 packages upgraded, 13 newly installed, 0 to remove and 0 not upgraded.
Need to get 4383 kB of archives. After unpacking 11.5 MB will be used.
Of course, every time I try to make the argument that Mono is much leaner than what people propose as an alternative, the anti-Mono brigade go on the defensive and insist that nobody in their right minds uses Python or Ruby either everything ever should be written in Qt. So, hypothetically Qt 4.8 (C++) Test code is as follows:
#include <QTextStream>
int main(int argc, char **argv)
 
   QTextStream s(stdout);
   s << "Hello, world!\n";
   return 0;
 
Install requirements are as follows:
root@dream:/# aptitude install libqtcore4
The following NEW packages will be installed:
  libffi5 a  libglib2.0-0 a  libglib2.0-data a  libpcre3 a  libqtcore4 
  libxml2 a  sgml-base a  shared-mime-info a  xml-core a  
0 packages upgraded, 9 newly installed, 0 to remove and 0 not upgraded.
Need to get 10.3 MB of archives. After unpacking 27.8 MB will be used.
Presented without comment for your consideration. Edit: There are complaints that these numbers are misleading, because they show default package manager behaviour, rather than what happens when passing extra flags or config file settings to Apt. When disabling installation of Recommends: packages, the numbers change as follows:

4 June 2012

Benjamin Mako Hill: Why Facebook's Network Effects are Overrated

A lot of people interested in free software, and user autonomy and network services are very worried about Facebook. Folks are worried for the same reason that so many investors are interested: the networks effects brought by hundreds of millions of folks signed up to use the service. Network effects -- the concept that a good or service increases in value as more people use it -- are not a new problem for free software. Software developers target Microsoft Windows because that is where the large majority of users are. Users with no love for Microsoft and who are otherwise sympathetic to free software use Windows because programs they need will only run there. Folks worried about Facebook are afraid for similar reasons. Sure, you can close down your Facebook account and move to Diaspora. But who will you talk to there? You can already hear people complaining about Facebook the same way they've been complaining about Windows or Office for years. People feel that their hands are tied and that their software, and their social network, will be determined by what everybody is doing. I'm worried about Facebook. But I'm not too intimidated by Facebook's network effects for two reasons. First, using Facebook doesn't preclude using anything else. Twitter has enormous overlapping functionality with Facebook. Sure, people use the systems very differently. But they both ask you to create lists of friends and followers and are designed around sending and receiving short status messages. Millions of people do both and both systems are thriving. For the millions of people who use both Facebook and Twitter, the two services have had to negotiate their marginal utility in a world they share with the other one. People decide that Twitter is for certain types of short messages and Facebook is for others. But these arrangements shift over time. And the relationships between services aren't always peaceful coexistence. Remember Friendster? Remember Orkut? Remember Tribe? Remember MySpace? MySpace, and all the others, are great examples of how social networks die. They very slowly fade away. MySpace users signed up for Facebook accounts and used both. They almost never just switched. Over time, as one platform became more attractive than the other, for many complicated reasons, attention and activity shifted. People logged in on MySpace less and Facebook more and, eventually, realized they were effectively no longer MySpace users. Anyone that has been on the Internet long enough to watch a few of these shifts from one platform to another knows that they're not abrupt -- even if they can be set in motion by a particular event or action. Users of social networking sites simply don't have to choose in the way that a person choosing to boot Windows and GNU/Linux does. I'm sure the vast majority of people with Diaspora accounts use Facebook actively. This is not a problem for Diaspora. It is how Diaspora -- or whatever else eventually achieves what many of us hoped Diaspora would -- could win. Second, Facebook is for the ephemeral. Facebook is primarily used for information that was produced very recently. This week if not today. If not this hour. Facebook has an enormous amount of data that users have fed it that may be hard to get out and move somewhere else. But most people don't care very much about having any regular access to the large majority of this information. What people care deeply about is having access to the data that they and their friends created today. And that data can just as easily be created somewhere else tomorrow. Or, with the right tools, created just as easily in both places. Compare this to something like Windows where moving away would require learning, converting, and perhaps even writing, new software. Perhaps even in new programming languages that most developers don't know yet. Compared to Windows, a migration away from Facebook will be easy. Facebook's photo galleries are an example of an important place where this holds less well. Social network information -- i.e., the list of who is friends with who -- is another example of something that is persistently valuable. That said, people really enjoy the act of finding and friending. Indeed, this process was part of the initial draw of Facebook and other social networks. None of this means that Facebook is over. It doesn't even mean that its ascendancy will be slowed. What it does mean is that Facebook is vulnerable to the next thing more than many technology firms that have benefited from network effects in the past. If users are given compelling reasons to switch to something else, they can with less trouble and they will. That compelling reason might be a new social network with better features or an awesome distributed architecture that allows freedom for users and the ability of those users to benefit from new and fantastic things that Facebook's overseers would never let them have and without the things Facebook's users suffer through today. Or it might be a sexier proprietary box to store users' private information. It doesn't mean that I'm not worried about Facebook. I remain deeply worried. It's just not very hard for me to imagine the end.

31 May 2012

Richard Hartmann: Potpourri II

Traffic jams suck; but they do give you a chance to think and blog. Truckers hams are telling me that four trucks are totalled and need to be removed by the THW. As the trucker next to me just broke out his gas grill and several people are joining him in a spontaneous BBQ, I don't expect to be moving any time soon. Kicking things along This is coming along nicely RAID 4 Unless you are forced to support legacy systems or playing RAIDemon and gotta try them all, there is no valid use case for RAID 4. So doing so is a patently bad idea. RAID 5 is always the better option as you are not relying on a single disk which contains the checksums, but use striping to distribute them. RAID 4 has a chance of 1/n that a failed disk will force all remaining disks to read all respective sectors and then the controller/CPU to XOR everything. There is a reason why RAID 3 was replaced with RAID 4; just as there's a reason why RAID 4 was replaced by RAID 5. Don't use RAID 4. Seriously. Tom Tom vs OSM In case you have been following the news in the GPS circles, you will have noticed that TomTom pretty gave up on innovating and resigned themselves to dying a slow death. Well that and to start a nice amount of FUD. While they have been rebuked pretty thoroughly already, I wanted to add my own POV. There is a kernel of truth in what TomTom said inasmuch they state that pedestrian paths are better than car paths. Of course, while they got the relative quality right, they are wrong about the absolute quality of the data. They claim pedestrian is OK and motorized is bad. In my experience, maps for motorized traffic are good while pedestrian tracks are mind-boggingly great. These days, most people (and probably all who read this) will be at least somewhat familiar with the quality of OSM in the random cities they visit over the year. The common verdict is usually "very nice". But that's not where OSM shines. It's in the lesser-known places where you don't expect too many tech-minded people to come along where it starts to really impress me. While I found a few stubs on a dead-end street in Akureyri which were not mapped, every foot trail I ever walked along in Iceland has been mapped. ski-doo tracks on Svalbard? Check. Backyard in Novosibirsk? Check, as well. And we are talking "packed earth track in between garages opening up into a 'playground' where a man and a pregnant women are passing a bottle back and forth while smoking and watching over their two kids who play next to a middle-aged man who is lying on the ground wasted, using a rock as a pillow all the while an extremely blingy Mercedes with two muscle-packed thugs is cruising by, all in the time it took us to walk through". Mapped. Horse tracks and hiking trails in Mongolia? Yep. Hutongs in Beijing including alleys so narrow you have to walk single file? Of course. Richard Fairhurst is right that the plural of anecdote is not data, but OSM is good. TomTom is afraid for a reason. As an aside, I find the picture used in TomTom's newsletter extremely funny; I am sure they didn't intend this, but hey. Windows 100-300 MiB for any random driver installation package is par for the course. Be it GFX, audio, or network card. If you plug in a different USB mouse, Windows 7 will take several seconds while "setting up" a standard USB HID device. And hitting ctrl-alt-del in the login screen or while logged in does not give you a quick way to shut down or reboot the machine. As I am breaking out the Windows installation every month to install updates and every six months to actually use this does not affect me a lot. Still, it's amazing that so many people are putting up with this. UEFI It's nice to see that Matthew Garrett is still going strong. I am not sure if this is the best way, but it seems to be a workable solution while in between a rock and a hard place. Not sure about the requirements of GPLv3 with regards to the keys Fedora will use to sign GRUB 2 with. From what I remember without rereading the license, as long as Fedora is not selling a system on which you can not disable secure boot they should be in the clear. IANAL, IIRC, etc. Wrapping up And I have not moved a single meter, other than making way to a police motorbike, in over an hour. Pity I don't have anything to BBQ with me; smells delicious over there.

15 May 2012

James Morrison: Testing email receive for appengine

It's not too obvious how to test email receive handlers in Appengine. The important observation is that the handlers take HTTP POSTs with multipart/form-data encoded data. In python you can build an email to be handled with the following code:
from email.message import Message 

def test_email(self):
body = Message()
body.add_header('to', 'test-unknown@other-app.com')
body.add_header('from', 'test@app.com')
body.add_header('Content-Type', 'multipart/alternative', boundary=self.boundary)
text = Message()
text['content-type'] = 'text/plain'
text.set_payload('I am I! Don Quixote! The man of La Mancha!')
body.attach(text)

post(payload=body.as_string())

14 May 2012

Benjamin Mako Hill: Date Arithmetic

When I set an alarm, my clock, now running on the computer in my pocket, is smart enough to tell me how much time will pass until the alarm is scheduled to sound. This has eliminated the old problem of sleeping past meetings before being surprised by an alarm precisely half a day after I had originally planned to wake. The price has been having to know exactly how little I will sleep: a usually depressing fact that had previously been obscured by my difficulty doing time arithmetic in my most somnolent moments.

Benjamin Mako Hill: Diamond Clarity

I3 I2 I1 SI2 SI1 VS2 VS1 VVS2 VVS1 IF FL
The GIA diamond clarity scale, shown above, is rather opaque.

13 May 2012

Jamie McClelland: Key Mapping for console redirection

This always flashes by too quickly for me to read... I'm preserving it here for next time.
Press the spacebar to pause...
KEY MAPPING FOR CONSOLE REDIRECTION:
Use the <ESC><0> key sequence for <F10>
Use the <ESC><!> key sequence for <F11>
Use the <ESC><@> key sequence for <F12>
Use the <ESC><Ctrl><M> key sequence for <Ctrl><M>
Use the <ESC><Ctrl><H> key sequence for <Ctrl><H>
Use the <ESC><Ctrl><I> key sequence for <Ctrl><I>
Use the <ESC><Ctrl><J> key sequence for <Ctrl><J>
Use the <ESC><X><X> key sequence for <Alt><x>, where x is any letter
key, and X is the upper case of that key
Use the <ESC><R><ESC><r><ESC><R> key sequence for <Ctrl><Alt><Del>

Jamie McClelland: Creating virtual machines

I recently setup an Alix board from PC Engines. I installed Debian onto a Compact Flash card using grml for the first time. After using parted to create a single partition, I ran:
grml-debootstrap --arch i386 --filesystem ext4 --grub /dev/sdb --hostname yaqeen --mirror http://http.us.debian.org/debian \ 
--nopassword  --release squeeze --target /dev/sdb1
I had to manually mount the partition and add console redirection for grub (and /etc/inittab). And then, when booting, I had to manually edit the grub configuration because it was trying to find the root filesystem on /dev/sdb instead of /dev/sda. I'm sure there is some tweaking I can do via /etc/deboostrap/scripts to fix those needs. Overall, I was very happy with the results. Thanks grml developers!

Jamie McClelland: Sparkleshare

Sparkleshare is a file sharing utility that keeps folders in sync on multiple computers in a similar fashion to the commercial and proprietary Dropbox. Sparkleshare recently released a Windows client, finally allowing me to start switching my co-workers at the Progressive Technology Project away from Dropbox. Overall, I'm very impressed. In particular, I appreciate the Sparkleshare authors' decision to build on top of existing tools (git for storage and revision control, ssh for transport, and ssh public key infrastructure for authorization and authentication). That means I don't have to learn new tools and protocols to debug and it means Sparkleshare can focus on the file sharing pieces. Despite my overall enthusiasm, I do have some serious concerns. Protecting your credentials A researcher found a startling security flaw in Dropbox - if you can copy a particular file from a user's computer to your own computer, you can impersonate them flawlessly, accessing all their Dropbox files without having to know the user's password. Unfortunately, Sparkleshare suffers from this same vulnerability if you use the default configuration. When you first install Sparkleshare, it creates a password-less ssh private/public key pair and then makes the public part easily accessible to you so you can add it to your server (or gitorious account, etc). Very convenient. But it also means that all an attacker needs to do is copy your private key (and your Sparkleshare configuration file) and they get complete control over your files. This problem is easily avoided. If you are running Linux or Mac OS X and you have your own key loaded in your ssh agent, Sparkleshare will happily use that key. So - simply by using your existing (presumably password-protected key) on your remote Sparkleshare servers, you can mitigate this problem. Sparkleshare will still load your Sparkleshare generated key, but if you don't provide that key with access to anything, no harm is done. Confirming each use of your key However... that leads to a new problem. If you are like me, your ssh agent is configured to ask for a confirmation every time your key is used. And, Sparkleshare regularly polls the remote git repository for changes. At best repeatedly clicking to confirm is tedious. At worst, it prevents you from intelligently rejecting malicious requests, thus defeating the whole purpose of the check. It is possible to launch Sparkleshare via ssh-agent in an environment in which you are not requiring the confirmation when Sparkleshare uses your key, but still requiring it for all other uses. However, given the trade offs, I've decided to add a password to my Sparkleshare provided ssh key rather than using my existing key: ssh-keygen -p -f ~/.config/sparkleshare/sparkleshare.jamie@progressivetech.org.key Now, I am prompted to enter my passphrase when I start Sparkleshare and don't have to confirm every use of the key. And, I continue to confirm each use of my main key. git was designed to store code, not documents Just because something is designed for one purpose doesn't mean it can't be used for another. However, there are a few limitations. Large files are one. git can handle files over 100MB, but may run into memory problems. I had to alter the git windowMemory setting, raising it higher than the size of the largest file. Another problem is disk space. Since git keeps full revision history on every machine, you have to download more data than just the files that are checked out. The more edits you make to a repository, the more disk space beyond what is checked out is needed (and deleting files won't help). Lastly, you can't use file modification times. With git, the file modification time will depend on when you checkout the files. With some fancy hook writing, you could tweak things so that the file modification date is the same as the commit date, but that still won't help you if you add an existing directory to Sparkleshare because all the files will have the same commit time. This "bug" has been reported to git and it has been rejected because mucking with the modification time of files can have bad results when you are using make to compile code. As Linus colorfully put it:
I'm sorry. If you don't see how it's WRONG to set a datestamp back to something that will make a simple "make" miscompile your source tree, 
I don't know what definition of "wrong" you are talking about.
It's WRONG.
It's STUPID.
And it's totally INFEASIBLE to implement.
Well, did I mention that git was designed for source code? No server validation Of all the problems I encountered, this one is by far the most serious. Perusing ~/.config/sparkleshare/debug.log is very informative. On a default installation, after you have added a project, you'll see:
19:32:27 [Fetcher][/home/jamie/SparkleShare/.tmp/bar] Fetching folder: ssh://foo@bar.org/foo/bar
19:32:27 [Fetcher] Disabled host key checking for bar.org
Wah. Once the project is added, whatever key fingerprint is given is stuffed into your ~/.ssh/known_hosts file. Host key checking is only disabled when you initially create the project, so if you connect to the proper server the first time, you are protected from subsequent man-in-the-middle attacks. However... if the initial fingerprint is wrong, your personal ssh configuration is now poisoned. This seems like a very bad idea. I've opened a debian bug to address it.

8 May 2012

James Bromberger: Courier IMAP and FAM

Last Friday, while tracking Debian Testing, the courier package was updated, and while authentication could be seen to be successful, actually using IMAP seemed to fail. Turns out the FAM package was somehow to blame; installing fam and libfam0 was the solution. This uninstalled gamin for me. So if you re pulling your hair out with a similar courier/imap issue, then perhaps have a look at the courier-imap mailing list.

23 April 2012

Benjamin Drung: Unreliable SSDs

Today my system froze and failed to reboot. I plugged in an Ubuntu live USB stick and booted from it. Then I discovered the problem that my Intel SSD 320 broke. The output of hdparm is attached to the end of the blog post. You can see that the device size is reduced to 8 MB from 120 GB and the serial number is called BAD_CTX 00000159. The firmware of the SSD was up-to-date and the last firmware update should have fixed the 8 MB bug. The Intel SSD 320 is my second SSD. My first SSD was a Super Talent Ultradrive GX 64GB, which died after around fifteen month of heavy use. It left a big bunch of my data corruption behind. SSDs seems to be very unreliable. Both SSDs died, but I cant remember that one of my HDDs died. $ sudo hdparm -I /dev/sda /dev/sda: ATA device, with non-removable media
Model Number: INTEL SSDSA2CW120G3
Serial Number: BAD_CTX 00000159
Firmware Revision: 4PC10362
Transport: Serial, ATA8-AST, SATA 1.0a, SATA II Extensions, SATA Rev 2.5, SATA Rev 2.6
Standards:
Used: unknown (minor revision code 0x0029)
Supported: 8 7 6 5
Likely used: 8
Configuration:
Logical max current
cylinders 16383 16
heads 16 16
sectors/track 63 63
--
CHS current addressable sectors: 16128
LBA user addressable sectors: 16384
LBA48 user addressable sectors: 16384
Logical Sector size: 512 bytes
Physical Sector size: 512 bytes
device size with M = 1024*1024: 8 MBytes
device size with M = 1000*1000: 8 MBytes
cache/buffer size = unknown
Nominal Media Rotation Rate: Solid State Device
Capabilities:
LBA, IORDY(can be disabled)
Standby timer values: spec'd by Standard, no device specific minimum
R/W multiple sector transfer: Max = 16 Current = 16
DMA: mdma0 mdma1 mdma2 udma0 udma1 udma2 udma3 udma4 udma5 *udma6
Cycle time: min=120ns recommended=120ns
PIO: pio0 pio1 pio2 pio3 pio4
Cycle time: no flow control=120ns IORDY flow control=120ns
Commands/features:
Enabled Supported:
Security Mode feature set
* Power Management feature set
* Write cache
* Look-ahead
* Host Protected Area feature set
* WRITE_BUFFER command
* READ_BUFFER command
* NOP cmd
* DOWNLOAD_MICROCODE
SET_MAX security extension
* 48-bit Address feature set
* Device Configuration Overlay feature set
* Mandatory FLUSH_CACHE
* FLUSH_CACHE_EXT
* General Purpose Logging feature set
* WRITE_ DMA MULTIPLE _FUA_EXT
* 64-bit World wide name
* IDLE_IMMEDIATE with UNLOAD
* WRITE_UNCORRECTABLE_EXT command
* READ,WRITE _DMA_EXT_GPL commands
* Segmented DOWNLOAD_MICROCODE
* Gen1 signaling speed (1.5Gb/s)
* Gen2 signaling speed (3.0Gb/s)
* Phy event counters
* Software settings preservation
* SMART Command Transport (SCT) feature set
* SCT LBA Segment Access (AC2)
* SCT Error Recovery Control (AC3)
* SCT Features Control (AC4)
* SCT Data Tables (AC5)
* Data Set Management TRIM supported (limit 8 blocks)
* Deterministic read ZEROs after TRIM
Security:
Master password revision code = 65534
supported
not enabled
not locked
frozen
not expired: security count
supported: enhanced erase
2min for SECURITY ERASE UNIT. 2min for ENHANCED SECURITY ERASE UNIT.
Logical Unit WWN Device Identifier: 500151795951d4b9
NAA : 5
IEEE OUI : 001517
Unique ID : 95951d4b9
Checksum: correct

19 April 2012

James Morrison: Issues with Appengine

I like App Engine, my wedding website runs on App Engine as well as a couple recent commercial projects. However, there are some annoyances that make a lot of the useful things I learned at Google not applicable.

  1. Chunked responses
    App Engine doesn't have a way of doing chunked responses.
    1.5. Processing after sending the responseMy annoyance here is that I can't send an early response and wait for some resource. Say I want to do 5 url fetches that I cache for a short period of time. If I want to reply in 250ms, I want to use any of the results I've gotten and reply to the user. Then once the rest of the fetches come in, I want to put them in the cache, so they will come back quickly the next time.
  2. Counters
    App Engine has crappy support for counters. You can shard your counters into the datastore: https://developers.google.com/appengine/articles/sharding_counters#counter_python or you can use taskqueues: http://blog.appenginefan.com/2009/10/non-sharded-counters-part-2-using-task.html . Now, how do you graph these counters over time, well, that is left as an exercise for the reader. Google has special datastores for stores and retrieving counters.
  3. Backends
    Backends in appengine are versioned separately from frontends. This sounds like a good idea, but to run the devserver with backends, the backends need to be in the same source tree. Thus backends share the same url space. Backends also share the same app.yaml, so again the url space is shared. Thus, if you make a change that you want to coordinate between the frontend and the backend, you need to change the application version in app.yaml, then rename all the backends in backends.yaml. If backends are supposed to be in the same source tree as frontends, then they should be prefixed with the application version. If backends should be versioned separately from frontends, then they shouldn't share url handlers from app.yaml.
    3.5 Uploading backends is slow
    Each backend is uploaded through appcfg.py separately. So if you are crazy and have one backend per backend level, then you need to upload 4 copies of the source code each time the backends get updated.
  4. Logging
    I want structured logs. Instead what you have to do is use the python logging module to write out human readable logs, then parse them out into the structure you want.
    http://code.google.com/p/google-app-engine-samples/source/browse/trunk/logparser/logparser.py

As a preemptive counter, 1.5 could be dealt with using backends and a background thread, except backends don't scale to the number of queries, so my use case above isn't fixed.

12 April 2012

Benjamin Mako Hill: My Setup

The Setup is an awesome blog that posts of interviews with nerdy people that ask the same four questions:
  1. Who are you, and what do you do?
  2. What hardware are you using?
  3. And what software?
  4. What would be your dream setup?
I really care about my setup so I am excited, and honored, that they just posted an interview with me! I answer questions about my setup often so I tried to be comprehensive with the hope that I will be able to point people to it in the future.

9 April 2012

Gunnar Wolf: Xilitla

On this Semana Santa (holy/major week), Regina and I took a little vacation: We went ~400Km North, to the magical Xilitla, in the Eastern part of San Luis Potos state. To get there, we went by the Sierra Gorda de Quer taro route: A beautiful but quite hard to drive road, crossing desert, forest and jungle through a very steep mountain ridge. What does hard to drive mean? It means that for ~200Km we had a speed average of 40-50Km/h. The road is in very good conditions, and traffic was quite light. And although our plans were to come back via the other ridge road (crossing Hidalgo state instead of Quer taro), we were persuaded to go the long way instead: We came back via San Luis Potos city, making ~700Km instead of ~400, but I'll concede it was a much easier drive. But although I take the road as an important part of the vacation, and although it was a very quick vacation, what is it we went to see there? Xilitla is a town at the beginning of the huasteca potosina region, with really exuberant vegetation, that captured Sir Edward James' heart back in the 1940s. Sir Edward, a noble Englishman, was good friends with several surrealist artists, and became one himself. After moving to Xilitla and buying an impressive chunk of jungle, in the 1960s he started building a surrealist garden in the middle of the jungle, which he continued to work on until his death, in 1984. We took some pictures, but of course, they pay very little tribute to the magic and beauty of the place. And going to the huasteca means going to places of nature, of many crystaline rivers. Yes, only three days (two of them spent getting there and back) are far too little to enjoy it. But even so, we went to the birth of river Huichihuay n (~45 minutes North of Xilitla) and to the Los Micos waterfalls (~20 minutes West of Ciudad Valles). Very nice places to visit, among so many others. We should go back to the huasteca soon! I uploaded many of the pictures here. They will not be syndicated on the planets that follow my blog on RSS (or for individuals following RSS, FWIW), but you will find them following the relevant links. And of course: I pay for a very cheap package on my hosting provider. Drupal often answers with an error page when the server is (even mildly) overloaded. So, feel free to hit reload if something appears unavailable.

5 April 2012

Benjamin Mako Hill: OH Man!

Since installing a whiteboard in our kitchen, conversations at the Acetarium have been moving in new and interesting directions. For example, Mika and I recently noticed that, when rotated correctly, the skeletal formula for 2,3-dimethyl-2-butanol looks pretty friendly! /copyrighteous/images/2,3-dimethyl-2-butanol-clean.png

4 April 2012

James Bromberger: Goodbye Linux.2.6.x

It s taken some time, but now none of my personal Linux hosts (4 in total) are running the 2.6 kernel any more. From the start (January) my company web host on Amazon EC2 has been running a 3.x kernel. My little Acer Aspire Revo low power home server, with attached disk pack that sits in my shed in a network cabinet has run 3.x for the last 6 months or so. My Linux laptop (Dell Studio 1558) which only recently got installed (and, since removing Windows, hasn t overheated once!) went to 3.x immediately. And the last piece of the puzzel is a virtual machine I ve had for many years with Bytemark.co.uk they re now offering a 3.2 kernel in their menu of selectable kernels. Not that 3.x is that much different than 2.6.3x; but its a line in the sand of feature and security thats easy to identify. But with nearly 15 years of looking at a 2.x kernel, its about time we moved to 3.x!

2 April 2012

Niels Thykier: Kudos to Jakub Adam, Miguel Landaeta and James Page

Credit where it is due and I believe it is due for Jakub Adam for packaging eclipse packages. If you use any of the eclipse packages provided the apt repositories for Wheezy or sid, it is very likely you have Jakub Adam to thank for it. I also believe that Miguel Landaeta and James Page deserve praise for their work. Miguel is to thank for the removal of libservlet2.4-java and updating its reverse dependencies not in that order ;-) . James Page, on the other hand, has been introducing and updating a lot of packages, noticeably the jenkins packages. Thank you and keep up the good work.

Next.

Previous.