Saturday, May 31, 2008

From MySQL to PostgreSQL

Why? In brief, it is said that mysql is not as stable as postgresql. Postgresql or pgsql focuses on a single database engine as compared to mysql which has a pluggable engine architecture and has multiple engines. Also postgresql is well designed as compared to mysql. psql console is much better than mysql console (you will realize it when you use it). It is supposed to be much more scalable and have better performance than mysql. Pgsql uses a more standard sql language as compared to mysql.

Both have fulltext search capabilities. Though it is said that the fulltext search of pgsql is better than mysql, but i still have to look into it. And the most important of all - pgsql is a full fledged RDBMS, whereas mysql (using the default MyISAM engine) is a DBMS. Data integrity is better in pgsql as compared to mysql. Also i have seen lots of corrupt tables in mysql(might be because i have used mysql throughout my career), and have heard(on the web) that mysql is more crash prone than pgsql.

The final question then comes down to speed. Which one is faster? Logically, since mysql is a DBMS and it does not maintain foreign key relations, it should be faster than pgsql. I will benchmark and blog the results sometime later.

Basically, pgsql is more stable & reliable than mysql. Pgsql has a rich set of features and data integrity is well maintained in pgsql.

Lets look at some of the steps you need to follow if you decide to switch to pgsql from mysql:


  • First of all, down the database engine from www.postgresql.org. Untar it and compile it.

    $ tar -xvjf postgresql-8.3.1.tar.bz2
    $ cd postgresql-8.3.1
    $ ./configure --with-openssl --enable-thread-safety --with-libxml
    (check out the options that you need using ./configure --help)
    $ make
    $ sudo make install

    By default this will install pgsql in /usr/local directory

  • Next, create a user postgres and the database directory for pgsql
    $ adduser postgres
    $ mkdir /usr/local/pgsql/data
    $ chown postgres.postgres /usr/local/pgsql/data

  • Create the pgsql database:
    Firstly, log into mysql and do
    mysql> show variables like '%character';
    +--------------------------+-----------------------------------------------------------------+
    | Variable_name | Value |
    +--------------------------+-----------------------------------------------------------------+
    | character_set_client | latin1 |
    | character_set_connection | latin1 |
    | character_set_database | latin1 |
    | character_set_filesystem | binary |
    | character_set_results | latin1 |
    | character_set_server | latin1 |
    | character_set_system | utf8 |
    | character_sets_dir | /usr/local/mysql-5.1.24-rc-linux-x86_64-glibc23/share/charsets/ |
    +--------------------------+-----------------------------------------------------------------+

    You will see here that the character set for the database & server is latin1. Even though the default database is utf8. If you create the pgsql database using the default command, it will create a utf8 database and you will face problems importing your data into it.

    So, create a latin1 database for pgsql
    $ su - postgres
    $ initdb -D /usr/local/pgsql/data -E latin1 --locale=C

  • Now you have postgresql installed and you can create your own databases and tables. But before proceeding forward, do psql from user postgres's shell.

    start pgsql:

    $ /usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data >~/logfile 2>&1 &

    $ psql
    Welcome to psql 8.3.1, the PostgreSQL interactive terminal.

    Type: \copyright for distribution terms
    \h for help with SQL commands
    \? for help with psql commands
    \g or terminate with semicolon to execute query
    \q to quit

    postgres=#


    The =# says that you are logged in as a super user. To login as another user, create another user and give him required privileges. And then su to the user and login to pgsql from that user.

    postgres=# CREATE USER jayant WITH CREATEDB INHERIT LOGIN;
    postgres=# \q
    $ su - jayant
    $ createdb test
    $ psql test
    test=>


    Here => says that i am not a super user. Now i can create my tables in the test database or create more databases.

    For help on how to create users do

    test=> \h CREATE USER

    And it will give you the syntax for creating a user in postgres

  • To convert your table from mysql format to pgsql format, just dump the table and data separately from mysql using the mysqldump --no-data and mysqldump --no-create-info respectively.

    And you will get two files <mysql_table>.sql & <mysql_table_data>.sql

    download a perl script mysql2pgsql.perl which will be able to convert the sql for your table into appropriate format for pgsql.

  • Now load the table and data into pgsql

    $ psql -f <mysql_table>.sql
    $ psql -f <mysql_table_data>.sql



