AutoHotkey Community

It is currently May 27th, 2012, 3:38 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 62 posts ]  Go to page Previous  1, 2, 3, 4, 5  Next
Author Message
 Post subject:
PostPosted: June 4th, 2007, 10:35 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
majkinetor wrote:
The usage is not the problem. The problem is sharing.
Then I don't understand the problem: you have to pass the dictionary handle to a function as a parameter or make it global. The same is with the variable containing all of your constants. The later is faster and does not need includes or dll calls.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 6th, 2007, 7:21 am 
Offline

Joined: January 31st, 2005, 9:50 am
Posts: 3910
Location: Bremen, Germany
Is there any limitation on OS? Does it run on all windows versions?

_________________
Ciao
toralf
Image


Report this post
Top
 Profile  
Reply with quote  
PostPosted: August 9th, 2007, 7:09 am 
Offline
User avatar

Joined: January 25th, 2006, 8:08 am
Posts: 225
Location: Froschtümpel
Hi,

got a question concerning "Hash of Hashes" (considering dictionaries as hashes).

What I try to do is putting dictionary items into a dictionary:
Code:
#include %A_ScriptDir%\Includes\CoHelper.ahk
#Include %A_ScriptDir%\Includes\Dic.ahk

CoInitialize()
pdic := Dictionary()
Add(pdic, "ATT1", "ATT1_1")
Add(pdic, "ATT2", "ATT2_1")
Add(pdic, "ATT3", "ATT3_1")
Add(pdic, "ATT4", "ATT4_1")

pdic2 := Dictionary()
Add(pdic2, "ENTRY1", pDic)

MsgBox, % "ENTRY1: " . "`n" . Enumerate(GetItem(pdic2, "ENTRY1"))

; Changing the contents of pDic
SetItem(pdic, "ATT1", "ATT1_2")
SetItem(pdic, "ATT2", "ATT2_2")
SetItem(pdic, "ATT3", "ATT3_2")
SetItem(pdic, "ATT4", "ATT4_2")

; Is pDic stored byVal or byRef? Unfortunately its stored byRef, so the old contents got lost ....
MsgBox, % "ENTRY1: " . "`n" . Enumerate(GetItem(pdic2, "ENTRY1"))

Release(pdic)
Release(pdic2)

CoUninitialize()


Doing the above - changing contents of pdic after inserting it into pdic2, also changes the inserted item in pdic2.
How can I store the contents of pdic in pdic2, instead of just storing the reference of pdic?

Thanks in advance
Hoppfrosch


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 9th, 2007, 1:11 pm 
Offline

Joined: December 19th, 2006, 2:14 pm
Posts: 72
Location: France
Chris wrote:
Thanks for these great functions. I've linked to this topic from the bottom of the Arrays page. Does anyone know whether Windows 9x/NT supports Scripting.Dictionary?


Hi

AFAIK, Scripting.Dictionary is implemented when WSH5.6 is installed. Since MS has a specific version for W98/NT4, it should be supported as well

Sean : thanks for this great work


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 23rd, 2007, 11:41 am 
Offline

Joined: October 21st, 2006, 5:13 pm
Posts: 23
Hi, I arrived here by reading the help file on arrays.

I downloaded the Dictionary and CoHelper scripts, but running the example included in Dictionary.ahk results in:-
Quote:
Error at line63 in #include file "\path to\CoHelper.ahk ".

Line Text: Enumerate(penum, ByRef Result)
Error:Duplicate function definition

The Enumerate() function has been defined in Dictionary.ahk as:-
Code:
Enumerate(pdic)
{
   DllCall(VTable(pdic, 20), "Uint", pdic, "UintP", penm)

   VarSetCapacity(var, 8 * 2, 0)

   Loop, % Count(pdic)
   {
      DllCall(VTable(penm, 3), "Uint", penm, "Uint", 1, "Uint", &var, "Uint", 0)
      pKey := DecodeInteger(&var + 8)
      DllCall(VTable(pdic, 9), "Uint", pdic, "Uint", &var, "Uint", &var)
      pItm := DecodeInteger(&var + 8)

      Unicode2Ansi(pKey, sKey)
      Unicode2Ansi(pItm, sItm)
      SysFreeString(pKey)
      SysFreeString(pItm)
      sKeys .= sKey . " : " . sItm . "`n"
   }

   DllCall(VTable(penm, 2), "Uint", penm)

   Return sKeys
}

and in CoHelper.ahk as:-
Code:
Enumerate(penum, ByRef Result)
{
   VarSetCapacity(varResult,16,0)
   If (0 =   hResult:=DllCall(NumGet(NumGet(1*penum)+12), "Uint", penum, "Uint", 1, "Uint", &varResult, "UintP", 0))
      Result:=(vt:=NumGet(varResult,0,"Ushort"))=8||vt<0x1000&&DllCall("oleaut32\VariantChangeTypeEx","Uint",&varResult,"Uint",&varResult,"Uint",LCID,"Ushort",1,"Ushort",8)=0 ? Ansi4Unicode(bstr:=NumGet(varResult,8)) . SubStr(SysFreeString(bstr),1,0) : NumGet(varResult,8)
   Return   hResult
}

Any comments please?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 23rd, 2007, 11:48 am 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
If i recall correctly COM.ahk replaced CoHelper.ahk.

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 23rd, 2007, 12:00 pm 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
fade2gray wrote:
I downloaded the Dictionary and CoHelper scripts, but running the example included in Dictionary.ahk results in:-
Quote:
Error at line63 in #include file "\path to\CoHelper.ahk ".

