Skip to content

Instantly share code, notes, and snippets.

@daimor
Created January 15, 2018 13:37
Show Gist options
  • Save daimor/cbd11489d2773106746214b94c2d52dc to your computer and use it in GitHub Desktop.
Save daimor/cbd11489d2773106746214b94c2d52dc to your computer and use it in GitHub Desktop.
Class Utils.Global Extends %RegisteredObject
{
/// Анализ размера глобала, с анализом размера его подузлов, на указанную вложенность
/// все необходимые параметры будут запршены при запуске
ClassMethod GlobalSize() [ PublicList = (big, DatabaseBlockSize, blksiz, cc, Bytes, Count, gls, lev) ]
{
set $ztrap="err"
set dir=$$selectdb()
do {
set glb=$$getval("Имя глобала","")
set glb=$translate(glb,"^")
if glb'="",'$data(@("^|""^^"_dir_"""|"_glb)) set glb=""
} while glb=""
set gls=$$getval("Собирать в буфер (будет очищен)","^gls")
set:$extract(gls)'="^" gls="^"_gls
do {
set lev=$$getval("Глубина расчета","2")
if $zstrip(lev,"*N")'="" set lev=""
} while lev=""
zw gls
kill @gls
write !
set Directory=dir /// Папка с БД
set Name=glb /// Глобал
set rc=$zutil(167,6,7,Directory,Name)
set x=$zutil(49,Directory)
set DatabaseBlockSize=+$piece(x,",",$$$blksizpiece) ;размер блока
/// начальный блок с глобалом
set PointerBlock=$piece(rc,"^",4)
open 63:"^^"_Directory
set blk=PointerBlock
set (Bytes,Count)=0
set blksiz=DatabaseBlockSize
set big='(blksiz=$$$2k)
do ..getsize(blk)
write !,"Блоков = ",Count
write !,"Занимаемое место = ",Bytes
quit
err
write !,$zerror
quit
getval(mess, def)
write !,mess_": "_def_" => "
read res
if res="" set res=def
quit res
selectdb()
new $namespace
set $namespace="%SYS"
set dir=""
do {
set dir=$$getval("Путь к БД",$zutil(12,""))
write !
set db=##class(SYS.Database).%OpenId(dir)
if '$isobject(db) set dir=""
} while dir=""
quit dir
}
/// рекурсивный обход блоков
ClassMethod getsize(blk, haslong = 0) [ Internal, PublicList = (big, DatabaseBlockSize, blksiz, cc, Bytes, Count, gls, lev) ]
{
quit:'blk
view blk
#; тип блока
set type=$case(DatabaseBlockSize,$$$2k:$$$type2k,:$$$type)
write:type'=8 !,$increment(cc),?10,blk,?20,type,?30,haslong
if type=8 {
#; Блок с данными
set bts=$$$offsetval(big) // размер блока
set blkcnt=0
if haslong {
#; составной большой блок данных, данные в нескольких блоках
for j=1:1 {
set x=$view(j*2,-6)
quit:x=""
set gl=$view(j*2+1,-5)
if $ascii(x)=$$$gdviewbiguni(big)!($ascii(x)=$$$gdviewbigcompact(big))!($ascii(x)=$$$gdviewbigbin(big)) {
set blkcnt=$piece(x,",",2)
set Count=Count+blkcnt // общее количество блоков
#; размеры блоков
set bts=bts+((blkcnt-1)*$$$datasize(blksiz)+$piece(x,",",3))
}
}
} else {
set blkcnt=1 // в обычном блоке он один
}
set t=$increment(Count,blkcnt),t=$increment(Bytes,bts)
try { set gl=$view(1,-5) } catch { set gl="" }
do ..cnt(gl,bts,blkcnt)
} elseif type'=1 {
#; связующие блоки
for i=1:1 {
set x=$view(i*2-1,-6)
quit:x=""
try { set gl=$view(i*2-1,-5) } catch { set gl="" }
#; связанный с текущим блок
set datablk=$view(i*2,-5)
set haslong=0
if $piece($view(i*2,-6),",",1) {
set haslong=1
}
do ..getsize(datablk,haslong)
view blk
}
}
quit
}
/// запись счетчиков в буфер
ClassMethod cnt(gl, bts, blkcnt = 1) [ Internal, PublicList = (gls, lev) ]
{
#; считаем в буфере
for i=0:1:lev {
set ind=""
for j=0:1:i {
set ind=ind_$listbuild($qsubscript(gl,j))
}
set t=$increment(@gls@(ind,"size"),bts)
set t=$increment(@gls@(ind,"cnt"),blkcnt)
}
quit
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment