Friday, October 31, 2008

C/C++ __gnu_cxx hash_set

In this post, we go about __gnu_cxx::hash_set. As we saw before, we need to define our own HashFcn. We'll also need to define EqualKey if we're using custom data types. Another workaround is to overload the == operator inside the std namespace, then you don't have to provide your own EqualKey. It should look like:

namespace std {
bool operator==(const dnsRecord& rec1, const dnsRecord& rec2) {
return rec1.ip == rec2.ip;
}
}
However, I prefer the first solution, and we'll use it in the code below. We also define our own hasher and pass it to the hash_set declaration instead of specializing the hash template inside the __gnu_cxx namespace as we did in the previous post.
#include <iostream>
#include <ext/hash_set>

using namespace std;
using namespace __gnu_cxx;

class dnsRecord {
public:
unsigned long ip;
string domainName;
};

class MyHasher {
public:
size_t operator()(const dnsRecord &r) const
{
return h(r.domainName.c_str());
};

private:
__gnu_cxx::hash<char*> h;
};

class MyComparator
{
public:
bool operator()(const dnsRecord& rec1, const dnsRecord& rec2) const {
return rec1.ip == rec2.ip;
}
};

int main(int argc, char *argv[])
{
hash_set<dnsRecord, MyHasher, MyComparator> hset;
dnsRecord rec1;
dnsRecord rec2;
dnsRecord rec3;
rec1.ip = 989798l; rec1.domainName = "dname1";
rec2.ip = 112334l; rec2.domainName = "dname2";
rec2.ip = 808323l; rec3.domainName = "dname3";
hset.insert(rec1);
hset.insert(rec2);
hset.insert(rec3);

dnsRecord rec4;
rec4.ip = 0;
rec4.domainName = "dname1";

hash_set<dnsRecord, MyHasher, MyComparator>::iterator it;
for(it = hset.begin(); it != hset.end(); it++)
cout << (*it).ip << ", " << (*it).domainName << endl;

rec4.domainName = "dname3";
hset.erase(rec4);

rec4.domainName = "dname3";
if(hset.find(rec4) == hset.end())
cout << "Successfully removed dname3" << endl;
else
cout << "Error!" << endl;

return EXIT_SUCCESS;
}

Tuesday, October 28, 2008

C/C++ __gnu_cxx hash_map

I had some trouble getting this to work, so I decided to post a quick tutorial...

We start with a simple hash_map with int keys and string values:

#include <iostream>
#include <ext/hash_map>

using namespace std;
using namespace __gnu_cxx;

int main(int argc, char *argv[])
{
//declaration
hash_map<int, string> hmap;

//insertion
int ints[] = {213, 432, 45, 10};
string strings[] = {"s1", "s2", "s3", "s4"};

for(int i = 0; i < 4; i ++)
hmap[ints[i]] = strings[i];

//iteration
for(hash_map<int, string>::iterator it = hmap.begin(); it != hmap.end(); it ++)
cout << (*it).first << " => " << (*it).second << endl;

//deletion
hmap.erase(ints[0]);
cout << "Removed: " << ints[0] << endl;

//search
if(hmap.find(ints[0]) == hmap.end())
cout << "Couldn't find: " << ints[0] << endl;

if(hmap.find(ints[1]) != hmap.end())
cout << "Found: " << ints[1] << ": " << hmap[ints[1]] << endl;

return EXIT_SUCCESS;
}
It gets a little bit messy when using string keys. Since hash_map is not part of the standard STL, there're some issues you need to worry about. In our case, there's no implementation provided for hash, or in other words, the hash_map can't hash strings by default. Strangely though, hash is defined for char*, and we'll make use of that fact.

You can either specialize the hash template for std::string inside the __gnu_cxx namespace or define your own hash functor and use it in your hash_map declaration. Remember that hash_map is declared as hash_map<Key, Type, HashFcn, EqualKey, Alloc>. I prefer the second solution, you can check it out here. For now, we'll go on with the first one.
#include <iostream>
#include <ext/hash_map>

using namespace std;
using namespace __gnu_cxx;

namespace __gnu_cxx {
template<>
struct hash<std::string>
{
hash<char*> h;
size_t operator()(const std::string &s) const
{
return h(s.c_str());
};
};
}

