Tuesday, January 15, 2008

TreeSet Comparator

When using TreeSet(Comparator) for a sorted set, be cautious that the compare() or compareTo() must be consistent with equals. Set interface is defined in terms of the equals operation, but a TreeSet instance performs all key comparisons using its compareTo (or compare) method, so two keys that are deemed equal by this method are, from the standpoint of the set, equal.

E.g., unique id used in equals(), but name (could be duplicate) is used in compare() and cause problem. The item with same name actually couldn't be added to the set.


/** To sort by 2 attributes **/
public int compare(TreeElement e1, TreeElement e2) {
    // sort by tree name first
     int compareName =e1.getTreeName().compareTo(e2.getTreeName());
     if (compareName != 0) {
         return compareName;
     }
     // sort by databaseKey if tree names are the same
     return e1.getDatabaseKey().compareTo(e2.getDatabaseKey());
}

Monday, January 14, 2008

Graceful Shutdown

JVM has a shutdownHook Runtime.getRuntime.addShutdownHook(Thread) which allows us to register a shutdown hook. However, it doesn't work well with Windows. It responds to CTRL-C, but doesn't react when the process is killed (from task manager, or service console). In Linux/Unix it does work.

So an alternate is to add stop handling in JavaService, which run java class as NT service, and provides an adaptor layer .


licAgentService.exe -install "HiPath Wireless License Agent" %EMS_JAVA_HOME%\bin\client\jvm.dll
-Xms16m -Xmx64m
-Djava.class.path=bootstrap.jar;%EXTRA_CLASSPATH%
-Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8100,suspend=n
-Djava.library.path=%EMS_HOME%\lib
-start com.siemens.bk.lic.bootstrap.Main
-stop com.siemens.bk.lic.bootstrap.Main -method systemExit
-out .\logs\stdout.log
-err .\logs\stderr.log
-current %LICAGENT_HOME%
-depends "License Agent","HiPath Wireless RMI"
-auto

With the debug option, we can debug a service too.
In Windows Registry \HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\, we can review all the option settings of the service.

Friday, January 4, 2008

My 1st Stored Procedure

Create/run store procedure in MySQL SQL Browser
-script->create function/procedure
-click 'execute' button to compile and store in db (proc table)
-type "call sp_ginger()" to run it, without ';"
-database browser->sp_ginger right click to edit


// the task is to diff value between adjcent records in stat table which contains
// up to 14M records remember in sp, assign statement need to "set statement"
// one minor thing is in query "... ttime desc" doesn't work (i.e., ignored)
// in sp, has to be "..s.ttime desc" though it is OK in query, strange thing
// is that ttime is not ambiguous in the statement.
// note that in ginger_watchdog, the timestamp type column will be automatically
// populated with current timestamp during insertion.

DELIMITER $$

DROP PROCEDURE IF EXISTS `webnmsdb`.`sp_ginger` $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_ginger`()
BEGIN

declare done INT default 0;
declare firstItem int default 0;
declare pid, ttime, v bigint(20);
declare instance char(100);

declare pre_pid, pre_ttime, pre_v bigint(20) default -1;
declare pre_instance char(100) default null;
declare rate bigint(20);

declare cur cursor for select * from ginger_order_temp;
declare continue handler for not found set done = 1;

create table if not exists ginger_watchdog (desp char(100), cur_timestamp TIMESTAMP);
insert into ginger_watchdog(desp) values('started sp at');

drop table if exists ginger_result;
create table ginger_result(pollid bigint(20), instance char(100), ttime bigint(20), val bigint(20));

drop table if exists ginger_order_temp;
create table ginger_order_temp select s.pollid, s.instance, s.ttime, s.val from statsdata10_17_2007 s, ratesOidToConvert oid where s.pollid=oid.pollid and s.pollid=992 order by s.pollid, s.ttime desc;

open cur;

repeat
   fetch cur into pid, instance, ttime, v;
   if not done then
   if (firstItem = 0) then
     set pre_pid=pid, pre_instance=instance, pre_ttime=ttime, pre_v=v;
     set firstItem = 1;
   else
     if (pid = pre_pid) then
       set rate = abs(pre_v - v)/((pre_ttime - ttime)/1000);
       insert into ginger_result values(pre_pid, pre_instance, pre_ttime, rate);
     end if;
     set pre_pid=pid, pre_instance=instance, pre_ttime=ttime, pre_v=v;
   end if;

end if;
until done end repeat;
close cur;

insert into ginger_watchdog(desp) values('finished sp at');

END $$
DELIMITER ;