You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
318 lines
8.4 KiB
318 lines
8.4 KiB
#!/bin/bash |
|
# |
|
tmp="/tmp/`basename $0`-$$" |
|
tmp0="$tmp.0.sql" |
|
tmp1="$tmp.1.sql" |
|
tmp2="$tmp.2.sql" |
|
tmp3="$tmp.3.sql" |
|
tmp4="$tmp.4.sql" |
|
msdd="1,000,000,000" |
|
msd="`echo "$msdd" | tr -d ,`" |
|
# |
|
usAge() |
|
{ |
|
echo "usAge: `basename $0` [-s sdiffX] [w] 0|[b startblock]|[s shift] endblock|z" |
|
echo " run as root or change dosql1()" |
|
echo |
|
echo " -s sdiffX = all shares must have minsdiff <= sdiffX - if not then abort" |
|
echo " any commas are removed with \"tr -d ,\"" |
|
echo " shares with sdiff below sdiffX are ignored. Default $msdd" |
|
echo " w = worker stats - without w = user stats" |
|
echo " 0 = from the first hi share" |
|
echo " b startblock = start after the workinfoid of startblock (instead of 0)" |
|
echo " i.e. this only includes data AFTER 'startblock'" |
|
echo " 'startblock' is the lowest block >= 'startblock'" |
|
echo " s shift = start from the shift with the starting 5 char code 'shift'" |
|
echo " if there ever is a duplicate, it will use the lowest one" |
|
echo " endblock = finish at the workinfoid of endblock (instead of z)" |
|
echo " this includes all of 'endblock'" |
|
echo " 'endblock' is the highest block <= 'endblock'" |
|
echo " z = to the last high share" |
|
echo |
|
echo " Basically would be '0 z' for all available share history or" |
|
echo " e.g. 'b NNN MMM' for a block range after NNN up to (including) MMM or" |
|
echo " e.g. 'b NNN z' starting after block NNN up to now" |
|
echo " Put a 'w' in front, to get worker instead of user summarisation" |
|
echo |
|
echo " The share history determines the limits used" |
|
echo " i.e. markersummaries before the first share, or after the last share," |
|
echo " are not included since that would invalidate the results" |
|
echo " Missing shares within the share data would invalidate the results" |
|
exit 1 |
|
} |
|
# |
|
dosql1() |
|
{ |
|
su - postgres << EOF |
|
echo "$sql" | psql ckdb |
|
EOF |
|
} |
|
# |
|
procsql() |
|
{ |
|
got="" |
|
fin="" |
|
prev="" |
|
while true ; do |
|
read line |
|
if [ "$?" != "0" ] ; then |
|
break |
|
fi |
|
if [ "$got" ] ; then |
|
if [ -z "$fin" ] ; then |
|
echo "$line" |
|
if [ "${line:0:1}" = "(" ] ;then |
|
fin="y" |
|
fi |
|
fi |
|
else |
|
if [ "${line:0:5}" = "-----" ] ; then |
|
got="y" |
|
echo "$prev" |
|
echo "$line" |
|
else |
|
prev="$line" |
|
fi |
|
fi |
|
done |
|
} |
|
# |
|
dosql() |
|
{ |
|
dosql1 2>&1 | procsql |
|
} |
|
# |
|
# reduce a large, 9 or more digit, comma number with 2 decimal places to nnG |
|
toG() |
|
{ |
|
sed -e "s/,\([0-9][0-9]\)[0-9],[0-9][0-9][0-9],[0-9][0-9][0-9]\.[0-9][0-9]*/.\1G/g" -e "s/\(\.[0-9][0-9]G\) *|/\1 |/g" -e "s/ *$//" |
|
} |
|
# |
|
dedup() |
|
{ |
|
cut -d '|' -f 1-5,7-10,12 |
|
} |
|
# |
|
dedupw() |
|
{ |
|
cut -d '|' -f 1-4,6-9,11 |
|
} |
|
# |
|
p1="$((0x1d))" |
|
p1v="`echo "$p1 3 - 8 * p" | dc`" |
|
# |
|
# calculate the diff ratio for each diffacc, given bits |
|
diff1() |
|
{ |
|
read line |
|
read line |
|
while true ; do |
|
read line |
|
if [ "$?" != "0" ] ; then |
|
break |
|
fi |
|
if [ "${line:0:1}" = "(" ] ; then |
|
break |
|
fi |
|
bits="`echo "$line" | cut -d '|' -f2 | tr -d ' '`" |
|
diffacc="`echo "$line" | cut -d '|' -f3 | tr -d ' '`" |
|
po="$((0x${bits:0:2}))" |
|
bi="$((0x${bits:2:6}))" |
|
pd="`echo "$p1v $po 3 - 8 * - p" | dc`" |
|
if [ "$pd" -lt "8" ] ; then |
|
pd="8" |
|
fi |
|
per="`echo "8 k $diffacc 2 $pd ^ 65535 * $bi / / p" | dc`" |
|
echo "$line | ${per}" |
|
done |
|
} |
|
# |
|
diffvals() |
|
{ |
|
grep "^$uorw *|" "$tmp4" | cut -d '|' -f4 | tr "\n" "+" | sed -e "s/+/ +/g" |
|
} |
|
# |
|
getdiff() |
|
{ |
|
echo "4 k 0 `diffvals` p" | dc |
|
} |
|
# |
|
# blocks are appended 3rd since if blocks exist, then at least 1 share must |
|
proc() |
|
{ |
|
read line |
|
read line |
|
while true ; do |
|
read line |
|
if [ "$?" != "0" ] ; then |
|
break |
|
fi |
|
if [ "${line:0:1}" = "(" ] ; then |
|
echo "$line" |
|
break |
|
fi |
|
uorw="`echo "$line" | cut -d'|' -f1 | tr -d ' '`" |
|
diffs="`getdiff` BDR" |
|
if [ "${diffs:0:1}" = "." ] ; then |
|
diffs=" 0$diffs" |
|
elif [ "${diffs:1:1}" = "." ] ; then |
|
diffs=" $diffs" |
|
elif [ "${diffs:2:1}" = "." ] ; then |
|
diffs=" $diffs" |
|
fi |
|
stats="`grep "^$uorw *|" "$tmp2"`" |
|
bstats="`grep "^$uorw *|" "$tmp3"`" |
|
if [ "$stats" ] ; then |
|
s=" | " |
|
else |
|
s="" |
|
fi |
|
if [ "$bstats" ] ; then |
|
b=" | " |
|
else |
|
b="" |
|
fi |
|
echo "$line | $diffs$s$stats$b$bstats" |
|
done |
|
} |
|
# |
|
procblk() |
|
{ |
|
while true ; do |
|
read line |
|
if [ "$?" != "0" ] ; then |
|
break |
|
fi |
|
if [ "${line:0:1}" = "(" ] ; then |
|
echo "$line" |
|
break |
|
fi |
|
uorw="`echo "$line" | cut -d'|' -f1 | tr -d ' '`" |
|
bstats="`grep "^$uorw *|" "$tmp3"`" |
|
echo "$line | $bstats" |
|
done |
|
} |
|
# |
|
if [ "$1" = "-s" ] ; then |
|
shift |
|
msd="`echo "$1" | tr -d ,`" |
|
shift |
|
fi |
|
# |
|
if [ -z "$1" ] ; then |
|
usAge |
|
fi |
|
# |
|
if [ "$1" = "-?" -o "$1" = "-h" -o "$1" = "-help" -o "$1" = "--help" ] ; then |
|
usAge |
|
fi |
|
# |
|
work="" |
|
if [ "$1" = "w" ] ; then |
|
work="w" |
|
shift |
|
fi |
|
# |
|
valsh="sdiff>=$msd" |
|
# Orphans included, Rejects not - since they can be below diff, or invalid, or too late or ... |
|
valblk="expirydate>'5555-05-05' and confirmed!='R'" |
|
# |
|
# START |
|
if [ "$1" = "0" ] ; then |
|
shift |
|
selwm1="ms.markerid>=(select min(markerid) from workmarkers where workinfoidstart>=(select min(workinfoid) from shares))" |
|
selsh1="" |
|
selblk1="and b.workinfoid>=(select min(workinfoid) from shares)" |
|
else |
|
if [ "$1" = "s" ] ; then |
|
shift |
|
selwm1="ms.markerid>=(select min(markerid) from workmarkers where description like 'Shift fin: $1 %')" |
|
selsh1="and workinfoid>=(select min(workinfoidstart) from workmarkers where description like 'Shift fin: $1 %')" |
|
selblk1="$selsh1" |
|
shift |
|
else |
|
if [ "$1" = "b" ] ; then |
|
shift |
|
selwm1="ms.markerid>=(select min(markerid) from workmarkers where workinfoidstart>(select min(workinfoid) from blocks where height>=$1))" |
|
selsh1="and s.workinfoid>=(select min(workinfoid) from blocks where height>=$1)" |
|
selblk1="and b.height>$1" |
|
shift |
|
else |
|
echo "ERR: Unknown first option '$1'" |
|
usAge |
|
fi |
|
fi |
|
fi |
|
# |
|
# END |
|
if [ "$1" = "z" ] ; then |
|
selwm2="" |
|
selsh2="" |
|
selblk2="" |
|
else |
|
if [ -z "$1" ] ; then |
|
echo "ERR: missing ending block|z" |
|
usAge |
|
else |
|
selwm2="and wm.markerid<=(select max(markerid) from workmarkers where workinfoidend<=(select max(workinfoid) from blocks where height<=$1))" |
|
selsh2="and s.workinfoid<=(select max(workinfoid) from blocks where height<=$1)" |
|
selblk2="and b.height<=$1" |
|
fi |
|
fi |
|
# |
|
# check all shares have minsdiff > $msd |
|
sql="select count(*) from shares s where s.minsdiff>$msd $selsh1 $selsh2 ;" |
|
# |
|
dosql > "$tmp0" |
|
count="`head -n 3 "$tmp0" | tail -n 1`" |
|
if [ "$count" != "0" ] ; then |
|
count |
|
echo "ERROR: there were '$count' shares with minsdiff>$msd - that must be '0'" |
|
usAge |
|
fi |
|
# |
|
# summarise markersummary into tmp1 for any user or worker with 'msd' diffacc or more |
|
if [ -z "$work" ] ; then |
|
sql="select ms.userid,substring(max(ms.workername) from '(^[^\._]*)'),to_char(sum(ms.diffacc),'999G999G999G999G999.99'),to_char(sum(ms.sharecount),'999G999G999G999G999') from markersummary ms where $selwm1 $selwm2 group by ms.userid having sum(ms.diffacc)>$msd order by sum(ms.diffacc) desc;" |
|
else |
|
sql="select ms.workername,to_char(sum(ms.diffacc),'999G999G999G999G999.99'),to_char(sum(ms.sharecount),'999G999G999G999G999.99') from markersummary ms where $selwm1 $selwm2 group by ms.workername having sum(ms.diffacc)>$msd order by sum(ms.diffacc) desc;" |
|
fi |
|
# |
|
dosql > "$tmp1" |
|
# |
|
# summarise the shares into tmp2 |
|
if [ -z "$work" ] ; then |
|
sql="select s.userid,count(*),to_char(min(s.sdiff),'999G999G999G999G999.99'),to_char(max(s.sdiff),'999G999G999G999G999.99'),to_char(avg(s.sdiff),'999G999G999G999G999.99') from shares s where $valsh $selsh1 $selsh2 group by s.userid;" |
|
else |
|
sql="select s.workername,count(*),to_char(min(s.sdiff),'999G999G999G999G999.99'),to_char(max(s.sdiff),'999G999G999G999G999.99'),to_char(avg(s.sdiff),'999G999G999G999G999.99') from shares s where $valsh $selsh1 $selsh2 group by s.workername;" |
|
fi |
|
# |
|
dosql > "$tmp2" |
|
# |
|
# summarise the blocks into tmp3 |
|
if [ -z "$work" ] ; then |
|
sql="select b.userid,count(*)||' B' from blocks b where $valblk $selblk1 $selblk2 group by b.userid;" |
|
else |
|
sql="select b.workername,count(*)||' B' from blocks b where $valblk $selblk1 $selblk2 group by b.workername;" |
|
fi |
|
# |
|
dosql > "$tmp3" |
|
# |
|
# summarise diff% into tmp4 (all ids will have a value) |
|
if [ -z "$work" ] ; then |
|
sql0="select ms.userid,wi.bits,sum(ms.diffacc)" |
|
sqlz="group by ms.userid,wi.bits;" |
|
else |
|
sql0="select ms.workername,wi.bits,sum(ms.diffacc)" |
|
sqlz="group by ms.userid,ms.workername,wi.bits;" |
|
fi |
|
# |
|
valwm="wm.status='p' and wm.expirydate>'5555-05-05'" |
|
sql="$sql0 from markersummary ms join workmarkers wm on ms.markerid=wm.markerid join workinfo wi on wm.workinfoidend=wi.workinfoid where $valwm and $selwm1 $selwm2 $sqlz" |
|
# |
|
dosql | diff1 > "$tmp4" |
|
# |
|
# join (append) to each tmp1 row, the matching row/data in tmp4, tmp2 and tmp3 |
|
cat "$tmp1" | proc | toG | dedup$work |
|
# |
|
shred -uz "$tmp0" "$tmp1" "$tmp2" "$tmp3" "$tmp4" &> /dev/null
|
|
|