Feb 26, 2012

Ease of implementation versus performance

I finished doing general code cleanup in GTweak and went back to coding registry backup management code. As of yet, I finished backup information querying code.

Now, back to the merits. It took me few minutes to get it working. This is the older one (DeleteBackup references are TODOs):

@echo off
echo.
echo  1 Query backup info
echo  2 Remove backup
:loop
echo.
set ch=&set/p ch=ú  
if "%ch%"=="1" call:QueryBackupInfo
if "%ch%"=="2" call:DeleteBackup
goto loop
:QueryBackupInfo
for /f %%A in ('dir/b %windir%\grestore*.cmd') do (
 call:MakeSemicolonSeparatedVariable %%A scriptlist
)
for %%A in (%scriptlist%) do (
 call:GetBackupInfo %%A
    call:PrintBackupInfo %%A
)
exit/b0
set _>>getbkinfo.var
pause
goto:eof
:MakeSemicolonSeparatedVariable
set var=%% %2 %%
set var=%var: =%
if defined %2 (
 call set %2=%var%;%1
 ) else (
 set %2=%1
)
set var=
exit/b0
:GetBackupInfo
for /f "tokens=6" %%B in ('type "%windir%\%1"^|find "This is auto-generated GTweak"') do (
 set gver=%%B
)
for /f "tokens=3*" %%B in ('type "%windir%\%1"^|find "Generated:"') do (
 set gdatecreated=%%B %%C
)
for /f "tokens=3 delims=\)" %%B in ('type "%windir%\%1"^|find "for %%%%A in (%%drive%%:"') do (
 call:CheckBackupFile %1 %%B
)
for /f "tokens=*" %%G in ('set %bid%') do (
 if "%%G" NEQ "" set/a BackedUpFilesCount+=1
)
for /f "tokens=4 delims=.=" %%G in ('set %bid%') do (
 if "%%G"=="1" (
  set/a _%bid%.SUM_OF_VALID_FILESIZE_MATCHES+=1
 )
)
for /f "tokens=3 delims=.=" %%A in ('set _%bid%.SUM_OF_VALID_FILESIZE_MATCHES') do (
 if "%%A"=="%BackedUpFilesCount%" (
  set _%bid%.BACKUP_VALID=1
 ) else (
  set _%bid%.BACKUP_VALID=0
 )
)
for /f "tokens=2 delims=." %%G in ('set %bid%') do (
 set %bid%.%%G.IsValid=
)
for %%A in ( _%bid%.SUM_OF_VALID_FILESIZE_MATCHES BackedUpFilesCount file SizeGotFromScript SizeNow ) do set %%A=
exit/b0
:PrintBackupInfo
echo.
echo  Backup Id: %bid%
echo.
echo  Restoration script path: %windir%\%1
echo  Program version: %gver%
echo  Possible date created: %gdatecreated%
for /f "tokens=3 delims=.=" %%A in ('set _%bid%.BACKUP_VALID') do (
 if "%%A"=="1" (
  echo  Backup valid ^(supposedly^): yes
 )
 if "%%A"=="0" (
  echo  Backup valid ^(supposedly^): no
 )
 if "%%A" NEQ "1" (
  if "%%A" NEQ "0" (
   echo  EXCEPTION OCCURED: [%%A]
  )
 )
)
echo  /////////////////////////////////////////////////////////////////////////
set gver=&set gdatecreated=&set bid=
exit/b0
:CheckBackupFile
for /f "tokens=1,3 delims=_" %%C in ('echo %2') do (
 set bid=%%C
 set file=%%D
)
for %%C in (%windir%\%2) do (
 for /f "tokens=8" %%D in ('type "%windir%\%1"^|find "%2)"') do (
  call:CompareSizes "%%~zC" %%D
 )
)
exit/b0
:CompareSizes
set SizeNow=%1
set SizeGotFromScript=%3
if "%SizeNow%"=="%SizeGotFromScript%" (
 set %bid%.%file%.IsValid=1
 ) else (
 set %bid%.%file%.IsValid=0
)
exit/b0

I decided to cease nesting FIND and TYPE commands in FOR loops. It was a bit more time-consuming to get it working, but it paid off.

