OOPS: Delayed Instantiation
பலன் கருதி பொருள் ஈட்டல்
நலம் பேணும் நன்முறையாம்
பொருள் சேர்க்கும் நன்மக்கள்
காலத்தே ஈட்டி பலம் கொள்வாரே!
பலன் கருதி பொருள் ஈட்டல்
நலம் பேணும் நன்முறையாம்
பொருள் சேர்க்கும் நன்மக்கள்
காலத்தே ஈட்டி பலம் கொள்வாரே!
# view.php
# get the file id
$id = "";
if ( array_key_exists( "id", $_REQUEST ) ) {
$id = $_REQUEST["id"];
}
# open database connectivity
$conn = new Mongo();
$store = $conn->store;
$image = $store->image;
# fetch the file as per the id or just randomly
if ( $id != "" ) {
$query = array ( 'id' => $id );
$cursor = $image->find( $query );
}
else {
# set the html headers for refreshing the page every 3 sec.
header( 'Refresh: 3;' );
# Random fetch logic, get the count first.
$count = $image->find()->count();
$rand = rand( 1, $count-1 ); # generate a random number.
# skip several records of the cursor based on the random number
$cursor = $image->find()->skip( $rand )->limit(1);
}
# write output stream as JPEG content
header( 'Content-Type: image/jpeg' );
foreach ( $cursor as $obj ) {
# decode the data, and just write on the output stream.
echo base64_decode($obj["data"]);
}
# import.php
$dir = $_REQUEST["dir"];
if ( $dir == "" ) {
echo "<h2>Import directory cannot be empty</h2>";
exit;
}
$conn = new Mongo();
$db = $conn->store;
$image = $db->image;
echo "<ol>";
$dhandle = opendir( $dir );
while ( ($file = readdir( $dhandle )) != false ) {
$path = $dir."/".$file;
if ( is_dir( $path ) ) {
continue;
}
$path = str_replace( '\\', '/', $path );
$handle = fopen( $path, "rb" );
$data = fread( $handle, filesize( $path ) );
fclose( $handle );
if ( $data == false ) {
continue;
}
$key = preg_replace( "/[[:punct:]]/", "_", $file );
echo "<li>Importing $path (Key: $key)...";
try {
$image->insert( array( "id" => $key,
"data" => base64_encode( $data ) ), true );
echo "Success";
}
catch ( MongoCursorException $e ) {
echo "Exception: $e";
}
echo "</li>";
ob_flush();
}
echo "</ol>";
Within minutes, I was able to have a browser based slide show application, which protected all my image files in the Database without being exposed out in the folder system.
I am enjoying every bit of Mongo, and hope to develop several application using that in the future.

Use Cases
Sensors needed
Controller
One side of the Internet researchers are working on “Internet Anonymization”, an idea to protect one’s identity; on the other hand, Internet giants are pushing “Social Networks” where they build intelligence on the so-called privacy of people. What a weird world !?!

Powered by ScribeFire.
Developer Camp 2010
10th July 2010, Chennai

I had asked a couple of the audience boys to go for hunting more audience for the talk. See I were to advertise and promote my talk, which in fact is critical for everything in the world we live. One of the volunteers advised to use a microphone and start the talk. When I started the talk, I was surprised to see that people walked in to fill up the hall. The talk went on and on with a lot of interesting examples which made everyone introspect about the way we see and assess our neighbourhood. I am sure my audience have understood now that everything that we see around and solve could be mathematically modeled and be solved using computers. Hurray, we made it!!
Followed by that talk, I was asked to talk about Design patterns as a lot of developers had voted for that topic. Ok, I wanted a coffee break! Went to the cafeteria and made some light south Indian coffee. I added some pulverized sugar to my coffee and came back to the hall, while I was talking with another developer from LatentView technologies. To my surprise, the coffee tasted like made with sea water. Then I realized that I had added salt instead of sugar. I would like to greet the “brahaspathi” who kept the salt bowl near the coffee vending machine.