It looks simple, but it is not that simple. Some points that need to be remembered while using pgsql


  • auto_increment column is defined using the SERIAL word. So, to create an auto_increment primary key column the syntax would be

    CREATE TABLE MYTABLE(ID SERIAL NOT NULL PRIMARY KEY, ....);

    This would also create a sequence mytable_id_seq.

  • While importing data from the mysql dump you may get some warning about backslash escapes in your sql. To remove this warning you will have to set the escape_string_warning to off.

    edit your postgresql.conf file which can be found in the /usr/local/pgsql/data directory and change the variable to off. Now restart pgsql.

  • To start and stop pgsql following commands can be used

    start pgsql
    $ /usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data >~/logfile 2>&1 &

    stop pgsql
    $ /usr/local/pgsql/bin/pg_ctl stop -D /usr/local/pgsql/data

  • Another thing to note is that you dont have custom queries like 'insert ignore into', 'replace into' or 'insert into ... on duplicate key...' in pgsql. You will need to create rules on the table to handle these cases.

    test=> \h create rule
    Command: CREATE RULE
    Description: define a new rewrite rule
    Syntax:
    CREATE [ OR REPLACE ] RULE name AS ON event
    TO table [ WHERE condition ]
    DO [ ALSO | INSTEAD ] { NOTHING | command | ( command ; command ... ) }


    So for exampe to create an insert ignore into type of rule, the following rule needs to be created.

    test=> CREATE OR REPLACE RULE "insert_ignore_mytable" AS ON INSERT TO "mytable" WHERE EXISTS (SELECT 1 FROM "mytable" WHERE id = NEW.id) DO INSTEAD NOTHING;

  • Remember SHOW PROCESSLIST of mysql which used to list down all the processes.

    To list down all the processes for pgsql following command needs to be run

    test=> select * from pg_stat_activity;



We will looking more and more into pgsql.

Friday, May 30, 2008

python programming - threading

There are a few options for threading in python. I wont be exploring all the options here. I would simply try to make this blog entry simple, sweet and short.

There are two modules in python which provide threading capabilities - "thread" module and "threading" module. The thread module is very basic. So lets focus on the threading module

To use the threading module, all you have to do is

import threading

class mythread(threading.Thread):
  def run(self):
    <your code>

mythread().start()
mythread().start()


This will create 2 threads running <your code>

That was quick right. Now lets see some basic stuff like Thread Naming, Thread isAlive and join which is used in most threading environments...

Naming a thread:

import threading

class mythread(threading.Thread):
  def run(self):
    print 'my name is ', self.getName()

foo = mythread()
foo.setName('Foo')
foo.start()

bar = mythread()
bar.setName('Bar')
bar.start()

mythread().start()


Run the program:

$ python threadname.py

And see the output

my name is Foo
my name is Bar
my name is Thread-3


Checking if the thread is still alive:

import threading
import time

class mythread(threading.Thread):
  def run(self):
    print 'my name is ', self.getName()

class aliveth(threading.Thread):
  def run(self):
    time.sleep(10)
    print 'my name is ', self.getName()

myt = mythread()
myt.setName('mythread')
myt.start()
if myt.isAlive():
  print 'myt is alive'
else:
  print 'myt is dead'

alt = aliveth()
alt.setName('aliveth')
alt.start()
if alt.isAlive():
  print 'alt is alive'
else:
  print 'alt is dead'

And check the output

my name is mythread
myt is dead
alt is alive
my name is aliveth


Joining threads:

You can use the thread.join() method to make a thread wait for another thread

import threading
import time

class ThreadOne ( threading.Thread ):
  def run ( self ):
    print 'Thread', self.getName(), 'started.'
    print self.getName(), ': sleeping '
    time.sleep ( 5 )
    print 'Thread', self.getName(), 'ended.'