Ah, recently I added Enumerate() to CoHelper.ahk while adding COM_Enumerate() to COM.ahk, completely forgetting about this Scripting.Dictionary (:yes, it's been deleted already from my HDD, all functions were replaced with Invoke()).
Are you gonna use it? I can safely remove Enumerate() from CoHelper.ahk.
However, I suggest to switch to Invoke()/COM_Invoke().


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 23rd, 2007, 12:40 pm 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
fade2gray wrote:
Error at line63 in #include file "\path to\CoHelper.ahk ".

I commented out Enumerate() in CoHelper.ahk. So, you may redownload it.
BTW, I recommend using COM.ahk over CoHelper.ahk, and COM_Invoke() function over the script(s) Scripting.Dictionary etc.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 23rd, 2007, 5:54 pm 
Offline

Joined: October 21st, 2006, 5:13 pm
Posts: 23
Thanks for the prompt replies.

I was trying to find a method to return multiple variables from a function (believing an array was the way to go) and have just figured how to use StringSplit.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: February 24th, 2008, 1:36 am 
Offline

Joined: September 23rd, 2005, 8:18 pm
Posts: 55
How do I loop through the whole dictionary the best way?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 21st, 2008, 6:36 pm 
Offline

Joined: September 23rd, 2005, 8:18 pm
Posts: 55
*bump* I would like to know how to loop through through it :)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 21st, 2008, 11:41 pm 
There is a function Enumerate in the script.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: June 22nd, 2009, 9:05 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Many thanks for this great functionality, specially to Sean and Laszlo :D

I've tried to put in some more simplicity and functionality in it :)

I would love to get some feedback ;)

EDIT:
Added action abbreviation characters: + (Add), - (Delete), = (Set)...

HowTo
Code:
;--------------------------------------------------------------------------------------------
;
;        D D D D    D D D D    D D D D           ;      D I C T I O N A R Y   D A T A B A S E
;        D      D   D      D   D       D         ;     
;        D       D  D       D  D        D        ;   
;        D        D D        D D       D         ;             
;        D        D D        D D D D D           ;      B Y   H O T K E Y I T
;        D        D D        D D       D         ;   
;        D       D  D       D  D        D        ;       
;        D      D   D      D   D       D         ;     
;        D D D D    D D D D    D D D D           ;     http://www.autohotkey.com/forum/viewtopic.php?p=276927#276927
;
;---------------------------------------------------------------------------------------------
;
;       Scripting.Dictionary  -  http://msdn.microsoft.com/en-us/library/x4k5wbx4.aspx
;        - A Dictionary object is the equivalent of a PERL associative array.
;          Items can be any form of data, and are stored in the array.
;          Each item is associated with a unique key.
;          The key is used to retrieve an individual item and is usually an integer or a string but can be anything else.
;          THE ONLY CHARACTERS YOU SHOULD NOT USE ARE CHR(2) + CHR(3) - those are used in sort action
;
;       Syntax
;         DDB([database,action,key/option,itm/option,skip,limit])
;
;
;       DDB()  -  ALL PARAMETERS ARE OPTIONAL  -  DDB() will destroy all databases and UNinitialise COM
;
;
;       DDB uses offers following functions ( - Key is like a Var and Item like Value in AutoHotkey - )
;       
;
;        - Create/N     --->   Initialises COM (if not already done so) and creates a new database.
;          key can be used to set comparison mode: 0=Binary (default); 1=Text (case insensitive); 2=Database
;          - DDB( "MyDB" , "create" , 1 ) ;Create a database named MyDB.
;
;        - Count/C      --->   Count items in Database
;          - ItemsInDatabase := DDB( "MyDB" , "count" ) alternatively
;
;        - Destroy/D    --->   Destroy a database
;          - DDB( "MyDB" , "destroy" )
;
;        - DestroyAll/DA--->   Destroy all databases (COM will be not UNinitialised, use DDB() therfore)
;          - DDB( "MyDB" , "destroyall" )
;
;        - GetCompMode  --->   Find out compare mode of database
;          - DDB( "MyDB" , "getcompmode" )
;
;
;        - Add/+        --->   Adds a key and item pair to a database
;          This is similar to var=value where var is the key and value is the itm.
;          - DDB( "MyDB" , "add" , "Key" , "Item" )
;
;        - Get/<        --->   Retrieves an Item from database using a key
;          - Item := DDB( "MyDB" , "get" , "Key" )
;
;        - Set/=        --->   Overwrites an existing Item to new value using a key
;          - DDB( "MyDB" , "set" , "Key" , "New Value" )
;
;        - Exists/?     --->   Checks if a key exist and returns 1 if a key exists
;          - If DDB( "MyDB" , "exists" , "Key" )
;
;        - Delete/-     --->   Delete a Key and its Item from Database
;          - DDB( "MyDB" , "delete" , "Key" )
;
;        - Rename/~     --->   Rename a key
;          - DDB( "MyDB" , "rename" , "Key" , "NewKey" )
;
;        - DeleteAll/_  --->   Delete all keys from database
;          - DDB( "MyDB" , "deleteall" )
;
;         - Hash         --->   Return hash of key
;          hash:=DDB( "MyDB" , "hash" , "key" )
;
;
;        - FIND / MATCH / REGEX / GETALL
;           - For item you can specify a different separator than default (`n)
;           - Parameter skip can be used to ommit first found items
;           - Parameter limit can be used to limit foundings
;             Example: DDB("MyDB","find","au",".",20,100)
;             = Find max 100 keys starting with "au" in "MyDB", ommit first 20 found and separate output by .
;
;        - GetAll        --->   Receives all keys from database
;          - AllKeys:=DDB( "MyDB" , "getall" , A_Space ) ;So output here will be: Key1 Key2 Key3...
;
;        - Find          --->   Find keys starting with given characters and return Values of found keys
;          Key can be used to
;          - FoundKeys:=DDB( "MyDB" , "find" , "Ke" , A_Tab )
;
;        - Match         --->   Match keys containing given characters anywhere inside the key
;          - FoundKeys:=DDB( "MyDB" , "match" , "ey" , A_Tab )
;
;        - RegEx         --->   Find keys using RegEx function
;          - FoundKeys:=DDB( "MyDB" , "regex" , "i).*y$" , A_Tab )
;
;
;
;        - Sort          --->   Sort Database using delimiter Chr(3) !!! DUE TO THIS OPTION "D" IS NOT AVALIABLE !!!
;          Parameter key can be used for sort options from AutoHotkey Sort command, only those are valid: C, CL, F, N, Pn, R
;          - DDB( "MyDB" , "sort" , "N R" )
;
;        - Copy          --->   Copy a database to new database
;          - DB( "MyDB" , "copy" , "MyDB" , "MyNewDB" )
;
;        - Replace       --->   Replace values from Items
;          DDB( "MyDB" , "replace" , "SearchText" , "ReplaceText" , "A" ) ; A to replace all
;
;        - RegExReplace  --->   Replace values from Item using RegExReplace
;          DDB( "MyDB" , "regexreplace" , "SearchText" , "ReplaceText" , "10" ) ;10->replace first 10 found
;
;
;        - Enum/&        --->   This action is used to loop trough keys in database
;          Loop
;             If (key:=DDB( "MyDB" , "enum" ))
;               MsgBox % "Key: " . key . "`nValue: " . DDB( "MyDB" , "get" , key)
;             else break
;          Alternatively you can catch ErrorLevel to receive the EnumPointer and go "manually" trough the database
;          - DDB( "MyDB" , "enum" ), pEnum:=ErrorLevel...
;          - key := DDB( "MyDB" , "enum" , pEnum )
;          To start manually from beginning (this is when you did not "Loop" trough the whole database)
;          - DDB( "MyDB" , "enum" , 0 ) ;start from beginning and return first key in Database
;--------------------------------------------------------------------------------------------

Example
Code:
#Include %A_ScriptDir%\DDB.ahk
SetBatchLines,-1
OnExit, Exit

DDB("MyDB","create",1) ;Same as DDB("MyDB","n",1)

;create 1000 keys and items
Loop 1000
   DDB("MyDB","add",A_Index,A_Index) ;or DDB("MyDB","+"...

;enum trogh database
Loop % (20) {
      If NextKey:=DDB("MyDB","enum"){ ;or DDB("MyDB","&")
         pEnum:=ErrorLevel
         ToolTip % "Key: " . NextKey . "`nValue: " . DDB("MyDB","get",NextKey) ;same as DDB("MyDB","<",NextKey)
         Sleep, 100
      } else break
}
ToolTip
MsgBox % "Change item 21:`nbefore: " . DDB("MyDB","get",21)
         . "`nafter: " . DDB("MyDB","set",21,"Hello World!")
         . DDB("MyDB","get",21)
MsgBox % "Item 21 recieved using pEnum: " . DDB("MyDB","get",DDB("MyDB","enum",pEnum))

MsgBox % "Find max 10 keys that start with character 2 and return their items separated by Tab`n" DDB("MyDB","find","2",A_Tab,0,10)
MsgBox % "Match 2 inside key, skip first 10 found and return max 20 items`n" DDB("MyDB","match",2,"",10,20)
MsgBox % "RegEx based search (^20.?$)`n" DDB("MyDB","regex","^20.?$","",0,10)
MsgBox % "Sort descending by number`n" . DDB("MyDB","sort","N R") . SubStr(DDB("MyDB","getAll"),1,100) . "`n…"
MsgBox % "Replace any 1 in Value by a`n" DDB("MyDB","replace",1,"a") DDB("MyDB","find","","|")
DDB("MyDB","sort","N")
MsgBox % "Rename Key 2 to AutoHotkey + Delete Key 3`n" DDB("MyDB","rename",2,"AutoHotkey") DDB("MyDB","delete",3) DDB("MyDB","getall","|")
MsgBox % "copy database to new database (remember 1 Item was deleted)`nItems in new Database: " DDB("MyDB","copy","new") DDB("new","count")

Exit:
DDB()
ExitApp

Function
Code:
DDB(pdic="",action="",Key="",Item="",skip=0,limit=4294967295,ByRef data=""){
   static
   local CLSID,IID,pKey,pItm,nLen,nLenItm,bExist,label,penum,result,nCompMode,wStr
   static var1,var2, CLSIDString:="{EE09B103-97E0-11CF-978F-00A02463E06F}", IIDString:="{42C642C1-97E1-11CF-978F-00A02463E06F}"
   If (label:="DDB" . action)
      Goto % label
   DDB<:
   DDBGet:
      Gosub,DDBAllocKey
      DllCall(NumGet(NumGet(pDic%pdic%+0)+48), UInt,pDic%pdic%, UInt,&var1, IntP,bExist)
      If bExist {     ; to avoid creating an unwanted new entry
         DllCall(NumGet(NumGet(pDic%pdic%+0)+36), UInt,pDic%pdic%, UInt,&var1, UInt,&var2)
         pItm := NumGet(&var2+8)
         nLen := DllCall("WideCharToMultiByte", UInt,0, UInt,0, UInt,pItm, Int,-1, UInt,0, Int,0, UInt,0, UInt,0)
         VarSetCapacity(Item, nLen)
         DllCall("WideCharToMultiByte", UInt,0, UInt,0, UInt,pItm, Int,-1, Str,Item, Int,nLen, UInt,0, UInt,0)
         DllCall("oleaut32\SysFreeString", UInt,pItm)
      }
      DllCall("oleaut32\SysFreeString", UInt,pKey)
   Return Item
   DDB+:
   DDBAdd:
      Gosub,DDBAllocItm
      DllCall(NumGet(NumGet(pDic%pdic%+0)+40), UInt,pDic%pdic%, UInt,&var1, UInt,&var2)
      DllCall("oleaut32\SysFreeString", UInt,pItm),DllCall("oleaut32\SysFreeString", UInt,pKey)
   Return
   DDB?:
   DDBExists:
      Gosub,DDBAllocKey
      DllCall(NumGet(NumGet(pDic%pdic%+0)+48), UInt,pDic%pdic%, UInt,&var1, IntP,bExist)
      DllCall("oleaut32\SysFreeString", UInt,pKey)
   Return bExist
   DDBFind:
   DDBMatch:
   DDBRegEx:
   DDBGetAll:
   DDBCopy:
   DDBSort:
   DDBRegexReplace:
   DDBReplace:
      ;label:=A_Thislabel
      DllCall(NumGet(NumGet(pDic%pdic%+0)+80), UInt,pDic%pdic%, UIntP,penum) ; create key-list in penum
      Loop % DDB(pdic,"count") {
         If (InStr("Clear0",pDic%pdic%) || DllCall(NumGet(NumGet(penum+0)+12), UInt,penum, UInt,1, UInt,&var1, UInt,0)) {
            DllCall(NumGet(NumGet(penum+0)+8), UInt,penum)   ; END: destroy key-list
            penum =                                          ; signal end of list
            break                                              ; empty
         }
         pKey := NumGet(&var1 + 8)
         nLen := DllCall("WideCharToMultiByte", UInt,0, UInt,0, UInt,pKey, Int,-1, UInt,0, Int,0, UInt,0, UInt,0)
         VarSetCapacity(wStr, nLen)
         DllCall("WideCharToMultiByte", UInt,0, UInt,0, UInt,pKey, Int,-1, Str,wStr, Int,nLen, UInt,0, UInt,0)
         If (InStr("DDBFindDDBMatchDDBRegex",label) and (Key="" or (label="DDBFind"
            ? (InStr(wStr,Key)=1) : (label="DDBMatch" ? (InStr(wStr,Key)) : (RegExMatch(wStr,Key)))))){
            bExist++
            If (bExist>skip){
               result.= DDB(pdic,"get",wStr) . (Item!="" ? Item : "`n")
               nLenItm++
               If (limit<=nLenItm){
                  DllCall("oleaut32\SysFreeString", UInt,pKey)
                  Break
               }
            }
         } else if (label="DDBReplace"){
            result:=DDB(pdic,"get",wStr)
            StringReplace,result,result,%Key%,%Item%,% (Item ? Item : "")
            DDB(pdic,"set",wStr,result)
         } else if (label="DDBRegexReplace"){
            result:=DDB(pdic,"get",wStr)
            result:=RegExReplace(result,Key,Item,"",Item ? Item : -1)
            DDB(pdic,"set",wStr,result)
         } else if !InStr("DDBFindDDBMatchDDBRegex",label){
            result.= wStr . (label="DDBGetAll" ? (Key!="" ? Key : "`n") : (Chr(2) . DDB(pdic,"get",wStr) . Chr(3)))
         }
         DllCall("oleaut32\SysFreeString", UInt,pKey)
      }
      If InStr("DDBGetAllDDBFindDDBMatchDDBRegEx",label)
         Return result
      else if (label="DDBReplace"){
         Return
      } else if (label="DDBCopy"){
         Gosub, DDBGetCompMode
         pdic:=Key
      } else Sort,result,% "D" . Chr(3) . (Key ? Key : "")
         Gosub, DDBDeleteAll
      If (label="DDBCopy"){
         Key:= nCompMode ? nCompMode : (Item ? Item : 1)
         Gosub, DDBCreate
      }
      Loop,Parse,result,% Chr(3)
         If (A_LoopField!="")
            DDB(pdic,"add",SubStr(A_LoopField,1,InStr(A_LoopField,Chr(2))-1),SubStr(A_LoopField,InStr(A_LoopField,Chr(2))+1))
   Return
   DDB&:
   DDBEnum:
      If Key>0
         penum%pdic%:=Key
      else If (!penum%pdic% or Key="0")
         DllCall(NumGet(NumGet(pDic%pdic%+0)+80), UInt,pDic%pdic%, UIntP,penum%pdic%) ; create key-list in penum
      If (InStr("Clear0",pDic%pdic%) || DllCall(NumGet(NumGet(penum%pdic%+0)+12), UInt,penum%pdic%, UInt,1, UInt,&var1, UInt,0)) {
            DllCall(NumGet(NumGet(penum%pdic%+0)+8), UInt,penum%pdic%)   ; END: destroy key-list
            penum%dic%=                                                  ; signal end of list
            ErrorLevel=                                                  ; empty
            Return                                                       
      }
      pKey := NumGet(&var1 + 8)
      nLen := DllCall("WideCharToMultiByte", UInt,0, UInt,0, UInt,pKey, Int,-1, UInt,0, Int,0, UInt,0, UInt,0)
      VarSetCapacity(wStr, nLen)
      DllCall("WideCharToMultiByte", UInt,0, UInt,0, UInt,pKey, Int,-1, Str,wStr, Int,nLen, UInt,0, UInt,0)
      DllCall("oleaut32\SysFreeString", UInt,pKey)
      ErrorLevel:=penum%pdic%
   Return wStr
   DDB=:
   DDBSet:
      Gosub,DDBAllocItm
      DllCall(NumGet(NumGet(pDic%pdic%+0)+32), UInt,pDic%pdic%, UInt,&var1, UInt,&var2)  ; 8 (Set0 -> 7)
      DllCall("oleaut32\SysFreeString", UInt,pKey)
      DllCall("oleaut32\SysFreeString", UInt,pItm)
   Return
   DDBHash:
      Gosub, DDBAllocKey
      DllCall(NumGet(NumGet(pDic%pdic%+0)+48), UInt,pDic%pdic%, UInt,&var1, IntP,bExist)
      DllCall(NumGet(NumGet(pDic%pdic%+0)+84), UInt,pDic%pdic%, UInt,&var1, UInt,&var2)
      result := NumGet(&var2+8)
      DllCall("oleaut32\SysFreeString", UInt,pKey)
      Return result
   Return
   DDB~:
   DDBRename:
      Gosub,DDBAllocItm
      DllCall(NumGet(NumGet(pDic%pdic%+0)+56), UInt,pDic%pdic%, UInt,&var1, UInt,&var2)
      DllCall("oleaut32\SysFreeString", UInt,pKey)
      DllCall("oleaut32\SysFreeString", UInt,pItm)
   Return
   DDB-:
   DDBDelete:
   Gosub,DDBAllocKey
   DllCall(NumGet(NumGet(pDic%pdic%+0)+64), UInt,pDic%pdic%, UInt,&var1)
   DllCall("oleaut32\SysFreeString", UInt,pKey)
   Return
   DDB_:
   DDBDeleteAll:
   Return DllCall(NumGet(NumGet(pDic%pdic%+0)+68), UInt,pDic%pdic%)
   DDBC:
   DDBCount:
      DllCall(NumGet(NumGet(pDic%pdic%+0)+44), UInt,pDic%pdic%, IntP,result)
   Return result
   DDBD:
   DDBDestroy:
      DllCall(NumGet(NumGet(pDic%pdic%+0)+8), UInt,pDic%pdic%)
      StringReplace,DDBAll,DDBAll,|pDic%pdic%|
   Return
   DDBN:
   DDBCreate:
      If !Init
         DllCall("ole32\CoInitialize", UInt,0),Init:=1
         ,VarSetCapacity(var1, 16, 0),VarSetCapacity(var2, 16, 0),NumPut(8, var1),NumPut(8, var2)
      DDBAll.="|" . pdic . "|"
      VarSetCapacity(CLSID, 16)
      VarSetCapacity(wStr, 79)
      DllCall("MultiByteToWideChar", UInt,0, UInt,0, UInt,&CLSIDString, Int,-1, UInt,&wStr, Int,79)
      DllCall("ole32\CLSIDFromString", Str,wStr, Str,CLSID)
      VarSetCapacity(IID, 16)
      DllCall("MultiByteToWideChar", UInt,0, UInt,0, UInt,&IIDString, Int,-1, UInt,&wStr, Int,79)
      DllCall("ole32\CLSIDFromString", Str,wStr, Str,IID)
      DllCall("ole32\CoCreateInstance", Str,CLSID, UInt,0, UInt,5, Str,IID, UIntP,pDic%pdic%) ; CLSCTX=5
      DllCall(NumGet(NumGet(pDic%pdic%+0)+72), UInt,pDic%pdic%, Int,Key) ; Set compare mode
   Return
   DDBGetCompMode:
      DllCall(NumGet(NumGet(pDic%pdic%+0)+76), UInt,pDic%pdic%, IntP,nCompMode)
   return nCompMode
   DDBDA:
   DDBDestroyAll:
      Loop,Parse,DDBAll,|
         If (A_LoopField!="")
            DllCall(NumGet(NumGet(A_LoopField+0)+8), UInt,A_LoopField)
      DDBAll=
   Return
   DDB:
      If DDBDestroyAll
         Gosub, DDBDestroyAll
      DllCall("ole32\CoUnInitialize")
   Return
   DDBAllocItm: ;Internal
      VarSetCapacity(wStr, (StrLen(Item))*2 + 1)
      DllCall("MultiByteToWideChar", UInt,0, UInt,0, UInt,&Item, Int,-1, UInt,&wStr, Int,StrLen(Item)+1)
      pItm := DllCall("oleaut32\SysAllocString", Str,wStr)
      NumPut(pItm,&var2+8)
   DDBAllocKey: ;Internal
      VarSetCapacity(wStr, (StrLen(Key))*2 + 1)
      DllCall("MultiByteToWideChar", UInt,0, UInt,0, UInt,&Key, Int,-1, UInt,&wStr, Int,StrLen(Key)+1)
      pKey := DllCall("oleaut32\SysAllocString", Str,wStr)
      NumPut(pKey,&var1+8)
   Return
}

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Last edited by HotKeyIt on June 28th, 2009, 6:33 pm, edited 2 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 24th, 2009, 3:19 pm 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Below you will find a test using DDB vs. COM vs. Laszlo vers. and vs. toralf version.

Edit:
Add and get are faster than com now :D
But DDB consumes still more memory, please help :(
Code:
#Include %A_ScriptDir%\Com.ahk
#Include %A_ScriptDir%\DDB.ahk
SetBatchLines,-1
;DDB create
DDB("DB","n",0)
;COM_Init() ; Initialized COM in DDB already
d := COM_CreateObject("Scripting.Dictionary") ; Create dictionary.

;Dic create by Toralf
Dic()

;Create Dictionary by Laszlo
dic:=CreateDictionary()

;how ofter to loop
LoopTimes:=10000


SplashTextOn,300,20,Creating %looptimes% items using DDB function
;Create 10000 Items
Start:=A_TickCount
Loop % LoopTimes
   DDB("DB","+",A_Index,A_Index)
CreateDDB:=A_TickCount-Start

SplashTextOn,300,20,Creating %looptimes% items using COM function
Start:=A_TickCount
Loop % LoopTimes
   COM_Invoke(d,"Item",A_Index,A_Index)
CreateCOM:=A_TickCount-Start

SplashTextOn,300,20,Creating %looptimes% items using Dic function
Start:=A_TickCount
Loop % LoopTimes
   Dic_Add(A_Index,A_Index)
CreateDic:=A_TickCount-Start

SplashTextOn,300,20,Creating %looptimes% items using Add function
Start:=A_TickCount
Loop % LoopTimes
   Add(dic,A_Index,A_Index)
CreateDict:=A_TickCount-Start

SplashTextOff
MsgBox % "Create " LoopTimes " items`nDDB: " CreateDDB "`nCOM: " CreateCOM "`nDic: " CreateDic "`nAdd: " CreateDict


SplashTextOn,300,20,Get %looptimes% items using DDB function
Start:=A_TickCount
Loop % LoopTimes
   DDB("DB","<",A_Index,A_Index)
CreateDDB:=A_TickCount-Start

SplashTextOn,300,20,Get %looptimes% items using COM function
Start:=A_TickCount
Loop % LoopTimes
   COM_Invoke(d,"Item",A_Index)
CreateCOM:=A_TickCount-Start

SplashTextOn,300,20,Get %looptimes% items using Dic function
Start:=A_TickCount
Loop % LoopTimes
   Dic_Get(A_Index)
CreateDic:=A_TickCount-Start

SplashTextOn,300,20,Get %looptimes% items using Get function
Start:=A_TickCount
Loop % LoopTimes
   Get(dic, A_Index)
CreateDict:=A_TickCount-Start
SplashTextOff
MsgBox % "Get " LoopTimes " items`nDDB: " CreateDDB "`nCOM: " CreateCOM "`nDic: " CreateDic "`nGet: " CreateDict




COM_Release(d) ; Done using dictionary d.
;COM_Term() ; Done using COM is done in DDB()
Dic(1)
Destroydictionary(dic)
DDB()




;###############################################################################
;###  Scripting.Dictionary COM object Modul                                  ###
;###############################################################################
Dic(Action=""){
    static initialized, pdic
    If (Action = "pdic")               ;return pdic
        Return pdic
    Else If Action {                   ;exit - clean up
        Dic_DestroyDictionary(pdic)
        ;DllCall("ole32\CoUninitialize")
    }Else{                             ;create a dictionary
        ;If !initialized {
        ;    initialized := True
        ;    DllCall("ole32\CoInitialize", UInt,0)
        ;  }
        pdic := Dic_CreateDictionary()
      }
    Return 1
  }

Dic_Add(sKey, sItm) {  ; If key exists: no effect (<--> Set)
   pdic := Dic("pdic")
   Dic_AllocBString(pKey, var1, sKey)
   Dic_AllocBString(pItm, var2, sItm)
   DllCall(Dic_VTable(pdic,10), UInt,pdic, UInt,&var1, UInt,&var2)
   DllCall("oleaut32\SysFreeString", UInt,pKey)
   DllCall("oleaut32\SysFreeString", UInt,pItm)
}

Dic_Set(sKey, sItm) {  ; If key exists, update the item, Else create a new entry
   pdic := Dic("pdic")
   Dic_AllocBString(pKey, var1, sKey)
   Dic_AllocBString(pItm, var2, sItm)
   DllCall(Dic_VTable(pdic,8), UInt,pdic, UInt,&var1, UInt,&var2)  ; 8 (Set0 -> 7)
   DllCall("oleaut32\SysFreeString", UInt,pKey)
   DllCall("oleaut32\SysFreeString", UInt,pItm)
}

Dic_Get(sKey) {  ; empty if not exists
   pdic := Dic("pdic")
   Dic_AllocBString(pKey, var1, sKey)
   DllCall(Dic_VTable(pdic,12), UInt,pdic, UInt,&var1, IntP,bExist)
   If bExist {     ; to avoid creating an unwanted new entry
      VarSetCapacity(var2, 16, 0)
      DllCall(Dic_VTable(pdic,9), UInt,pdic, UInt,&var1, UInt,&var2)
      pItm := *(&var2+8) | *(&var2+9) << 8 | *(&var2+10) << 16 | *(&var2+11) << 24
      Dic_Unicode2Ansi(pItm, sItm)
      DllCall("oleaut32\SysFreeString", UInt,pItm)
   }
   DllCall("oleaut32\SysFreeString", UInt,pKey)
   Return sItm
}

Dic_NextKey(ByRef penum) {                         ; penum = "": create new list
   pdic := Dic("pdic")
   If penum =                                          ; not static: allow multiple independent lists
      DllCall(Dic_VTable(pdic,20), UInt,pdic, UIntP,penum) ; create key-list in penum
   VarSetCapacity(var, 16, 0)
   If DllCall(Dic_VTable(penum,3), UInt,penum, UInt,1, UInt,&var, UInt,0) {
      DllCall(Dic_VTable(penum,2), UInt,penum)             ; END: destroy key-list
      penum =                                          ; signal end of list
      Return                                           ; empty
   }
   pKey := Dic_UInt@(&var + 8)
   Dic_Unicode2Ansi(pKey, sKey)
   DllCall("oleaut32\SysFreeString", UInt,pKey)
   Return skey
}

Dic_Count() {      ; #entries
   pdic := Dic("pdic")
   DllCall(Dic_VTable(pdic,11), UInt,pdic, IntP,nCount)
   Return nCount
}

Dic_Exists(sKey) {
   pdic := Dic("pdic")
   Dic_AllocBString(pKey, var, sKey)
   DllCall(Dic_VTable(pdic,12), UInt,pdic, UInt,&var, IntP,bExist)
   DllCall("oleaut32\SysFreeString", UInt,pKey)
   Return bExist
}

Dic_Rename(sKeyFr, sKeyTo) {
   pdic := Dic("pdic")
   Dic_AllocBString(pKeyFr, var1, sKeyFr)
   Dic_AllocBString(pKeyTo, var2, sKeyTo)
   DllCall(Dic_VTable(pdic,14), UInt,pdic, UInt,&var1, UInt,&var2)
   DllCall("oleaut32\SysFreeString", UInt,pKeyFr)
   DllCall("oleaut32\SysFreeString", UInt,pKeyTo)
}

Dic_Remove(sKey) {
   pdic := Dic("pdic")
   Dic_AllocBString(pKey, var, sKey)
   DllCall(Dic_VTable(pdic,16), UInt,pdic, UInt,&var)
   DllCall("oleaut32\SysFreeString", UInt,pKey)
}

Dic_RemoveAll() {
   pdic := Dic("pdic")
   Return DllCall(Dic_VTable(pdic,17), UInt,pdic)
}

Dic_SetCompareMode(nCompMode = 1) { ; 0: Binary, 1: Text, 2: Database, n: LCID
   pdic := Dic("pdic")
   Modes = btd
   Loop, Parse, Modes
      If RegExMatch(nCompMode, "i)^" A_LoopField)
         nCompMode := A_Index - 1
   DllCall(Dic_VTable(pdic,18), UInt,pdic, Int,nCompMode)
}

Dic_GetCompareMode() {
   pdic := Dic("pdic")
   DllCall(Dic_VTable(pdic,19), UInt,pdic, IntP,nCompMode)
   Return nCompMode
}

Dic_HashVal(sKey) {
   pdic := Dic("pdic")
   Dic_AllocBString(pKey, var1, sKey)
   DllCall(Dic_VTable(pdic,12), UInt,pdic, UInt,&var1, IntP,bExist)
   VarSetCapacity(var2, 16, 0)
   DllCall(Dic_VTable(pdic,21), UInt,pdic, UInt,&var1, UInt,&var2)
   nHashVal := *(&var2+8) | *(&var2+9) << 8 | *(&var2+10) << 16 | *(&var2+11) << 24
   DllCall("oleaut32\SysFreeString", UInt,pKey)
   Return nHashVal
}

;#########  PRIVATE FUNCTIONS   ################################################

Dic_CreateDictionary() {
    CLSID_Dictionary := "{EE09B103-97E0-11CF-978F-00A02463E06F}"
    IID_IDictionary  := "{42C642C1-97E1-11CF-978F-00A02463E06F}"
    Return Dic_CreateObject(CLSID_Dictionary, IID_IDictionary)
  }

Dic_DestroyDictionary(pdic) {
    DllCall(Dic_UInt@(Dic_UInt@(pdic)+8), UInt,pdic)
  }

Dic_AllocBString(ByRef Key, ByRef Var, sString) {
   Dic_Ansi2Unicode(sString, wString)
   Key := DllCall("oleaut32\SysAllocString", Str,wString)
   VarSetCapacity(Var, 16, 0)
   DllCall("ntdll\RtlFillMemoryUlong", UInt,&Var,  UInt,4, UInt,8)
   DllCall("ntdll\RtlFillMemoryUlong", UInt,&Var+8,UInt,4, UInt,Key)
}

Dic_UInt@(ptr) {
   Return *ptr | *(ptr+1) << 8 | *(ptr+2) << 16 | *(ptr+3) << 24
}

Dic_CreateObject(ByRef CLSID, ByRef IID, CLSCTX = 5) {
   If StrLen(CLSID) = 38
      Dic_GUID4String(CLSID, CLSID)
   If StrLen(IID) = 38
      Dic_GUID4String(IID, IID)
   DllCall("ole32\CoCreateInstance", Str,CLSID, UInt,0, UInt,CLSCTX, Str,IID, UIntP,ppv)
   Return ppv
}
Dic_GUID4String(Byref CLSID, sString) {
   VarSetCapacity(CLSID, 16)
   Dic_Ansi2Unicode(sString, wString, 38)
   DllCall("ole32\CLSIDFromString", Str,wString, Str,CLSID)
}
Dic_Ansi2Unicode(ByRef sString, ByRef wString, nLen = 0) {
   If !nLen
      nLen := DllCall("MultiByteToWideChar", UInt,0, UInt,0, UInt,&sString, Int,-1, UInt,0, Int,0)
   VarSetCapacity(wString, nLen*2 + 1)
   DllCall("MultiByteToWideChar", UInt,0, UInt,0, UInt,&sString, Int,-1, UInt,&wString, Int,nLen)
}
Dic_VTable(ppv, idx) {
   Return Dic_UInt@(Dic_UInt@(ppv) + idx*4)
}
Dic_Unicode2Ansi(ByRef wString, ByRef sString, nLen = 0) {
   pString := wString + 0 > 65535 ? wString : &wString
   If !nLen
      nLen := DllCall("WideCharToMultiByte", UInt,0, UInt,0, UInt,pString, Int,-1, UInt,0, Int,0, UInt,0, UInt,0)
   VarSetCapacity(sString, nLen)
   DllCall("WideCharToMultiByte", UInt,0, UInt,0, UInt,pString, Int,-1, Str,sString, Int,nLen, UInt,0, UInt,0)
}


;By Laszlo

CreateDictionary(nCompMode = 0) { ; Compare mode = 0: Binary, 1: Text, 2: Database, n: LCID
   CLSID_Dictionary := "{EE09B103-97E0-11CF-978F-00A02463E06F}"
   IID_IDictionary  := "{42C642C1-97E1-11CF-978F-00A02463E06F}"
   pdic := CreateObject(CLSID_Dictionary, IID_IDictionary)
   DllCall(VTable(pdic,18), UInt,pdic, Int,nCompMode) ; Set compare mode
   Return pdic
}

DestroyDictionary(pdic) {
   DllCall(UInt@(UInt@(pdic)+8), UInt,pdic)
}

Add(pdic, sKey, sItm) {  ; If key exists: no effect (<--> Set)
   AllocBString(pKey, var1, sKey)
   AllocBString(pItm, var2, sItm)
   DllCall(VTable(pdic,10), UInt,pdic, UInt,&var1, UInt,&var2)
   DllCall("oleaut32\SysFreeString", UInt,pKey)
   DllCall("oleaut32\SysFreeString", UInt,pItm)
}

Set(pdic, sKey, sItm) {  ; If key exists, update the item, Else create a new entry
   AllocBString(pKey, var1, sKey)
   AllocBString(pItm, var2, sItm)
   DllCall(VTable(pdic,8), UInt,pdic, UInt,&var1, UInt,&var2)  ; 8 (Set0 -> 7)
   DllCall("oleaut32\SysFreeString", UInt,pKey)
   DllCall("oleaut32\SysFreeString", UInt,pItm)
}

Get(pdic, sKey) {  ; empty if not exists
   AllocBString(pKey, var1, sKey)
   DllCall(VTable(pdic,12), UInt,pdic, UInt,&var1, IntP,bExist)
   If bExist {     ; to avoid creating an unwanted new entry
      VarSetCapacity(var2, 16, 0)
      DllCall(VTable(pdic,9), UInt,pdic, UInt,&var1, UInt,&var2)
      pItm := *(&var2+8) | *(&var2+9) << 8 | *(&var2+10) << 16 | *(&var2+11) << 24
      Unicode2Ansi(pItm, sItm)
      DllCall("oleaut32\SysFreeString", UInt,pItm)
   }
   DllCall("oleaut32\SysFreeString", UInt,pKey)
   Return sItm
}

Count(pdic) {      ; #entries
   DllCall(VTable(pdic,11), UInt,pdic, IntP,nCount)
   Return nCount
}

Exists(pdic, sKey) {
   AllocBString(pKey, var, sKey)
   DllCall(VTable(pdic,12), UInt,pdic, UInt,&var, IntP,bExist)
   DllCall("oleaut32\SysFreeString", UInt,pKey)
   Return bExist
}

Rename(pdic, sKeyFr, sKeyTo) {
   AllocBString(pKeyFr, var1, sKeyFr)
   AllocBString(pKeyTo, var2, sKeyTo)
   DllCall(VTable(pdic,14), UInt,pdic, UInt,&var1, UInt,&var2)
   DllCall("oleaut32\SysFreeString", UInt,pKeyFr)
   DllCall("oleaut32\SysFreeString", UInt,pKeyTo)
}

Remove(pdic, sKey) {
   AllocBString(pKey, var, sKey)
   DllCall(VTable(pdic,16), UInt,pdic, UInt,&var)
   DllCall("oleaut32\SysFreeString", UInt,pKey)
}

RemoveAll(pdic) {
   Return DllCall(VTable(pdic,17), UInt,pdic)
}

GetCompareMode(pdic) {
   DllCall(VTable(pdic,19), UInt,pdic, IntP,nCompMode)
   Return nCompMode
}

HashVal(pdic,sKey) {
   AllocBString(pKey, var1, sKey)
   DllCall(VTable(pdic,12), UInt,pdic, UInt,&var1, IntP,bExist)
   VarSetCapacity(var2, 16, 0)
   DllCall(VTable(pdic,21), UInt,pdic, UInt,&var1, UInt,&var2)
   nHashVal := *(&var2+8) | *(&var2+9) << 8 | *(&var2+10) << 16 | *(&var2+11) << 24
   DllCall("oleaut32\SysFreeString", UInt,pKey)
   Return nHashVal
}

NextKey(ByRef penum, pdic="") {                        ; penum = "": create new list. pdic=0,"Clear": destroy list
   If penum =                                          ; not static: allow multiple independent lists
      DllCall(VTable(pdic,20), UInt,pdic, UIntP,penum) ; create key-list in penum
   VarSetCapacity(var, 16, 0)
   If (InStr("Clear0",pdic) || DllCall(VTable(penum,3), UInt,penum, UInt,1, UInt,&var, UInt,0)) {
      DllCall(VTable(penum,2), UInt,penum)             ; END: destroy key-list
      penum =                                          ; signal end of list
      Return                                           ; empty
   }
   pKey := UInt@(&var + 8)
   Unicode2Ansi(pKey, sKey)
   DllCall("oleaut32\SysFreeString", UInt,pKey)
   Return skey
}

AllocBString(ByRef Key, ByRef Var, sString) {
   Ansi2Unicode(sString, wString)
   Key := DllCall("oleaut32\SysAllocString", Str,wString)
   VarSetCapacity(Var, 16, 0)
   DllCall("ntdll\RtlFillMemoryUlong", UInt,&Var,  UInt,4, UInt,8)
   DllCall("ntdll\RtlFillMemoryUlong", UInt,&Var+8,UInt,4, UInt,Key)
}

UInt@(ptr) {
   Return *ptr | *(ptr+1) << 8 | *(ptr+2) << 16 | *(ptr+3) << 24
}

;;; COM Helper functions

CreateObject(ByRef CLSID, ByRef IID, CLSCTX = 5) {
   If StrLen(CLSID) = 38
      GUID4String(CLSID, CLSID)
   If StrLen(IID) = 38
      GUID4String(IID, IID)
   DllCall("ole32\CoCreateInstance", Str,CLSID, UInt,0, UInt,CLSCTX, Str,IID, UIntP,ppv)
   Return ppv
}
GUID4String(Byref CLSID, sString) {
   VarSetCapacity(CLSID, 16)
   Ansi2Unicode(sString, wString, 38)
   DllCall("ole32\CLSIDFromString", Str,wString, Str,CLSID)
}
Ansi2Unicode(ByRef sString, ByRef wString, nLen = 0) {
   If !nLen
      nLen := DllCall("MultiByteToWideChar", UInt,0, UInt,0, UInt,&sString, Int,-1, UInt,0, Int,0)
   VarSetCapacity(wString, nLen*2 + 1)
   DllCall("MultiByteToWideChar", UInt,0, UInt,0, UInt,&sString, Int,-1, UInt,&wString, Int,nLen)
}
VTable(ppv, idx) {
   Return UInt@(UInt@(ppv) + idx*4)
}
Unicode2Ansi(ByRef wString, ByRef sString, nLen = 0) {
   pString := wString + 0 > 65535 ? wString : &wString
   If !nLen
      nLen := DllCall("WideCharToMultiByte", UInt,0, UInt,0, UInt,pString, Int,-1, UInt,0, Int,0, UInt,0, UInt,0)
   VarSetCapacity(sString, nLen)
   DllCall("WideCharToMultiByte", UInt,0, UInt,0, UInt,pString, Int,-1, Str,sString, Int,nLen, UInt,0, UInt,0)
}

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 13th, 2010, 5:04 pm 
Offline

Joined: May 21st, 2010, 3:24 pm
Posts: 12
The two download links at the top seem to be dead. Maybe it is temporary. Will you check them?

_________________
Anyone have any comments?

Cheerio,
Autokeyminer :cool:

autokeyminer@ymail.com


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 62 posts ]  Go to page Previous  1, 2, 3, 4, 5  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: xXDarknessXx and 14 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group