typedef struct {
int x;
int y;
} point;

int main(int argc, char *argv[])
{
//declaration
hash_map<string, point> hmap;

//insertion
string strings[] = {"p1", "p2", "p3", "p4"};

point a, b, c, d;
a.x = a.y = 0;
b.x = b.y = 1;
c.x = c.y = 2;
d.x = d.y = 3;

hmap[strings[0]] = a;
hmap[strings[1]] = b;
hmap[strings[2]] = c;
hmap[strings[3]] = d;

//iteration
for(hash_map<string, point>::iterator it = hmap.begin(); it != hmap.end(); it ++)
cout << (*it).first << " => (" << (*it).second.x << ", " << (*it).second.y << ")" << endl;

//deletion
hmap.erase(strings[1]);
cout << "Removed: " << strings[1] << endl;

//search
if(hmap.find(strings[1]) == hmap.end())
cout << "Couldn't find: " << strings[1] << endl;

if(hmap.find(strings[0]) != hmap.end())
cout << "Found: " << strings[0] << ": (" << hmap[strings[0]].x << ", " << hmap[strings[0]].y << ")" << endl;

return EXIT_SUCCESS;
}

Repair Network Connection in Ubuntu

I'm running Ubuntu 8.04 under VirtualBox on Vista. I've created a virtual network interface for the vm and bridged my network connections. The network connection was down for a while, so when I started vm there was no connection. After a while however, the connection was restored and I was able to use it on Vista. The problem is, the vm didn't feel that the connection was restored. I googled for that and got a useful thread on ubuntuforums. I applied the solution I found there and added a launcher to my panel.

Right-click the panel -> "Add to Panel..." -> "Custom Application Launcher" then enter:

Type: Application
Name: NetRepair
Command: gksudo /etc/init.d/networking restart
Comment: Repair Network Connection
Click OK.

The launcher should appear on your panel. When you click the icon, it'll run the command you entered and will ask for your password. Hopefully, this should 'repair' your network connection.

btw, this is my first post from ubuntu!

Friday, August 29, 2008

Escapement mechanisms in mechanical clocks

I was fascinated by the simplicity and elegance of these mechanisms, yet it's not comprehensible at the first glance which adds to its charm. Illustrated above is the grasshopper escapement which was invented by British clockmaker John Harrison around 1722. Read more about that here.

Tuesday, August 12, 2008

Watching Beijing 2008 Olympic Games

it's very interesting to watch the competitors pushing the limits of our perception of human capabilities both physical and mental, as they strive for perfection and withstand termendous stress, being watched by millions of people worldwide, and also how they represent their nations, attempting to bring back as much glory as possible, and to be rewarded with medals and world records, with the national anthem playing in the background and the flag hanging above their heads.

Wednesday, July 9, 2008

Alarm Clocks For Dummies

You should always remember to switch on the alarm clock after you set it or else, it will never ring!

I used to stay up late during the last week and these days, I have to finish some errands early in the morning so I had to use the alarm clock, I decide when I'd like to wake up, set the alarm and go to sleep happily, do you see a problem? I didn't switch the alarm on!

What's even more interesting, I wake up around the same time I set the alarm to for no obvious reason! It's strange because I have no certain sleep patterns and the times I set the alarm to are quite random, but somehow whether I switch the alarm on or not, I wake up in time!

I thought that was interesting and funny, but I don't recommend you try it on an important day :)

Thursday, June 26, 2008

Installing JDK on Vista 64-bit

I needed to work on some Java SE application and all the machines I have now run Vista 64-bit, I downloaded the JDK 6 update 6 for Windows x64 from the Sun website but it doesn't seem to work at all, the setup went okay but then, Eclipse craches just after showing the splash screen and the NetBeans installer says that it can't find the jdk on my computer, I installed the 32-bit jdk and everything worked fine.

update: I gave it another look and I found that the Eclipse I got was 32-bit and I read on the web that the NetBeans setup has issues and some say that you can ignore the installer, extract the zip and run, so maybe there was nothing wrong with neither the JKD nor Vista, it was just different configurations that didn't match.