@@ -30,6 +30,9 @@ writedownmode:@[value;`writedownmode;`default]; /-the
3030 /- at EOD the data will be merged from each partition before being moved to hdb
3131 /- 3. partbyenum - the data is partitioned by [ partitiontype ] and a symbol or integer column with parted attribution assigned in sort.csv
3232 /- at EOD the data will be merged from each partition before being moved to hdb
33+ /- 3. partbyfirstchar - the data is partitioned by [ partitiontype ] and a symbol column based on the first character with parted attribution assigned in sort.csv
34+ /- at EOD the data will be sorted and merged from each partition before being moved to hdb
35+
3336
3437mergemode : @ [value ;`mergemode ;`part ]; /-the partbyattr writedown mode can merge data from temporary storage to the hdb in three ways:
3538 /- 1. part - the entire partition is merged to the hdb
@@ -52,7 +55,6 @@ tpcheckcycles:@[value;`tpcheckcycles;0W]; /-num
5255
5356sorttypes : @ [value ;`sorttypes ;`sort ]; /-list of sort types to look for upon a sort
5457sortworkertypes : @ [value ;`sortworkertypes ;`sortworker ]; /-list of sort types to look for upon a sort being called with worker process
55-
5658wdbtypes : @ [value ;`wdbtypes ;`wdb ]; /-list of wdb types for sort processes to look for on initmissingtables
5759
5860subtabs : @ [value ;`subtabs ;` ]; /-list of tables to subscribe for
@@ -92,7 +94,7 @@ saveenabled: any `save`saveandsort in mode;
9294sortenabled : any `sort`saveandsort in mode ;
9395
9496/- parted writedown modes have special behaviour during merging or WDB initialisation
95- partwritemodes : `partbyattr`partbyenum ;
97+ partwritemodes : `partbyattr`partbyenum`partbyfirstchar ;
9698
9799/ - log which modes are enabled
98100switch : string `off`on ;
@@ -125,19 +127,24 @@ maptoint:{[val]
125127 `long $ (` sv hdbsettings [`hdbdir ], `sym )? `TORQNULLSYMBOL ^val ]
126128 };
127129
130+ mapfctoint : {[val ]
131+ .Q.an ?$ [0 <type val ;first each ;first ] string val
132+ };
133+
128134/- function to upsert to specified directory
129135upserttopartition : {[dir ;tablename ;tabdata ;pt ;expttype ;expt ;writedownmode ]
130136 /- enumerate first extra partition value
131137 if [writedownmode ~`partbyenum ;i : maptoint first expt ];
138+ if [writedownmode ~`partbyfirstchar ;i : mapfctoint first expt ];
132139 /- create directory location for selected partition
133140 /- replace non-alphanumeric characters in symbols with _
134141 /- convert to symbols and replace any null values with `TORQNULLSYMBOL
135- directory : $ [writedownmode ~ `partbyenum ;
142+ directory : $ [writedownmode in `partbyenum`partbyfirstchar ;
136143 ` sv .Q.par [dir ;pt ;` $ string i], tablename , ` ;
137- ` sv .Q.par [dir ;pt ;tablename ], (` $ "_" ^.Q.an .Q.an ? "_" sv string `TORQNULLSYMBOL ^ ensuresymlist [expt ]), ` ];
144+ ` sv .Q.par [dir ;pt ;tablename ], (` $ "_" ^.Q.an .Q.an ? "_" sv string `TORQNULLSYMBOL ^ ensuresymlist [expt ]), ` ];
138145 .lg.o [`save ;"saving " , (string tablename ), " data to partition " , string directory ];
139146 /- selecting rows of table with matching partition
140- r : ? [tabdata ;$ [writedownmode ~ `partbyenum ;enlist (in ;first expttype ;expt );{(x;y;(), z)}[in ;;]' [expttype ;expt ]];0b ;()];
147+ r : ? [tabdata ;$ [writedownmode in `partbyenum`partbyfirstchar ;enlist (in ;first expttype ;expt );{(x;y;(), z)}[in ;;]' [expttype ;expt ]];0b ;()];
141148 /- upsert selected data matched on partition to specific directory
142149 . [upsert ;(directory ;r);{[e ] .lg.e [`savetablesbypart ;"Failed to save table to disk : " , e];' e}];
143150 .lg.o [`track ;"appending details to partsizes" ];
@@ -152,8 +159,8 @@ savetablesbypart:{[dir;pt;forcesave;tablename;writedownmode]
152159 .lg.o [`rowcheck ;"the " , (string tablename ), " table consists of " , (string arows ), " rows" ];
153160 /- get additional partition(s) defined by parted attribute in sort.csv
154161 extrapartitiontype : .merge.getextrapartitiontype [tablename ];
155- if [(writedownmode ~ `partbyenum ) and 1 <c : count extrapartitiontype ;
156- .lg.e [`partbyenum ;"only 1 parted attribute should be defined on table when partbyenum writedown mode is used but we have " , string c]
162+ if [(writedownmode in `partbyenum`partbyfirstchar ) and 1 <c : count extrapartitiontype ;
163+ .lg.e [writedownmode ;"only 1 parted attribute should be defined on table when using partbyenum and partbyfirstchar writedown modes, but we have " , string c]
157164 ];
158165 /- check each partition type actually is a column in the selected table
159166 .merge.checkpartitiontype [tablename ;extrapartitiontype ];
@@ -182,7 +189,7 @@ savetables:$[writedownmode in partwritemodes;savetablesbypart[;;;;writedownmode]
182189savetodisk : {[]
183190 changes : savetables [savedir ;getpartition [];immediate ;] each tablelist [];
184191 /- we have to let the idbs know of the changes in the wdbhdb. using filldb[] to make sure it is a db with all the tables
185- if [any [changes ] and writedownmode in `partbyenum`default ;filldb getpartition [];notifyidbs [`.idb.intradayreload ;enlist ()]]};
192+ if [any [changes ] and writedownmode in `partbyenum`partbyfirstchar` default ;filldb getpartition [];notifyidbs [`.idb.intradayreload ;enlist ()]]};
186193
187194/- send an intraday reload message to idbs:
188195notifyidbs : {[func ;params ]
@@ -332,8 +339,8 @@ merge:{[dir;pt;tableinfo;mergelimits;hdbsettings;mergemethod;writedownmode]
332339 setcompression [hdbsettings [`compression ]];
333340 /- get tablename
334341 tabname : tableinfo [0 ];
335- /- get list of partition directories for specified table - partbyenum uses different folder structure vs partbyattr/default
336- partdirs : $ [writedownmode in `partbyenum ;
342+ /- get list of partition directories for specified table - partbyenum & partbyfirstchar use different folder structures vs partbyattr/default
343+ partdirs : $ [writedownmode in `partbyenum`partbyfirstchar ;
337344 p where 0 <count each key each p : ` sv ' ((-1 _ ` vs p),/: key p : .Q.par [hsym dir ;pt ;` ]),\: tabname ;
338345 ` sv ' tabledir ,/: key tabledir : .Q.par [hsym dir ;pt ;tabname ]];
339346 /- we only really have to merge those partitions where we have received some updates, otherwise table is empty
@@ -363,7 +370,7 @@ merge:{[dir;pt;tableinfo;mergelimits;hdbsettings;mergemethod;writedownmode]
363370 .merge.mergehybrid [tableinfo ;dest ;partdirs ;mergelimits [tabname ]]
364371 ];
365372 .lg.o [`merge ;"removing segments " , (", " sv string [partdirs ])];
366- $ [writedownmode in `partbyenum ;
373+ $ [writedownmode in `partbyenum`partbyfirstchar ;
367374 removetablefromenumdir each partdirs ;
368375 .os.deldir .os.pth [[string [tabledir ]]]
369376 ];
@@ -384,7 +391,7 @@ removetablefromenumdir:{[partdir]
384391
385392endofdaymerge : {[dir ;pt ;tablist ;mergelimits ;hdbsettings ;mergemethod ;writedownmode ]
386393 /- merge data from partitions
387- /- .z.pd funciton in finspace will cause an error. Add in this check to skip over the use of .z.pd. This should be temporary and will be removed when issue resolved by AWS.
394+ /- .z.pd function in finspace will cause an error. Add in this check to skip over the use of .z.pd. This should be temporary and will be removed when issue resolved by AWS.
388395 tempfix2 : $ [.finspace.enabled ;0b ;(0 < count .z.pd [])];
389396 $ [tempfix2 and ((system "s" )<0 );
390397 [.lg.o [`merge ;"merging on worker" ];
@@ -423,12 +430,34 @@ endofdaymerge:{[dir;pt;tablist;mergelimits;hdbsettings;mergemethod;writedownmode
423430 ];
424431 };
425432
433+ /- end of day sort and merge only used by writedown mode sortbyfirstchar, requiring sort pre-merge
434+ endofdaysortandmerge : {[dir ;pt ;tablist ;mergelimits ;hdbsettings ;mergemethod ;writedownmode ]
435+ /-sort permitted tables in database
436+ /- sort the table and garbage collect (if enabled)
437+ .lg.o [`sort ;"starting to sort data" ];
438+ /- .z.pd function in finspace will cause an error. Add in this check to skip over the use of .z.pd. This should be temporary and will be removed when issue resolved by AWS.
439+ tempfix1 : $ [.finspace.enabled ;0b ;count [.z.pd []]];
440+ tnds : raze {y,/: .Q.dd [x;]each key [x],\: y}[.Q.dd [dir ;pt ]]each key tablist ;
441+ tnds : tnds where tnds [;1 ] in exec ptdir from .merge.partsizes ;
442+ $ [tempfix1 &0 >system "s" ;
443+ [.lg.o [`sortandmerge ;"sorting on worker sort" , string .z.p ];
444+ {(neg x)(`.wdb.reloadsymfile ;y);(neg x)(:: )}[;.Q.dd [hdbsettings `hdbdir ;`sym ]] each .z.pd [];
445+ {[x ;compression ] setcompression compression ;.sort.sorttab x;if [gc ;.gc.run []]}[;hdbsettings `compression ] peach tnds ];
446+ [.lg.o [`sort ;"sorting on main sort" ];
447+ reloadsymfile [.Q.dd [hdbsettings `hdbdir ;`sym ]];
448+ {[x ] .sort.sorttab [x];if [gc ;.gc.run []]} each tnds ]];
449+ .lg.o [`sort ;"finished sorting data" ];
450+ endofdaymerge [dir ;pt ;tablist ;mergelimits ;hdbsettings ;mergemethod ;writedownmode ];
451+ };
452+
426453/- end of day sort [depends on writedown mode]
427454endofdaysort : {[dir ;pt ;tablist ;writedownmode ;mergelimits ;hdbsettings ;mergemethod ]
428455 /- set compression level (.z.zd)
429456 setcompression [hdbsettings [`compression ]];
430457 $ [writedownmode in partwritemodes ;
431- endofdaymerge [dir ;pt ;tablist ;mergelimits ;hdbsettings ;mergemethod ;writedownmode ];
458+ $ [writedownmode ~`partbyfirstchar ; /-partbyfirstchar will not be sorted by sym within each parition, this needs done first
459+ endofdaysortandmerge [dir ;pt ;tablist ;mergelimits ;hdbsettings ;mergemethod ;writedownmode ];
460+ endofdaymerge [dir ;pt ;tablist ;mergelimits ;hdbsettings ;mergemethod ;writedownmode ]];
432461 endofdaysortdate [dir ;pt ;key tablist ;hdbsettings ]
433462 ];
434463 /- run steps to rollover idb
@@ -534,7 +563,7 @@ fixpartition:{[subto]
534563 ];
535564 }
536565
537- /- for writedown modes partbyenum/default we make sure that partition 0/currentpartition has all the tables.
566+ /- for writedown modes partbyenum/partbyfirstchar/ default we make sure that partition 0/currentpartition has all the tables.
538567/- In that case we can use .Q.chk later to fill the db making it useable for intraday processes
539568/- pt - date; partition for which the function should initialise
540569initmissingtables : {[pt ]
@@ -550,7 +579,7 @@ filldb:{[pt]
550579
551580/- initialises table t in db with its schema in part
552581inittable : {[t ;pt ]
553- tabledir : ` sv $ [writedownmode ~ `partbyenum ; .Q.par [.Q.dd [hsym savedir ;pt ];0 ;t]; .Q.par [hsym savedir ;pt ;t]], ` ;
582+ tabledir : ` sv $ [writedownmode in `partbyenum`partbyfirstchar ; .Q.par [.Q.dd [hsym savedir ;pt ];0 ;t]; .Q.par [hsym savedir ;pt ;t]], ` ;
554583 if [() ~ key tabledir ;tabledir set .Q.en [hsym hdbdir ;0 # value t]];
555584 }
556585
@@ -590,7 +619,7 @@ getsortparams:{[]
590619 /- get the attributes csv file
591620 /-even if running with a sort process should read this file to cope with backups
592621 .sort.getsortcsv [sortcsv ];
593- /- check the sort.csv for parted attributes `p if the writedownmode `partbyattr or `partbyenum is selected
622+ /- check the sort.csv for parted attributes `p if the writedownmode `partbyattr, `partbyenum or `partbyfirstchar is selected
594623 /- if each table does not have at least one `p attribute the process will exit
595624 if [writedownmode in partwritemodes ;
596625
@@ -612,7 +641,7 @@ getsortparams:{[]
612641/- If the function is ran on sort process send initmissingtables command to wdbs
613642idbreload : {[pt ]
614643 .lg.o [`idb ;"starting idb reload" ];
615- if [writedownmode in `partbyenum`default ;
644+ if [writedownmode in `partbyenum`default`partbyfirstchar ;
616645 .lg.o [`eod ;"initialising wdbhdb for partition: " , string [pt ]];
617646 $ [.proc.proctype ~`sort ;{[pt ]ws : exec w from .servers.getservers [`proctype ;wdbtypes ;()! ();1b ;0b ];{[ws ;pt ]ws (`.wdb.initmissingtables ;[pt ])}[;pt ] each ws }[pt ];initmissingtables [pt ]];
618647 .lg.o [`eod ;"notifying idbs for newly created partition" ];
0 commit comments