class ThreadTwo ( threading.Thread ):
  def run ( self ):
    print 'Thread', self.getName(), 'started.'
    print self.getName(), ': waiting for ', thingOne.getName()
    thingOne.join()
    print 'Thread', self.getName(), 'ended.'

class ThreadThree (threading.Thread):
  def run(self):
    print 'Thread', self.getName(), 'started'
    print self.getName(),': Not waiting for any other thread'
    print 'Thread', self.getName(), 'ended.'

thingOne = ThreadOne()
thingOne.start()
thingTwo = ThreadTwo()
thingTwo.start()
thingThree = ThreadThree()
thingThree.start()


And check the output

Thread Thread-1 started.
Thread-1 : sleeping
Thread Thread-2 started.
Thread-2 : waiting for Thread-1
Thread Thread-3 started
Thread-3 : Not waiting for any other thread
Thread Thread-3 ended.
Thread Thread-1 ended.
Thread Thread-2 ended.


This covers most of the stuff for programming threads in python. We will look into thread synchronization issues some other time.

Friday, May 23, 2008

python postgresql connectivity

It is sweet and simple. Got it running in 2 minutes...


  • Download psycopg 2.0 (yup that's the name) from http://www.initd.org

  • Extract the library
    $ tar -xvzf psycopg2-2.0.7.tar.gz

  • Build the extension
    $ cd psycopg2-2.0.7/
    $ python setup.py build

  • And install the extension
    $ sudo python setup.py install

  • Create a simple script
    $ vim pypgsql.py


    import psycopg2

    try:
        conn = psycopg2.connect("dbname='test' user='jayant' host='localhost' password='secret'")
    except:
        print "unable to connect to db"

    cur = conn.cursor()
    cur.execute("""select datname from pg_database""")
    rows = cur.fetchall()

    print "\nShow me the databases\n"
    for row in rows:
        print " ", row[0]


    Save the pypgsql.py file.

  • And finally run the script
    $ python pypgsql.py

    Output:

    Show me the databases

      template1
      template0
      postgres
      test

Monday, May 19, 2008

The forbidden kingdom


Another jackie chan movie. And this time jet li is in it too. And then there is this sweet girl Liu Yifei (difficult to spell though). Jackie chan movies are always full of fun and kung-fu.

The story revolves around a young american kid who is a fan of kung-fu and watches tons of chinese kung-fu movies. He sees a golden staff in the pawn shop w
here he gets his movies from and is drawn to ancient china where he is the saviour who has to return the staff to the monkey king to save the kingdom from t
he evil warlord. The ancient chinese world is full of immortals. And he sees this sweet girl and falls for her. Jackie chan plays the part of a drunk and jet li the part of a silent monk.

A totally imaginary story. If you would have followed the recent movies from jackie chan - the Myth and some others (i dont remember the names). But in all
these movies there is this stuff about ancient chinese civilizations, transportation of other worlds and a relic of huge importance and power that has to be saved from evil.

Though it does make the stories interesting but they still tend to be repetative. I liked the movie. I generally like movies with kung-fu and sweet girls. It is worth a watch

Thursday, May 15, 2008

python on web - getting started : building your first app

I would be focusing here on the following tasks.


  • install pylons.

  • create a helloworld app using pylons.

  • install genshi.

  • change template engine.

  • deploy on apache using mod_wsgi.



Install Pylons

Run the following:

$ easy_install Pylons==0.9.6.1
OR
$ easy_install -f http://pylonshq.com/download/ Pylons==0.9.6.1

More details at http://wiki.pylonshq.com/display/pylonsdocs/Installing+Pylons


Create helloworld app

$ paster create -t pylons helloworld

A directory helloworld with the following structure is created

jayant@jayantbox:~/myprogs/python/helloworld$ ls -lh
total 44K
drwxr-xr-x 4 jayant jayant 4.0K 2008-04-25 17:47 data
-rwxr-xr-x 1 jayant jayant 1.5K 2008-05-15 10:41 development.ini
drwxr-xr-x 2 jayant jayant 4.0K 2008-04-25 17:47 docs
drwxr-xr-x 2 jayant jayant 4.0K 2008-04-25 17:47 ez_setup
drwxr-xr-x 9 jayant jayant 4.0K 2008-05-14 19:52 helloworld
drwxr-xr-x 2 jayant jayant 4.0K 2008-04-25 17:47 helloworld.egg-info
-rwxr-xr-x 1 jayant jayant 79 2008-04-25 17:47 MANIFEST.in
-rwxr-xr-x 1 jayant jayant 463 2008-04-25 17:47 README.txt
-rwxr-xr-x 1 jayant jayant 1.2K 2008-04-25 17:47 setup.cfg
-rwxr-xr-x 1 jayant jayant 865 2008-04-25 17:47 setup.py
-rwxr-xr-x 1 jayant jayant 507 2008-04-25 17:47 test.ini

To run the app, from within the helloworld directory do

jayant@jayantbox:~/myprogs/python/helloworld$ paster serve --reload development.ini
Starting subprocess with file monitor
Starting server in PID 15555.
serving on 0.0.0.0:5000 view at http://127.0.0.1:5000

Create a test.html in the <path_to_helloworld>helloworld/helloworld/public directory

<html>
<body>
Hello World!!
</body>
</html>


And point your browser to http://127.0.0.1:5000/test.html to see the "Hello World!!" page.

Now lets create a controller and try printing info through a template.

jayant@jayantbox:~/myprogs/python/helloworld$ paster controller hello
Creating /home/jayant/myprogs/python/helloworld/helloworld/controllers/hello.py
Creating /home/jayant/myprogs/python/helloworld/helloworld/tests/functional/test_hello.py

Edit the <path_to_helloworld>/helloworld/helloworld/controllers/hello.py file and put in some python code

import logging

from helloworld.lib.base import *

log = logging.getLogger(__name__)

class HelloController(BaseController):

    def index(self):
        # Return a rendered template
        # return render('/some/template.mako')
        # or, Return a response
        return 'Hello World'
    def serverinfo(self):
        import cgi
        import pprint
        c.pretty_environ = cgi.escape(pprint.pformat(request.environ))
        c.name = 'Jayant Kumar'
        return render('serverinfo.mako')

Now create a template serverinfo.mako in <path_to_helloworld>/helloworld/helloworld/templates

<h2>
Server info for ${request.host}
</h2>

<p>
The URL you called: ${h.url_for()}
</p>

<p>Hi there ${c.name or c.full_name or "Joe Smith"}</p>

<p>
The name you set: ${c.name}
</p>

<p>The WSGI environ:<br>
<pre>${c.pretty_environ}</pre>
</p>

Edit the <path_to_helloworld>/helloworld/helloworld/config/routing.py file and check if the following code there in the "CUSTOM ROUTES" section

map.connect('', controller='hello', action='index')
map.connect(':controller/:action/:id')
map.connect('*url', controller='template', action='view')

This means that an empty URL is matched to the index action of the hello controller. Otherwise, the route mapper looks for URLs in the form controller/action/id, but if action or controller are not specified the request is routed to the view action of the templates controller (created by the Pylons template). This raises a 404 error by default

Now go to http://localhost:5000/hello/hello and http://localhost:5000/hello/serverinfo and check out the output.

Installing genshi and switching the template engine

$ easy_install Genshi

To enable genshi in your project edit the <path_to_helloworld>/helloworld/helloworld/config/environment.py file and change the template engine from mako to genshi

    config.init_app(global_conf, app_conf, package='helloworld',
        template_engine='genshi', paths=paths)


Now create a new template in <path_to_helloworld>/helloworld/helloworld/templates, say serverinfo.html and put in the following code

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://genshi.edgewall.org/"
lang="en">
<h2>
Testing...
</h2>

<p>Hi there ${c.name}</p>

<p>
The name you set: ${c.name}
</p>

<p>The WSGI environ:<br/>
<div py:content="c.pretty_environ">Pretty Environ</div>
</p>
</html>

And change your <path_to_helloworld>/helloworld/helloworld/controllers/hello.py to render the new template

        return render('serverinfo')

And check the output at http://localhost:5000/hello/hello and http://localhost:5000/hello/serverinfo

Deploy using mod_wsgi

For those who have not yet configured mod_wsgi, you can get mod_wsgi from http://code.google.com/p/modwsgi/.

Simply untar it and do a

./configure --with-apxs=/path/to/apache/bin/apxs
make
sudo make install


Bingo and you have the mod_wsgi.so file in your apache/modules directory

Change the httpd.conf and add the following

LoadModule wsgi_module modules/mod_wsgi.so

to load the wsgi module and then deploy the hello world application

WSGIDaemonProcess hello thread=25
WSGIScriptAlias /hello "/path/to/apache/anydirectory/hello.wsgi
<Location /hello>
        WSGIProcessGroup hello
        WSGIReloadMechanism Process
</Location>


This says that the application helloworld would run as a separate process with 25 threads. And since we have also enabled process reload mechanism available with mod_wsgi-2.0, all that is needed to restart/reload the application is to touch/change the wsgi script modification time.

Wait a minute, we did not create the hello.wsgi script. Create a directory in /path/to/apache or anywhere where apache has read access and where you want to keep your application startup scripts. So what i did was.

$ mkdir /path/to/apache/wsgi

And create a hello.wsgi inside it

cd /path/to/apache/wsgi
vim hello.wsgi


Add the following code here

import os, sys
sys.path.append('/path/to/python/application/helloworld')

from paste.deploy import loadapp

application = loadapp('config:/path/to/python/application/helloworld/development.ini')


And we are done. Please note that the /path/to/python/application should be readable and executable by apache. Or you can do (very unsafe - not recommended on production servers)

chmod -R a+rx /path

Now simply restart apache and point your browser to

http://localhost/hello/
and
http://localhost/hello/hello/serverinfo

To see the output.

Source:
http://wiki.pylonshq.com/display/pylonsdocs/Installing+Pylons
http://wiki.pylonshq.com/display/pylonsdocs/Getting+Started
http://wiki.pylonshq.com/display/pylonsdocs/Using+Other+Template+Languages
http://code.google.com/p/modwsgi/wiki/InstallationInstructions
http://code.google.com/p/modwsgi/wiki/IntegrationWithPylons

Python on web - getting started : selecting the tools

Why am i writing this? Well, because i felt that there are so many options, it is difficult to select an option for yourself. I was confused for quite some time in terms of what framework to use, what templating engine to use, which ORM layer to use and how to deploy the app on the web.

First of all, lets start of with the framework. The major frameworks are Django, TurboGears and pylons. Django is supposed to be the best framework from among the three. But Django is very tightly integrated to its template engine and ORM layer. And any sort of customization is not only difficult but also slows down the app. But it is good thing to start off python-on-web as a beginer. And its tight integration also accounts for its speed. It is the fastest framework among all of them. Take a look at some of the benchmarks on web here
http://www.rkblog.rk.edu.pl/w/p/simple-python-frameworks-benchmark/ And http://www.alrond.com/en/2007/feb/04/in-addition-to-the-test-of-mvc-frameworks/

Django is a good framework to use if you are building a small site with default settings. But when you need to have an enterprise level site with customizations, it is better to use something like Turbogears or Pylons. Turbogears is good and has "Turbogears Widgets" but it lacks proper documentation. TurboGears uses CherryPy whereas Pylons uses paste. I felt pylons to be much easier to use and easier to configure. Pylons has a very small base though it is not as fast as Django. There are lots of comparisons available on the net - just google for it. http://nxsy.org/unscientific-and-biased-comparison-of-django-pylons-and-turbogears gives a detailed comparison of different features of all the 3 frameworks.

After selecting Pylons as my framework, i have tons of options with respect to templating engine. I can use the default mako or kid or genshi or Cheetah (complete list available at http://projects.dowski.com/projects/buffet). I took a look on the performance benchmark and ease of use of all of them (from googlebaba ofcourse). And what i could figure out was that mako is the fastest template engine available. Genshi is a successor of kid and has a very clean xml-based integration. Which means that if i am using genshi, the html designer would not be able to see the code embedded within templates. So, i would prefer to use Mako or Genshi depending on the requirements. A list of different types of available template engines can be obtained from http://wiki.python.org/moin/Templating. Benchmarks are available here http://www.kuwata-lab.com/tenjin/pytenjin-users-guide.html#benchmark. Changing template engine for pylons is described here http://wiki.pylonshq.com/display/pylonsdocs/Using+Other+Template+Languages

I did not do any DB operations, so i did not go into selecting the ORM layer. Anyways, i always prefer to write my own queries instead of letting the ORM layer decide what query to fire. SQLAlchemy seems good though if you plan to use an ORM layer. SQLObject is also there, but it is old.

For deployment few options available are mod_wsgi, mod_python and the default paster. The paster server comes integrated with pylons and ofcourse cannot be used for production level deployment. mod_wsgi looked easy to use and is also supposed to be a small bit faster than mod_python. You can look at http://wiki.pylonshq.com/display/pylonscookbook/Production+deployment+using+mod_python for mod_python or http://code.google.com/p/modwsgi/wiki/IntegrationWithPylons or mod_wsgi integration.

Next we would look at building and deploying the "hello world" application

Monday, May 12, 2008

The Iron Man


Yup, another super hero movie. And though you would be tired of superhero movies by now and you would not want to see another super hero movie, you would still go and watch this movie. I am not telling you to watch the movie. It is just that your inner self would not allow you to rest until you have watched the movie.

So what do we have here. Yes there is Tony Stark, a man who does not care for anything or anybody. He gets captured in Afghanistan by some very bad Afghanistanis who want him to prepare some missiles for them. And Tony makes an iron man of himself to get out of there. He escapes and realizes the power that an Iron Man could give him to fight against evil and save innocent lives. And then he makes a very advanced iron man and uses it to save the people in Afghanistan from those bad Afghanistanis.

The concept is the same - good against evil. The creation of another super hero. Which is all crap.

The good thing is all the technical stuff shown. A bit of comedy. And the action ofcourse - the special effects. And these are the things that you would want to watch in the movie.

That was the reason why i went to see the movie.

Thursday, May 08, 2008

Cities in india...

Scenario 1
Two guys are fighting and a third guy comes along, then a fourth and they start arguing about who's right.

You are in Kolkata

Scenario 2
Two guys are fighting and a third guy comes along, sees them and walks on.

That's Mumbai

Scenario 3
Two guys are fighting and a third guy comes along & tries to make peace.The first two get together & beat him up.

That's Delhi

Scenario 4
Two guys are fighting. A crowd gathers to watch. A guy comes along And quietly opens a chai-stall

That's Ahmedabad.

Scenario 5
Two guys are fighting and a third guy comes he writes a software Program to stop the fight. But the fight doesn't stop b'cos of a bug in the
program.

That's Bangalore

Scenario 6
Two guys are fighting. A crowd gathers to watch. A guy comes along And quietly says that "AMMA" doesn't like all this nonsense. Peace comes in.

That's Chennai.

Scenario 7
Two guys are fighting. Third guy comes along with a carton of beer. All sit together drinking beer and abusing each other and all go home being friends.

You are in Goa

Scenario 8
Two guys are fighting. Both of them take time out and call their Friends on mobile. Now 50 guys are fighting.
. .. . . . . . . . . . . . . . . . . . You are DEFINITELY IN Haryana

Tuesday, May 06, 2008

java: Arrays vs ArrayLists vs Vectors vs LinkedLists

The question is which one to use and when? Which one is more efficient? Lets look into each one of them.

An array is basically a fixed size collection of elements. The bad point about an array is that it is not resizable. But its constant size provides efficiency. So arrays are better to use when you know the number of elements available with you.

ArrayList is another collection where the number of elements is resizable. So if you are not sure about the number of elements in the collection use an ArrayList. But there are certain facts to be considered while using ArrayLists.

=> ArrayLists is not synchronized. So if there are multiple threads accessing and modifying the list, then synchronization might be required to be handled externally.
=> ArrayList is internally implemented as an array. So whenever a new element is added an array of n+1 elements is created and then all the n elements are copied from the old array to the new array and then the new element is inserted in the new array.
=> Adding n elements requires O(n) time.
=> The isEmpty, size, iterator, set, get and listIterator operations require the same amount of time, independently of element you access.
=> Only Objects can be added to an ArrayList
=> Permits null elements

If you need to add a large number of elements to an ArrayList, you can use the ensureCapacity(int minCapacity) operation to ensure that the ArrayList has that required capacity. This will ensure that the Array is copied only once when all the elements are added and increase the performance of addition of elements to an ArrayList. Also inserting an element in the middle of say 1000 elements would require you to move 500 elements up or down and then add the element in the middle.

The benefit of using ArrayList is that accessing random elements is cheap and is not affected by the number of elemets in the ArrayList. But addition of elements to the head of tail or in the middle is costly.

Vector is similar to ArrayList with the difference that it is synchronized. It offers some other benefits like it has an initial capacity and an incremental capacity. So if your vector has a capacity of 10 and incremental capacity of 10, then when you are adding the 11th element a new Vector would be created with 20 elements and the 11 elements would be copied to the new Vector. So addition of 12th to 20th elements would not require creation of new vector.

By default, when a vector needs to grow the size of its internal data structure to hold more elements, the size of internal data structure is doubled, whereas for ArrayList the size is increased by only 50%. So ArrayList is more conservative in terms of space.

LinkedList is much more flexible and lets you insert, add and remove elements from both sides of your collection - it can be used as queue and even double-ended queue! Internally a LinkedList does not use arrays. LinkedList is a sequence of nodes, which are double linked. Each node contains header, where actually objects are stored, and two links or pointers to next or previous node. A LinkedList looks like a chain, consisting of people who hold each other's hand. You can insert people or node into that chain or remove. Linked lists permit node insert/remove operation at any point in the list in constant time.

So inserting elements in linked list (whether at head or at tail or in the middle) is not expensive. Also when you retrieve elements from the head it is cheap. But when you want to randomly access the elements of the linked list or access the elements at the tail of the list then the operations are heavy. Cause, for accessing the n+1 th element, you will need to parse through the first n elements to reach the n+1th element.

Also linked list is not synchronized. So multiple threads modifying and reading the list would need to be synchronized externally.

So the choice of which class to use for creating lists depends on the requirements. ArrayList or Vector( if you need synchronization ) could be used when you need to add elements at the end of the list and access elements randomly - more access operations than add operations. Whereas a LinkedList should be used when you need to do a lot of add/delete (elements) operations from the head or the middle of the list and your access operations are comparatively less.

Monday, May 05, 2008

multiplexes in Delhi/NCR

Gone are the days when you could enjoy movie sitting in the balcony or do a cost cutting by watching a movie in the front row. Multiplexes are everywhere. Every seat from the back to the front row are priced same.

So, it becomes really important to figure out where you want to watch your movie.

This blog would majorly focus on the few major cinema chains in Delhi/NCR - PVR, Fun Cinemas, Waves, JAM, Satyam Cineplexes, Adlabs and DT cinemas. Too many of them.

PVR has a lot of branches in and around Delhi. And it is the oldest cinema chain. I have been to PVR Priya, PVR Saket, PVR Naraina, PVR in gurgaon and my neighborhood Spice PVR in noida. The good thing about PVR is that it offers luxury and the staff is well trained. I have never had any discomfort while watching movies at PVR. But at most PVR movie halls, the screens are small. And sometimes it feels more like a home theater than a movie hall.

Regarding Fun Cinemas & DT Cinemas, I have been there once or twice only. And i dont recall anything odd about them. Satyam cineplexes - have been there (patel nagar) once (got a free ticket from somewhere). The only thing I recall is that the seats were extermely uncomfortable and small. And the staff is not that great.

Waves(Noida) is great. I specially like the 0.1 & 0.2 halls which are extremely large. The screen is good and the seats extremely comfortable. I have also been to Waves-Kaushambi, but it sucks badly. Mostly because the mall does not have any other shops and there is nothing else to do.

The best cinema among all of them is ofcourse JAM multiplex. The good thing about JAM is that the seating arrangement is in a curve. So you can see the whole hall without much exercise. And ofcourse the screens are large and seating very comfortable. Though there is no online booking available for JAM. I generally prefer to go to Waves-Noida or JAM.

And then there is ADLABS. The only good thing about ADLABS is the iMax hall in Pacific Mall near kaushambhi. This hall has a huge no enormous screen where if you watch a movie, you actually feel like a part of the movie. Watching 3D movies on the screen is also very entertaining. But that's the only good thing about ADLABS. The seats are very uncomfortable and narrowly placed. The prices of almost all adlabs cinemas are very high. And i have had 2-3 bad experiences with ADLABS.

1. I booked tickets in the last row assuming hoping for better view. But in pacific mall the last and second last row are at the same height. So, if you are sitting in the last row, you would not be able to view the movie unless you stand up or peek from between seats. I was with family - if i would have been with friends, i would have simply sat on the steps to watch the movie.

2. ADLABS Noida(TGI Mall) is the worst one of all. The prices here are extremely steep. When i went there to see a movie for the first time, the movie started 1 hour late. The croud there was furious and the management was no-where to be seen.

3. Another incident at ADLABS Noida which happened with my friend was that when he went to see "U Me aur Hum". There were only 5 people in the hall, so the management canceled the show and ran "tashan" instead. Even i was shocked when i heard this. I dont know how far would they go with this attitude. I have seen movies at PVR when only 5-8 people were there. And i have never heard of a show being canceled to run another show. PVR or any other cinema halls, do not run the show if they do not have an audience. But ADLABS is too much i think.

With more and more multiplexes opening up, there would be a competition between them for service and price. ADLABS would lose on the price front and if they continue this behavior, they may also lose on the service front - a total loss.

And then there is another very good thing about ADLABS Noida - the ebony launge which has couple seats. Here the service is good (though i have been there only once). I still have to explore the Gold class in PVR Spice and the SKY Box in Satyam Cineplexes in Nehru place.

Sunday, May 04, 2008

U me aur hum

The recipe for making a good bollywood movie is to take a good non-bollywood movie - extract the concept and put in the normal bollywood masala - emotion, action, drama.

Bingo, thats how we got "U me aur hum" and "Shaurya". Well, but i am not going to talk about shourya here. Shourya was a exact - word to word copy of "A few good men". Whereas "U me aur hum" extracts the concept and weaves a story around it.

If any of you would have seen The Notebook, you would realize the similarity in concept between both of them.

The story is the same - an old man tells a story to a old women. The story is a simple "Boy meet girl" story where boy loves the girl very much and would do anything to stay with her. The girl developes an illness whereby she loses her memory for short spans of time. And since the boy loves the girl very much - he stays with the girl - even when the girl forgets that he is her husband/lover. And the climax tells that the touching story is of these two people.

The notebook was much better. It actually made me cry. And i rarely cry at movies. Whereas U me aur hum was emotional but heavy. It takes you to the brink of emotional overflow (crying) but does not make you cry. Which is why you may feel heavy after the movie. The Notebook on the other hand makes you emotional and then takes you through. It does not stop you from crying.

I am sorry, if this review feels more like a comparison. But i couldn't stop myself from comparing both of them.

The script is good. The acting is superb by both Ajay Devgun and Kajol. There are scenes which would touch you. Cinematography is very good. First half is fun filled. And the second half is the main film - emotional and touching.

Watch it with your spouse, it should make the bonds stronger.

The Spiderwick Chronicles


Can you ever think that there are goblins, boggarts and orgs all around us and invisible to us all the time - while they could see us. And if we see them, they could sense it. That's what this movie is about. It is basically a children's movie - a mix of "Alice in wonderland" and "harry potter".

I generally love such movies. The concept of the movie itself is non-realistic and that makes the movie more interesting. The author or script-writer can open up his imagination and write whatever he could possibly think of.

The movie starts off with "Mr Spiderwick" writing a book and sealing it to hide its secret. And after many many years, his grand-grand children come over to that place to stay. How they become acquainted with the "other" world and then see the boggards, goblins and the orges. And then they have a mission to save the book from the hands of the big bad shape changing orge - "Mulgarath".

The special effects are good and you probably would sit on the edge of your seat throughout the movie. A movie worth watching...