The talk on Design pattern started in a small room as the number of votes was ~10 (which is still a large number) in unconferences. When we started that talk, one of the volunteer said, he would want to record the talk which is a good idea. The talk started, and we found that lot of people started to come into the room and we had to move to a bigger hall as the number of audience was over 40, which is like “wow”. The talk went on for a while and we interacted about Singleton vs Multiton, Strategy, Factory vs Bridge patterns with lots of examples. Overall, it was a wonderful discussion forum where we learned a lot of insight about software design using design patterns.
If I were to use one word to describe the audience, I would say “intriguing”. It was an awesome experience for me to talk about some of my experiences to a wonderful audience that you had brought it. It is very rare to find a combination of patient, smart, involved, intelligent, experienced audience who crave for knowledge. Our talks helped us to introspect on to the technology that we have been practicing. The ambiance was very motivating in the sense, lot of natural light and spaciousness. Overall, I enjoyed every bit of it. I am little depressed that I could not enjoy the food as I was rushing back to office. Also, I wanted to take part in the fish bowl about Industry-Academic Co-op, but couldn’t. I am sure, there is a lot of people who got benefited by this program, in fact I heard that statement from a lot of the audience after the lecture/talk.
Thanks to Shiv Deepak for introducing DevCamp.
Thanks to Balaji Damodaran for inviting me to the DevCamp.
Thanks to Shaswat Nimesh for the photographs.

EFYTimes news article is here.
Powered by ScribeFire.