@echo off
echo.
echo  1 Query backup info
echo  2 Remove backup
:loop
echo.
set ch=&set/p ch=ú  
if "%ch%"=="1" call:QueryBackupInfo
if "%ch%"=="2" call:DeleteBackup
goto loop
:QueryBackupInfo
for /f %%A in ('dir/b %windir%\grestore*.cmd') do (
 call:MakeSemicolonSeparatedVariable %%A scriptlist
)
for %%A in (%scriptlist%) do (
 call:GetBackupInfo %%A
    call:PrintBackupInfo %%A
)
exit/b0
set _>>getbkinfo.var
pause
goto:eof
:MakeSemicolonSeparatedVariable
set var=%% %2 %%
set var=%var: =%
if defined %2 (
 call set %2=%var%;%1
 ) else (
 set %2=%1
)
set var=
exit/b0
:GetBackupInfo
call:RetrieveVersion %1
call:RetrieveCreationDate %1
for /f "tokens=1-13 delims=\() " %%B in (%windir%\%1) do (if "%%B %%D %%F"=="for in Windows" (call:CompareSizes %%G %%K))
for /f "tokens=*" %%G in ('set %bid%') do (if "%%G" NEQ "" set/a BackedUpFilesCount+=1)
for /f "tokens=4 delims=.=" %%G in ('set %bid%') do (if "%%G"=="1" (set/a _%bid%.SUM_OF_VALID_FILESIZE_MATCHES+=1))
for /f "tokens=3 delims=.=" %%A in ('set _%bid%.SUM_OF_VALID_FILESIZE_MATCHES') do (if "%%A"=="%BackedUpFilesCount%" (set _%bid%.BACKUP_VALID=1) else (set _%bid%.BACKUP_VALID=0))
for /f "tokens=2 delims=." %%G in ('set %bid%') do (set %bid%.%%G.IsValid=)
for %%A in ( _%bid%.SUM_OF_VALID_FILESIZE_MATCHES BackedUpFilesCount hive ) do (set %%A=)
exit/b0
:PrintBackupInfo
echo.
echo  Backup Id: %bid%
echo.
echo  Restoration script path: %windir%\%1
echo  Program version: %gver%
echo  Possible date created: %gdatecreated%
for /f "tokens=3 delims=.=" %%A in ('set _%bid%.BACKUP_VALID') do (
 if "%%A"=="1" (echo  Backup valid ^(supposedly^): yes)
 if "%%A"=="0" (echo  Backup valid ^(supposedly^): no)
 if "%%A" NEQ "1" (if "%%A" NEQ "0" (echo  EXCEPTION OCCURED: [%%A]))
)
echo  /////////////////////////////////////////////////////////////////////////
set gver=&set gdatecreated=&set bid=
exit/b0
:CompareSizes
for /f "tokens=1,3 delims=_" %%A in ("%1") do (set bid=%%A&set hive=%%B)
set CommitedSize=%3
set CommitedSize=%CommitedSize:"=%
for %%A in (%windir%\%1) do (if "%%~zA"=="%CommitedSize%" (set %bid%.%hive%.IsValid=1) else (set %bid%.%hive%.IsValid=0))
set CommitedSize=
set hive=
exit/b0
:RetrieveVersion
for /f "tokens=1-5,6" %%B in (%windir%\%1) do (if "%%B %%C %%D %%E %%F"=="rem This is auto-generated GTweak" (set gver=%%G&exit/b0))
set gver=UNKNOWN
exit/b0
:RetrieveCreationDate
for /f "tokens=1-2,*" %%B in (%windir%\%1) do (if "%%B %%C"=="rem Generated:" (set gdatecreated=%%D&exit/b0))
set gdatecreated=UNKNOWN
exit/b0

Results? Previous (old) version needed 57 seconds to verify 140 registry backups, newer - only 13 seconds. A bit more work and 4x faster script an award. Give it a try, but it is reasonable only, when you have at least 100 backups, then the effect is truly noticeable. Newer script relies on internals of Command Prompt, not even uses TYPE command.

Above scripts are on early (alpha) stage of development, use entirely on your own risk.

No comments:

Post a Comment