Archive for October, 2005

prime_options.pm v0.4.4

Friday, October 28th, 2005

加入模块处理options选项,感觉写到很不标准……
暂时过度一下。

#!/usr/bin/perl
# file:prime_options.pm
# Analyze primedb options.
# by:1e0n 05/10/28 v0.4.4

package prime_options;
require Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = qw(analyze_options);

sub analyze_options (*){
    local *options = shift;
    if (defined @options) {   
        if ($#options <= 1) {
            local $agm1 = shift @options;
            $agm1 =~ s/^\-(.*)$/$1/ or invalid_option(*agm1);
            print "option:$agm1\n";
        } else {
            invalid_option(*agm1);
            }
    } else {
        # do nothing;
        #print "no options\n";
    }
}

sub help {
    print <<EOF;
Usage: primedb [OPTIONS]

Options:
-h, –help        Give this help
-v, –version      display the version of primedb and exit.

primedb homepage: http://1e0n.blogs.friendster.com/x/
Please report bugs to <perl.pl+prime(at)gmail.com>
EOF
    exit;
}

sub invalid_option {
    local *cp_agm1 = shift;
    print <<EOF;
primedb: invalid option — $cp_agm1;
Usage: primedb [OPTIONS]

Try `primedb –help’ for more information.
EOF
    exit;
}

1;

–help

Friday, October 28th, 2005

接下来写下–help的内容。
加入个prime_help.pm??
把一些设想设成options,未来实现!

prime database project

Friday, October 28th, 2005

test1修改到最后就是test2版本了。打包在这里:
http://www.damocn.com/x/archive/prime-0.4.0.test2.tar.gz

直接开发test3的版本了。

花了一晚上在www.sourceforge.net申请了prime database project的项目:)
希望可以通过~~

超级期待!

在准备一系列的unix软件发布工作。写doc那些:)
project要规范化!

prime_main v0.3.14

Friday, October 28th, 2005

昨天修订了很多……但忘了修正过什么了。

今天就是改了下名。

#!/usr/bin/perl -w
#use strict;
# file:primedb
# main program of prime_project.
# by:leon 05/10/28 v0.3.15

use Socket;
use IO::Handle;
use read_write_db qw(read_db write_db);
use cal_prime qw(cal_prime_by_step);

# Bidirectional communication using socketpair
socketpair(CHILD, PARENT, AF_UNIX, SOCK_STREAM, PF_UNSPEC) or  die "socketpair: $!";
CHILD->autoflush(1);
PARENT->autoflush(1);

unless ($pid = fork) {
    # This is Child,for calculate prime
    die "cannot fork: $!" unless defined $pid;
    close CHILD;

    # Child ignore "ctrl+c"
    $SIG{INT} = ‘IGNORE’;

    # Read date from database for prepare calculate
    local (@prime_n_array,$prime_step_id,@new_prime_id_array,@new_prime_n_array);
    print "Child:    Reading existing prime data from database\n";
    read_db(*prime_n_array,*prime_step_id);
    my $if_cal = 0;
    print "Child:    Reading finish\n";
    print "Child:    Now start calculate prime step by step\n";

    while (1) {
        $|=1;
        print PARENT "go_on?\n";
        chomp($line = <PARENT>);

        if ($line eq "go_on") {
            # Parent didn’t catch "ctrl+c" so we go on next step calculate
            # print "\b";
            print "In step:calculating step $prime_step_id\n";
            $if_cal = 1;
            cal_prime_by_step(*prime_n_array,*prime_step_id,*new_prime_id_array,*new_prime_n_array);

            # When finish a step save data to database
            print "In step:saving step $prime_step_id\n";
            write_db(*new_prime_id_array,*new_prime_n_array,*prime_step_id);
        } elsif ($line eq "exit") {
            # Parent catch "ctrl+c" so we stop and exit
            print PARENT "child_finish\n";
            last;
        } else {
            # For Extensions
            print "Child:    I don’t understand What Parent say.\n";
            exit;
        }
    }

    print "Child:    Exiting\n";

    close PARENT;
    exit;
} else {
    # This is Parent,for control Child
    close PARENT;

    # Catch ctrl+c,but don’t exit directly.Parent send a msg
    # to Child then exit after Child finish ending work
    $SIG{INT} = sub {$int_count++};

    # When Child finish a step and ask Parent if go on or do something else
    # Parent responses a answer
    while (chomp($line = <CHILD>)) {
        # Parent catch "ctrl+c" and ask Child to exit.
        if ($int_count) {
            # Now we should ignore ctrl+c!
            $SIG{INT} = ‘IGNORE’;

            # Do some ending job
            print "Parent:    Calling Child to finish job\n";
            print CHILD "exit\n";
            chomp($line = <CHILD>);
            if ($line eq "child_finish") {
                print "Parent:    All job finish\n";
                print "Parent:    Exiting\n";
                last;
            } else {
                print "Parent:    I don’t understand What Child say.\n";
            }
        }

        # Havn’t catch ctrl+c,so let Child go on next step
        if ($line eq "go_on?") {
            print CHILD "go_on\n";
        } else {
            # For Extensions
            print "Parent:    I don’t understand What Child say.\n";
        }
    }

    close CHILD;
    waitpid($pid,0);
}

read_conf.pm v0.1.4

Friday, October 28th, 2005

prime.conf改名为primedb.conf。

#!/usr/bin/perl
# file:read_conf.pm
# Get mysql user and password from the conf file:primedb.conf
# by:1e0n 05/10/28 v0.1.4

package read_conf;
require Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = qw($user $pwd);

open CONF,"primedb.conf" or die "can’t read file:primedb.conf";
foreach (<CONF>) {
    chomp;
    $user = $1 if /^user=(\S*)\s*$/;
    $pwd  = $1 if /^passward=(\S*)\s*$/;
}

1;

init_database v0.3.8

Friday, October 28th, 2005

init_mysql_database改名为init_database。
以后可以扩展到其他数据库。
另外更改了输出的错误信息。

#!/usr/bin/perl -w
# file:init_database
# Init database.
# by:1e0n 05/10/28-v0.3.8
use strict;
use DBI();
use read_conf qw($user $pwd);

# Connect to the database.
print "init_mysql: Connect to the database\n";
my $dbh = DBI->connect("DBI:mysql:database=prime_db;host=localhost",
                       $user,
                          $pwd,
                          {’PrintError’ => 0})
        or die <<EOF;
Connect to database fail:
    Maybe you havn’t configure primedb.conf correctly?
    See README && prime.conf for more information.
EOF

# Drop table ‘prime_table’.
$dbh->do("DROP TABLE prime_table");

# Create a new table ‘prime_table’.
# This’s the table we store the prime series.
print "init_mysql: Init table\n";
$dbh->do("CREATE TABLE prime_table (id                    INTEGER,
                                    prime_n                INTEGER,
                                    prime_step_id        INTEGER,
                                    prime_step_n        INTEGER)");

# Insert init data into ‘prime_table’,that’s:
# +—–+——-+————-+————+
# | id  |prime_n|prime_step_id|prime_step_n|
# +—–+——-+————-+————+
# |  1  |   2   |      1      |      1     | first prime is 2,and sqrt(2) is 1
# |  2  |   3   |      1      |      1     | second prime is 3,and sqrt(3) is 1
# +—–+——-+————-+————+
print "init_mysql: Init data\n";
$dbh->do("INSERT INTO prime_table VALUES(1,2,1,1)");
$dbh->do("INSERT INTO prime_table VALUES(2,3,1,1)");

# Now all finish.
# Disconnect from the database.
print "init_mysql: Now database is ready\n";
$dbh->disconnect();

prime_main v0.3.14

Thursday, October 27th, 2005

经过测试发现刚才那个bug原来没有修正:(
不过现在处理好了:)
原来我在cal的过程里就已经有个write_db的动作,而在exit里面又write_db,当然退出时写进去的数据会重复拉。

好了,应该没有bug了,打算发布test2版本。

#!/usr/bin/perl -w
#use strict;
# file:prime_main
# main program of prime_project.
# by:leon 05/10/27 v0.3.14

use Socket;
use IO::Handle;
use read_write_db qw(read_db write_db);
use cal_prime qw(cal_prime_by_step);

# Bidirectional communication using socketpair
socketpair(CHILD, PARENT, AF_UNIX, SOCK_STREAM, PF_UNSPEC) or  die "socketpair: $!";
CHILD->autoflush(1);
PARENT->autoflush(1);

unless ($pid = fork) {
    # This is Child,for calculate prime
    die "cannot fork: $!" unless defined $pid;
    close CHILD;

    # Child ignore "ctrl+c"
    $SIG{INT} = ‘IGNORE’;

    # Read date from database for prepare calculate
    local (@prime_n_array,$prime_step_id,@new_prime_id_array,@new_prime_n_array);
    print "Child:    Reading existing prime data from database\n";
    read_db(*prime_n_array,*prime_step_id);
    my $if_cal = 0;
    print "Child:    Reading finish\n";
    print "Child:    Now start calculate prime step by step\n";

    while (1) {
        $|=1;
        print PARENT "go_on?\n";
        chomp($line = <PARENT>);

        if ($line eq "go_on") {
            # Parent didn’t catch "ctrl+c" so we go on next step calculate
            # print "\b";
            print "In step:calculating step $prime_step_id\n";
            $if_cal = 1;
            cal_prime_by_step(*prime_n_array,*prime_step_id,*new_prime_id_array,*new_prime_n_array);

            # When finish a step save data to database
            print "In step:saving step $prime_step_id\n";
            write_db(*new_prime_id_array,*new_prime_n_array,*prime_step_id);
        } elsif ($line eq "exit") {
            # Parent catch "ctrl+c" so we stop and exit
            print PARENT "child_finish\n";
            last;
        } else {
            # For Extensions
            print "Child:    I don’t understand What Parent say.\n";
            exit;
        }
    }

    print "Child:    Exiting\n";

    close PARENT;
    exit;
} else {
    # This is Parent,for control Child
    close PARENT;

    # Catch ctrl+c,but don’t exit directly.Parent send a msg
    # to Child then exit after Child finish ending work
    $SIG{INT} = sub {$int_count++};

    # When Child finish a step and ask Parent if go on or do something else
    # Parent responses a answer
    while (chomp($line = <CHILD>)) {
        # Parent catch "ctrl+c" and ask Child to exit.
        if ($int_count) {
            # Now we should ignore ctrl+c!
            $SIG{INT} = ‘IGNORE’;

            # Do some ending job
            print "Parent:    Calling Child to finish job\n";
            print CHILD "exit\n";
            chomp($line = <CHILD>);
            if ($line eq "child_finish") {
                print "Parent:    All job finish\n";
                print "Parent:    Exiting\n";
                last;
            } else {
                print "Parent:    I don’t understand What Child say.\n";
            }
        }

        # Havn’t catch ctrl+c,so let Child go on next step
        if ($line eq "go_on?") {
            print CHILD "go_on\n";
        } else {
            # For Extensions
            print "Parent:    I don’t understand What Child say.\n";
        }
    }

    close CHILD;
    waitpid($pid,0);
}

下面的几步

Thursday, October 27th, 2005

v0.4.test1已经修改的比较完善了,最初的设想都已经实现。
应该很快到v0.4.test2。

再之后的版本我打算重新处理prime_main和write_db的接口。

还有就是当相对成熟后到开源网站www.sourceforge.net申请个自己的project。
看到sourceforge有104,845个项目了,天阿!

prime_main v0.3.12

Thursday, October 27th, 2005

修正了一个bug:当程序开始读取database的数据,但还没开始开始计算的时候如果收到ctrl+c信号会保存已有数据,那样就造成了数据重复。
另外加强了界面友好性。
现在这个test1版本应该比较完善了。

#!/usr/bin/perl -w
#use strict;
# file:prime_main
# main program of prime_project.
# by:leon 05/10/27 v0.3.12

use Socket;
use IO::Handle;
use read_write_db qw(read_db write_db);
use cal_prime qw(cal_prime_by_step);

# Bidirectional communication using socketpair
socketpair(CHILD, PARENT, AF_UNIX, SOCK_STREAM, PF_UNSPEC) or  die "socketpair: $!";
CHILD->autoflush(1);
PARENT->autoflush(1);

unless ($pid = fork) {
    # This is Child,for calculate prime
    die "cannot fork: $!" unless defined $pid;
    close CHILD;

    # Child ignore "ctrl+c"
    $SIG{INT} = ‘IGNORE’;

    # Read date from database for prepare calculate
    local (@prime_n_array,$prime_step_id,@new_prime_id_array,@new_prime_n_array);
    print "Child:    Reading existing prime data from database\n";
    read_db(*prime_n_array,*prime_step_id);
    my $if_cal = 0;
    print "Child:    Reading finish\n";
    print "Child:    Now start calculate prime step by step\n";

    while (1) {
        $|=1;
        print PARENT "go_on?\n";
        chomp($line = <PARENT>);

        if ($line eq "go_on") {
            # Parent didn’t catch "ctrl+c" so we go on next step calculate
            # print "\b";
            print "In step:$prime_step_id\n";
            $if_cal = 1;
            cal_prime_by_step(*prime_n_array,*prime_step_id,*new_prime_id_array,*new_prime_n_array);

            # When finish a step save data to database
            write_db(*new_prime_id_array,*new_prime_n_array,*prime_step_id);
        } elsif ($line eq "exit") {
            # Parent catch "ctrl+c" so we stop

            if ($if_cal==1) {
                print "Child:    Saving step data before exit\n";
                write_db(*new_prime_id_array,*new_prime_n_array,*prime_step_id);
                print "Child:    Saved!\n";
                print PARENT "child_finish\n";
            } else {
                print "Child:    Needn’t save data case hav’t cal new prime\n";
                print PARENT "child_finish\n";
            }
            last;
        } else {
            # For Extensions
            print "Child:    I don’t understand What Parent say.\n";
            exit;
        }
    }

    print "Child:    Exiting\n";

    close PARENT;
    exit;
} else {
    # This is Parent,for control Child
    close PARENT;

    # Catch ctrl+c,but don’t exit directly.Parent send a msg
    # to Child then exit after Child finish ending work
    $SIG{INT} = sub {$int_count++};

    # When Child finish a step and ask Parent if go on or do something else
    # Parent responses a answer
    while (chomp($line = <CHILD>)) {
        # Parent catch "ctrl+c" and ask Child to exit.
        if ($int_count) {
            # Now we should ignore ctrl+c!
            $SIG{INT} = ‘IGNORE’;

            # Do some ending job
            print "Parent:    Calling Child to finish job\n";
            print CHILD "exit\n";
            chomp($line = <CHILD>);
            if ($line eq "child_finish") {
                print "Parent:    All job finish\n";
                print "Parent:    Exiting\n";
                last;
            } else {
                print "Parent:    I don’t understand What Child say.\n";
            }
        }

        # Havn’t catch ctrl+c,so let Child go on next step
        if ($line eq "go_on?") {
            print CHILD "go_on\n";
        } else {
            # For Extensions
            print "Parent:    I don’t understand What Child say.\n";
        }
    }

    close CHILD;
    waitpid($pid,0);
}

read_write_db.pm v0.3.7

Thursday, October 27th, 2005

eng:
add some useful comment.

cn:
加入些有用的注释。

#!/usr/bin/perl
# file:read_write_db.pm
# read mysql database into hashref or write back hashref to database.
# by:1e0n 05/10/27 v0.3.7

package read_write_db;
require Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = qw(read_db write_db);

use DBI();
use read_conf qw($user $pwd);

sub read_db {
    # Use Typeglob to make a efficient prarmeter passing
    local (*cp_prime_n_array,*cp_prime_step_id) = @_;
    my $n;

    # Connect to the database.
    my $dbh = DBI->connect("DBI:mysql:database=prime_db;host=localhost",
                            $user,$pwd,
                            {’RaiseError’ => 1});

    # pick out all prime to ref && sqrt_of_prime_id to ref
    # that’s a little slowly process if we have a big database
    my $prime_n_ref = $dbh->selectall_arrayref("SELECT prime_n FROM prime_table");
    my $prime_step_id_ref = $dbh->selectrow_arrayref("SELECT MAX(prime_step_id) FROM prime_table");

    # copy prime to array "copy_prime",$cp_prime_n_array[0] is no use but we let it equal 1.
    # we start from $cp_prime_n_array[1] = 2 which mean the first prime is 2.
    # that’s really not a good method to change data type but no matter,it’s fast enough.
    @cp_prime_n_array = (1);
    foreach (@$prime_n_ref) {
        $cp_prime_n_array[++$n]=$_->[0];
    }

    $cp_prime_step_id = $prime_step_id_ref->[0];

    #列数: $#{$ref}+1 行数?: $#{$ref->[0]}+1 提取一个数:@$ref[0]->[1];

    # after reading data disconnect mysql
    $dbh -> disconnect();
}

sub write_db {
    local (*cp_new_prime_id_array,*cp_new_prime_n_array,*cp_prime_step_id)=@_;

    # Connect to the database.
    my $dbh = DBI->connect("DBI:mysql:database=prime_db;host=localhost",
                            $user,$pwd,
                            {’RaiseError’ => 1});

    $insert = $dbh->prepare("INSERT INTO prime_table (id,prime_n,prime_step_id) VALUES (?,?,?)");

    my $i=0;
    for (@cp_new_prime_id_array) {
        $insert->execute($_,$cp_new_prime_n_array[$i],$cp_prime_step_id) or die ($dbh->errstr);
        $i++;
    }

    # after reading data clear memory && disconnect mysql
    $insert->finish();
    $dbh -> disconnect();
}

1;