ACE 5.6.7 does not compile with STLport in Windows environment (I used vc9 on Windows Server 2008) because of the following header in ACE (ACE_wrappers/ace/checked_iterator.h), which wrongly assumes the existence of stdext::checked_array_iterator in the iterator header. A PRF is already submitted in the ACE mailing list (http://www.archivum.info/comp.soft-sys.ace/2008-07/00026/%5Bace-users%5D-Checked_iterator.h-problem-with-STLport..html)
# if defined (_MSC_VER) && (_MSC_FULL_VER >= 140050000)
// Checked iterators are currently only supported in MSVC++ 8 or better.
# include <iterator>
# endif /* _MSC_VER >= 1400 */# if defined (_MSC_VER) && (_MSC_FULL_VER >= 140050000)
template <typename PTR>
stdext::checked_array_iterator<PTR>
ACE_make_checked_array_iterator (PTR buf, size_t len)
{
return stdext::checked_array_iterator (buf, len);
}
# else
template <typename PTR>
PTR
ACE_make_checked_array_iterator (PTR buf, size_t /* len */)
{
// Checked iterators are unsupported. Just return the pointer to
// the buffer itself.
return buf;
}
# endif /* _MSC_VER >= 1400 */#endif /* ACE_CHECKED_ITERATOR_H */
I need to develop a solution to it. The easiest way to find a solution is to use some macro explicitly set by the STLport header, which is not set by any other STL libraries. I chose to use the _STLP_ITERATOR macro set by “stl/stlport/iterator” header.
#ifndef _STLP_ITERATOR
#define _STLP_ITERATOR# ifndef _STLP_OUTERMOST_HEADER_ID
# define _STLP_OUTERMOST_HEADER_ID 0×38
# include <stl/_prolog.h>
# endif# ifdef _STLP_PRAGMA_ONCE
# pragma once
# endif#if defined (_STLP_IMPORT_VENDOR_STD)
# include _STLP_NATIVE_HEADER(iterator)
#endif /* IMPORT */# ifndef _STLP_INTERNAL_ITERATOR_H
# include <stl/_iterator.h>
# endif# ifndef _STLP_INTERNAL_STREAM_ITERATOR_H
# include <stl/_stream_iterator.h>
# endif# if (_STLP_OUTERMOST_HEADER_ID == 0×38)
# include <stl/_epilog.h>
# undef _STLP_OUTERMOST_HEADER_ID
# endif#endif /* _STLP_ITERATOR */
The solution is the following, where I have added the !defined(_STLP_ITERATOR) condition along with the check for Visual Studio compiler version.
# if !defined(_STLP_ITERATOR) && defined (_MSC_VER) && (_MSC_FULL_VER >= 140050000)
// Checked iterators are currently only supported in MSVC++ 8 or better.
# include <iterator>
# endif /* _MSC_VER >= 1400 */# if defined (_MSC_VER) && (_MSC_FULL_VER >= 140050000)
template <typename PTR>
stdext::checked_array_iterator <PTR>
ACE_make_checked_array_iterator (PTR buf, size_t len)
{
return stdext::checked_array_iterator (buf, len);
}
# else
template <typename PTR>
PTR
ACE_make_checked_array_iterator (PTR buf, size_t /* len */)
{
// Checked iterators are unsupported. Just return the pointer to
// the buffer itself.
return buf;
}
#
endif /* _MSC_VER >= 1400 */#endif
/* ACE_CHECKED_ITERATOR_H */
To build (cross compilation) 32 bit C/C++ applications on 64 bit linux box, use “-m32″ as a compiler argument. You would need the following 32bit libraries in place.
#include <cstdio>
#include <iostream>
main()
{
std::cout << “C++” << std::endl;
printf ( “long: %d\n”, sizeof(long) );
printf ( “long long: %d\n”, sizeof(long long) );
return 0;
}
To compile in native 64bit:
[sudar@tstsrv12 tmp]$ g++ -m64 -o out64 code.cpp
[sudar@tstsrv12 tmp]$ ./out64
C++
long: 8
long long: 8
[sudar@tstsrv12 tmp]$ ldd out64
linux-vdso.so.1 => (0x00007fffc43fe000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x0000003e7be00000)
libm.so.6 => /lib64/libm.so.6 (0×0000000000601000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003e79e00000)
libc.so.6 => /lib64/libc.so.6 (0×0000000000886000)
/lib64/ld-linux-x86-64.so.2 (0×0000000000110000)
To compile in 32bit:
[sudar@tstsrv12 tmp]$ g++ -m32 -o out32 code.cpp
[sudar@tstsrv12 tmp]$ ./out32
C++
long: 4
long long: 8
[sudar@tstsrv12 tmp]$ ldd out32
linux-gate.so.1 => (0×00130000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0×00133000)
libm.so.6 => /lib/libm.so.6 (0×00223000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x0024c000)
libc.so.6 => /lib/libc.so.6 (0x0025a000)
/lib/ld-linux.so.2 (0×00110000)

There is a Simple way to capture the MAC address of the machine in Win32 environment. In Win32, UUID (version 1) uses MAC address & timestamp as the seeds for generating the UUID. In the UUID string, the last 6 bytes are the MAC address of the machine. UuidCreateSequential() is the Win32 API which is used to capture the MAC address via the UUID generated by it.
#include <rpc.h> // for UUID, UuidCreateSequential
#include <cstring> // for memcpy
#include <algorithm> // for std::swap
unsigned __int64
MACAddress( void ) const
{
UUID u;
::UuidCreateSequential( &u );
u.Data4[0] = u.Data4[1] = 0;
std::swap( u.Data4[0], u.Data4[7] );
std::swap( u.Data4[1], u.Data4[6] );
std::swap( u.Data4[2], u.Data4[5] );
std::swap( u.Data4[3], u.Data4[4] );
unsigned __int64 code;
::memcpy( &code, &u.Data4, sizeof(u.Data4) );
return code;
} // MACAddress
Let me share another hack. If you want to generate strings which do not repeat themselves, you could use UuidCreate() Win32 API, which generates unique UUIDs everytime the function is called. The UUID thus obtained can be converted to a number or a string depending upon the need, which guarantees non-repeatable ids.
I had configured raid STRIPE on 2 500Gb hard disks to create a 1TB stripped disk using Intel Raid controller on Asus D5Q motherboard. When I loaded CentOS 5.2, it identified the stripped disk correctly and formatted that too. After the installation is completed, CentOS 5.2 was not able to detect the disk array at all.
dmesg was showing messages like the following:
device-mapper: uevent: version 1.0.3
device-mapper: ioctl: 4.11.5-ioctl (2007-12-12) initialised: dm-devel@redhat.com
attempt to access beyond end of device
sda: rw=0, want=1953535936, limit=976773168
Buffer I/O error on device sda1, logical block 1953535872
attempt to access beyond end of device
When I tried “fdisk -l”, I got the following:
Disk /dev/sda: 500.1 GB, 500107862016 bytes
255 heads, 63 sectors/track, 60801 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytesDevice Boot Start End Blocks Id System
/dev/sda1 * 1 121602 976768033+ 83 LinuxDisk /dev/sdb: 500.1 GB, 500107862016 bytes
255 heads, 63 sectors/track, 60801 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytesDisk /dev/sdb doesn’t contain a valid partition table
The above is natural as RAID STRIPE is built using /dev/sda and /dev/sdb.
When I tried “dmraid -r”, I got
[root@tstsrv12 sudar]# dmraid -r
/dev/sda: isw, “isw_djiaeaj”, GROUP, ok, 976773166 sectors, data@ 0
/dev/sdb: isw, “isw_djiaeaj”, GROUP, ok, 976773166 sectors, data@ 0
Till this point, my /dev/mapper directory is:
[root@tstsrv12 sudar]# ll /dev/mapper/
total 0
crw——- 1 root root 10, 63 Feb 26 13:24 control
To enable the RAID multi-device, I had to run “dmraid -v -d -ay”, which returned:
[root@tstsrv12 sudar]# dmraid -v -d -ay
DEBUG: _find_set: searching isw_djiaeaj
DEBUG: _find_set: not found isw_djiaeaj
DEBUG: _find_set: searching isw_djiaeaj_Volume0
DEBUG: _find_set: searching isw_djiaeaj_Volume0
DEBUG: _find_set: not found isw_djiaeaj_Volume0
DEBUG: _find_set: not found isw_djiaeaj_Volume0
DEBUG: _find_set: searching isw_djiaeaj
DEBUG: _find_set: found isw_djiaeaj
DEBUG: _find_set: searching isw_djiaeaj_Volume0
DEBUG: _find_set: searching isw_djiaeaj_Volume0
DEBUG: _find_set: found isw_djiaeaj_Volume0
DEBUG: _find_set: found isw_djiaeaj_Volume0
DEBUG: checking isw device “/dev/sda”
DEBUG: checking isw device “/dev/sdb”
DEBUG: set status of set “isw_djiaeaj_Volume0″ to 16
DEBUG: set status of set “isw_djiaeaj” to 16
RAID set “isw_djiaeaj_Volume0″ already active
INFO: Activating GROUP RAID set “isw_djiaeaj”
DEBUG: _find_set: searching isw_djiaeaj_Volume0(null)1
DEBUG: _find_set: not found isw_djiaeaj_Volume0(null)1
RAID set “isw_djiaeaj_Volume0(null)1″ already active
INFO: Activating partition RAID set “isw_djiaeaj_Volume0(null)1″
DEBUG: freeing devices of RAID set “isw_djiaeaj_Volume0″
DEBUG: freeing device “isw_djiaeaj_Volume0″, path “/dev/sda”
DEBUG: freeing device “isw_djiaeaj_Volume0″, path “/dev/sdb”
DEBUG: freeing devices of RAID set “isw_djiaeaj”
DEBUG: freeing device “isw_djiaeaj”, path “/dev/sda”
DEBUG: freeing device “isw_djiaeaj”, path “/dev/sdb”
DEBUG: freeing devices of RAID set “isw_djiaeaj_Volume0(null)1″
DEBUG: freeing device “isw_djiaeaj_Volume0(null)1″, path “/dev/mapper/isw_djiaeaj_Volume0″
Now, my “/dev/mapper” directory is:
[root@tstsrv12 sudar]# ll /dev/mapper/
total 0
crw——- 1 root root 10, 63 Feb 26 13:24 control
brw-rw—- 1 root disk 253, 0 Feb 26 13:25 isw_djiaeaj_Volume0
brw-rw—- 1 root disk 253, 1 Feb 26 13:25 isw_djiaeaj_Volume0(null)1
Now, I am able to mount the RAID array on to my folder:
mount LABEL=/vendors /vendors
The output of “df” is now:
[root@tstsrv12 sudar]# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sdc1 29753556 3516168 24701576 13% /
/dev/sdc3 410600744 26227400 363179596 7% /opt
/dev/sdd1 473086160 202800 448464160 1% /backup
tmpfs 8154532 0 8154532 0% /dev/shm
/dev/mapper/isw_djiaeaj_Volume0(null)1
946176360 204572 897133388 1% /vendors
See, the RAID drive is mapped to /vendors folder.The Real Issue behind the problem is identified and a solution is presented at http://www.linuxquestions.org/questions/linux-kernel-70/centos-kernel-upgrade-breaks-dmraid-on-intel-software-raid-638450/. I am summarizing the changes here:
1. The real problem is the way dmraid is initialized at initrd’s init script. There is a bug in ‘mkinitrd’ script that generates ‘initrd**img’.
2. Open ‘/sbin/mkinitrd’ and search for “dmraid -ay -i -p”; It may appear something like “dmraid -ay -i -p “isw_cfgaijfacg_Volume0″. Look at the suffix “Volume0″, this suffix attachment has become the problem for us. dmraid does not like the Volume% suffix. It should have been initialized as “dmraid -ay -i -p “isw_cfgaijfacg”".
3. Let’s change the script to the following from:
emit “dmraid -ay -i -p \”$dmname\”"
to
dmnamecore=$(echo $dmname | sed -e ‘s/_Volumn[0-9]\+//;’)
emit “dmraid -ay -i -p \”$dmnamecore\”"
4. Generate a new initrd image by running “mkinitrd /boot/initrd-2.4.18-92.el5.img.dmraid `uname -r`”
5. Edit your /etc/grub.conf to use the newly created initrd image instead of the old one by editing the following line from “initrd /boot/initrd-2.4.18-92.el5.img” to “initrd /boot/initrd-2.4.18-92.el5.img.dmraid”
6. Reboot your machine.
Powered by ScribeFire.
